project-search.js (1890B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */ 4 5 // Maybe reuse file search's functions? 6 7 import getMatches from "./get-matches"; 8 9 export function findSourceMatches(content, queryText, options) { 10 if (queryText == "") { 11 return []; 12 } 13 14 const text = content.value; 15 const lines = text.split("\n"); 16 17 return getMatches(queryText, text, options).map(({ line, ch, match }) => { 18 const { value, matchIndex } = truncateLine(lines[line], ch); 19 return { 20 line: line + 1, 21 column: ch, 22 23 matchIndex, 24 match, 25 value, 26 }; 27 }); 28 } 29 30 // This is used to find start of a word, so that cropped string look nice 31 const startRegex = /([ !@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?])/g; 32 // Similarly, find 33 const endRegex = new RegExp( 34 [ 35 "([ !@#$%^&*()_+-=[]{};':\"\\|,.<>/?])", 36 '[^ !@#$%^&*()_+-=[]{};\':"\\|,.<>/?]*$"/', 37 ].join("") 38 ); 39 // For texts over 100 characters this truncates the text (for display) 40 // around the context of the matched text. 41 function truncateLine(text, column) { 42 if (text.length < 100) { 43 return { 44 matchIndex: column, 45 value: text, 46 }; 47 } 48 49 // Initially take 40 chars left to the match 50 const offset = Math.max(column - 40, 0); 51 // 400 characters should be enough to figure out the context of the match 52 const truncStr = text.slice(offset, column + 400); 53 let start = truncStr.search(startRegex); 54 let end = truncStr.search(endRegex); 55 56 if (start > column) { 57 // No word separator found before the match, so we take all characters 58 // before the match 59 start = -1; 60 } 61 if (end < column) { 62 end = truncStr.length; 63 } 64 const value = truncStr.slice(start + 1, end); 65 66 return { 67 matchIndex: column - start - offset - 1, 68 value, 69 }; 70 }