diff --git a/src/ide/search/searchview.ts b/src/ide/search/searchview.ts index 965b8ee3..368d7b2a 100644 --- a/src/ide/search/searchview.ts +++ b/src/ide/search/searchview.ts @@ -90,13 +90,47 @@ export function openSearchDialog() { const resultsDiv = $('#searchboxResults'); + // Current result list + selection index (for arrow-key navigation). + let currentHits: SearchHit[] = []; + let selectedIdx = -1; + + /** Highlight the list item at index i (or none if i < 0). */ + const selectRow = (i: number) => { + selectedIdx = Math.max(-1, Math.min(i, currentHits.length - 1)); + resultsDiv.find('li.search-hit').each((j, el) => { + $(el).toggleClass('active', j === selectedIdx); + }); + if (selectedIdx >= 0) { + const li = resultsDiv.find('li.search-hit').eq(selectedIdx); + if (li.length) { + const box = resultsDiv[0] as HTMLElement; + const item = li[0] as HTMLElement; + if (item.offsetTop < box.scrollTop) { + box.scrollTop = item.offsetTop; + } else if (item.offsetTop + item.offsetHeight > box.scrollTop + box.clientHeight) { + box.scrollTop = item.offsetTop + item.offsetHeight - box.clientHeight; + } + } + } + }; + + /** Open the currently selected (or given) hit. */ + const openSelected = (i: number = selectedIdx) => { + const hit = currentHits[i]; + if (!hit) return; + openSearchHit(hit); + bootbox.hideAll(); + }; + const render = (hits: SearchHit[]) => { - if (!hits || hits.length === 0) { + currentHits = hits || []; + if (currentHits.length === 0) { + selectedIdx = -1; resultsDiv.html('