Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Commit 884ee84

Browse files
committed
Merge pull request #8591 from adobe/rlim/show-match-index
Show match index in place of match count
2 parents 327bc4d + f341962 commit 884ee84

File tree

3 files changed

+123
-33
lines changed

3 files changed

+123
-33
lines changed

src/nls/root/strings.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,7 @@ define({
137137
"BUTTON_NO" : "No",
138138

139139
// Find, Replace, Find in Files
140-
"FIND_RESULT_COUNT" : "{0} results",
141-
"FIND_RESULT_COUNT_SINGLE" : "1 result",
140+
"FIND_MATCH_INDEX" : "{0} of {1}",
142141
"FIND_NO_RESULTS" : "No results",
143142
"FIND_QUERY_PLACEHOLDER" : "Find\u2026",
144143
"REPLACE_PLACEHOLDER" : "Replace with\u2026",

src/search/FindReplace.js

Lines changed: 78 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ define(function (require, exports, module) {
8484
this.queryInfo = null;
8585
this.foundAny = false;
8686
this.marked = [];
87+
this.resultSet = [];
88+
this.matchIndex = -1;
8789
this.markedCurrent = null;
8890
}
8991

@@ -139,30 +141,71 @@ define(function (require, exports, module) {
139141
state.parsedQuery = parseQuery(queryInfo);
140142
}
141143
}
142-
144+
145+
/**
146+
* @private
147+
* Show the current match index by finding matchRange in the resultSet stored
148+
* in the search state if this is the first call for a new search query. For
149+
* subsequent calls, just compare matchRange with the next match in the resultSet
150+
* based on the search direction and show the next match if they are the same.
151+
* If not, then find the match index by searching matchRange in the entire resultSet.
152+
*
153+
* @param {!SearchState} state The search state that has the array of search result
154+
* @param {!{from: {line: number, ch: number}, to: {line: number, ch: number}}} matchRange - the range of current match
155+
* @param {!boolean} searchBackwards true if searching backwards
156+
*/
157+
function _updateFindBarWithMatchInfo(state, matchRange, searchBackwards) {
158+
// Bail if there is no result set.
159+
if (!state.foundAny) {
160+
return;
161+
}
162+
163+
if (findBar) {
164+
if (state.matchIndex === -1) {
165+
state.matchIndex = _.findIndex(state.resultSet, matchRange);
166+
} else {
167+
state.matchIndex = searchBackwards ? state.matchIndex - 1 : state.matchIndex + 1;
168+
// Adjust matchIndex for modulo wraparound
169+
state.matchIndex = (state.matchIndex + state.resultSet.length) % state.resultSet.length;
170+
171+
// Confirm that we find the right matchIndex. If not, then search
172+
// matchRange in the entire resultSet.
173+
if (!_.isEqual(state.resultSet[state.matchIndex], matchRange)) {
174+
state.matchIndex = _.findIndex(state.resultSet, matchRange);
175+
}
176+
}
177+
178+
if (state.matchIndex !== -1) {
179+
// Convert to 1-based by adding one before showing the index.
180+
findBar.showFindCount(StringUtils.format(Strings.FIND_MATCH_INDEX,
181+
state.matchIndex + 1, state.marked.length));
182+
}
183+
}
184+
}
185+
143186
/**
144187
* @private
145188
* Returns the next match for the current query (from the search state) before/after the given position. Wraps around
146189
* the end of the document if no match is found before the end.
147190
*
148191
* @param {!Editor} editor The editor to search in
149-
* @param {boolean} rev True to search backwards
192+
* @param {boolean} searchBackwards true to search backwards
150193
* @param {{line: number, ch: number}=} pos The position to start from. Defaults to the current primary selection's
151194
* head cursor position.
152195
* @param {boolean=} wrap Whether to wrap the search around if we hit the end of the document. Default true.
153196
* @return {?{start: {line: number, ch: number}, end: {line: number, ch: number}}} The range for the next match, or
154197
* null if there is no match.
155198
*/
156-
function _getNextMatch(editor, rev, pos, wrap) {
199+
function _getNextMatch(editor, searchBackwards, pos, wrap) {
157200
var cm = editor._codeMirror;
158201
var state = getSearchState(cm);
159-
var cursor = getSearchCursor(cm, state, pos || editor.getCursorPos(false, rev ? "start" : "end"));
202+
var cursor = getSearchCursor(cm, state, pos || editor.getCursorPos(false, searchBackwards ? "start" : "end"));
160203

161-
state.lastMatch = cursor.find(rev);
204+
state.lastMatch = cursor.find(searchBackwards);
162205
if (!state.lastMatch && wrap !== false) {
163206
// If no result found before hitting edge of file, try wrapping around
164-
cursor = getSearchCursor(cm, state, rev ? {line: cm.lineCount() - 1} : {line: 0, ch: 0});
165-
state.lastMatch = cursor.find(rev);
207+
cursor = getSearchCursor(cm, state, searchBackwards ? {line: cm.lineCount() - 1} : {line: 0, ch: 0});
208+
state.lastMatch = cursor.find(searchBackwards);
166209
}
167210
if (!state.lastMatch) {
168211
// No result found, period: clear selection & bail
@@ -377,24 +420,26 @@ define(function (require, exports, module) {
377420
}
378421

379422
/**
380-
* Selects the next match (or prev match, if rev==true) starting from either the current position
423+
* Selects the next match (or prev match, if searchBackwards==true) starting from either the current position
381424
* (if pos unspecified) or the given position (if pos specified explicitly). The starting position
382425
* need not be an existing match. If a new match is found, sets to state.lastMatch either the regex
383426
* match result, or simply true for a plain-string match. If no match found, sets state.lastMatch
384427
* to false.
385428
* @param {!Editor} editor
386-
* @param {?boolean} rev
429+
* @param {?boolean} searchBackwards
387430
* @param {?boolean} preferNoScroll
388431
* @param {?Pos} pos
389432
*/
390-
function findNext(editor, rev, preferNoScroll, pos) {
433+
function findNext(editor, searchBackwards, preferNoScroll, pos) {
391434
var cm = editor._codeMirror;
392435
cm.operation(function () {
393436
var state = getSearchState(cm);
394437
clearCurrentMatchHighlight(cm, state);
395438

396-
var nextMatch = _getNextMatch(editor, rev, pos);
439+
var nextMatch = _getNextMatch(editor, searchBackwards, pos);
397440
if (nextMatch) {
441+
_updateFindBarWithMatchInfo(getSearchState(editor._codeMirror),
442+
{from: nextMatch.start, to: nextMatch.end}, searchBackwards);
398443
_selectAndScrollTo(editor, [nextMatch], true, preferNoScroll);
399444
state.markedCurrent = cm.markText(nextMatch.start, nextMatch.end,
400445
{ className: "searching-current-match", startStyle: "searching-first", endStyle: "searching-last" });
@@ -416,6 +461,9 @@ define(function (require, exports, module) {
416461
state.markedCurrent = null;
417462

418463
ScrollTrackMarkers.clear();
464+
465+
state.resultSet = [];
466+
state.matchIndex = -1;
419467
}
420468

421469
function clearSearch(cm) {
@@ -477,37 +525,36 @@ define(function (require, exports, module) {
477525
var cursor = getSearchCursor(cm, state);
478526
if (cm.getValue().length <= FIND_MAX_FILE_SIZE) {
479527
// FUTURE: if last query was prefix of this one, could optimize by filtering last result set
480-
var resultSet = [];
528+
state.resultSet = [];
481529
while (cursor.findNext()) {
482-
resultSet.push(cursor.pos); // pos is unique obj per search result
530+
state.resultSet.push(cursor.pos); // pos is unique obj per search result
483531
}
484532

485533
// Highlight all matches if there aren't too many
486-
if (resultSet.length <= FIND_HIGHLIGHT_MAX) {
534+
if (state.resultSet.length <= FIND_HIGHLIGHT_MAX) {
487535
toggleHighlighting(editor, true);
488536

489-
resultSet.forEach(function (result) {
537+
state.resultSet.forEach(function (result) {
490538
state.marked.push(cm.markText(result.from, result.to,
491539
{ className: "CodeMirror-searching", startStyle: "searching-first", endStyle: "searching-last" }));
492540
});
493-
var scrollTrackPositions = resultSet.map(function (result) {
541+
var scrollTrackPositions = state.resultSet.map(function (result) {
494542
return result.from;
495543
});
496544

497545
ScrollTrackMarkers.addTickmarks(editor, scrollTrackPositions);
498546
}
499547

500-
var countInfo;
501-
if (resultSet.length === 0) {
502-
countInfo = Strings.FIND_NO_RESULTS;
503-
} else if (resultSet.length === 1) {
504-
countInfo = Strings.FIND_RESULT_COUNT_SINGLE;
505-
} else {
506-
countInfo = StringUtils.format(Strings.FIND_RESULT_COUNT, resultSet.length);
548+
// Here we only update find bar with no result. In the case of a match
549+
// a findNext() call is guaranteed to be followed by this function call,
550+
// and findNext() in turn calls _updateFindBarWithMatchInfo() to show the
551+
// match index.
552+
if (state.resultSet.length === 0) {
553+
findBar.showFindCount(Strings.FIND_NO_RESULTS);
507554
}
508-
findBar.showFindCount(countInfo);
509-
state.foundAny = (resultSet.length > 0);
510-
indicateHasMatches(resultSet.length);
555+
556+
state.foundAny = (state.resultSet.length > 0);
557+
indicateHasMatches(state.resultSet.length);
511558

512559
} else {
513560
// On huge documents, just look for first match & then stop
@@ -593,8 +640,8 @@ define(function (require, exports, module) {
593640
.on("queryChange.FindReplace", function (e) {
594641
handleQueryChange(editor, state);
595642
})
596-
.on("doFind.FindReplace", function (e, rev) {
597-
findNext(editor, rev);
643+
.on("doFind.FindReplace", function (e, searchBackwards) {
644+
findNext(editor, searchBackwards);
598645
})
599646
.on("close.FindReplace", function (e) {
600647
// Clear highlights but leave search state in place so Find Next/Previous work after closing
@@ -612,12 +659,12 @@ define(function (require, exports, module) {
612659

613660
/**
614661
* If no search pending, opens the Find dialog. If search bar already open, moves to
615-
* next/prev result (depending on 'rev')
662+
* next/prev result (depending on 'searchBackwards')
616663
*/
617-
function doSearch(editor, rev) {
664+
function doSearch(editor, searchBackwards) {
618665
var state = getSearchState(editor._codeMirror);
619666
if (state.parsedQuery) {
620-
findNext(editor, rev);
667+
findNext(editor, searchBackwards);
621668
return;
622669
}
623670

0 commit comments

Comments
 (0)