/* Code Studio — project search Runs backend/search.agi over the opened project folder and renders the hits grouped by file. Clicking a hit opens the file and jumps to the line. */ var csSearchOptions = { matchCase: false, wholeWord: false }; var csSearchRunning = false; function toggleSearchOption(option, button){ csSearchOptions[option] = !csSearchOptions[option]; $(button).toggleClass("active", csSearchOptions[option]); } function clearSearchResults(){ $("#searchKeyword").val(""); $("#searchResults").html('
Open a project folder, then search its file contents.
'); } function startProjectSearch(){ var keyword = $("#searchKeyword").val(); if (!currentProjectFolder){ $("#searchResults").html('
No project folder is open. ' + 'Use File > Open Folder first.
'); return; } if (!keyword || keyword.trim() == ""){ clearSearchResults(); return; } if (csSearchRunning) return; csSearchRunning = true; $("#searchResults").html('
Searching…
'); $.ajax({ url: "../system/ajgi/interface?script=Code Studio/backend/search.agi", method: "POST", dataType: "json", data: { root: currentProjectFolder, keyword: keyword, include: $("#searchInclude").val(), matchCase: csSearchOptions.matchCase ? "true" : "false", wholeWord: csSearchOptions.wholeWord ? "true" : "false" }, success: function(response){ csSearchRunning = false; if (!response.success){ $("#searchResults").html('
' + escapeHTMLText(response.error) + '
'); return; } renderSearchResults(response, keyword); }, error: function(){ csSearchRunning = false; $("#searchResults").html('
The search backend is unreachable.
'); } }); } function renderSearchResults(response, keyword){ if (response.results.length == 0){ $("#searchResults").html('
No results for "' + escapeHTMLText(keyword) + '".
'); return; } var html = '
' + response.totalHits + ' result(s) in ' + response.results.length + ' file(s)' + (response.truncated ? ' — showing the first matches only' : '') + '
'; response.results.forEach(function(file){ var encodedPath = encodeURIComponent(file.path); var ext = file.name.split(".").pop(); html += '
' + '
' + '' + '' + '' + escapeHTMLText(file.relative) + '' + '' + file.hits.length + '' + '
' + '
'; file.hits.forEach(function(hit){ html += '
' + '' + highlightKeyword(hit.text.replace(/^\s+/, ""), keyword) + '' + '
'; }); html += '
'; }); $("#searchResults").html(html); } //Wrap every occurrence of the keyword in a , on already escaped text function highlightKeyword(text, keyword){ var escapedText = escapeHTMLText(text); var escapedKeyword = escapeHTMLText(keyword).replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); var flags = csSearchOptions.matchCase ? "g" : "gi"; try { return escapedText.replace(new RegExp(escapedKeyword, flags), function(match){ return "" + match + ""; }); } catch(e){ return escapedText; } } function openSearchHit(filepath, lineNumber){ openFile(filepath); //The file may still be loading — poll briefly for its model to appear var attempts = 0; var timer = setInterval(function(){ attempts++; var editorObject = getFocusedEditorObject(); var tabInfo = getFocusedTabInfo(); if (editorObject && tabInfo && tabInfo.filepath == filepath){ clearInterval(timer); editorObject.editor.revealLineInCenter(lineNumber); editorObject.editor.setPosition({ lineNumber: lineNumber, column: 1 }); editorObject.editor.focus(); } else if (attempts > 40){ clearInterval(timer); } }, 50); }