keep selection indices valid when adding / removing results
MODIFY
lib/project/results-model.coffee
lib/project/results-model.coffee
@@ -222,8 +222,10 @@ class ResultsModel
addResult: (filePath, result) ->
filePathInsertedIndex = null
+ filePathUpdatedIndex = null
if @results[filePath]
@matchCount -= @results[filePath].matches.length
+ filePathUpdatedIndex = @paths.indexOf(filePath)
else
@pathCount++
filePathInsertedIndex = binaryIndex(@paths, filePath, stringCompare)
@@ -232,16 +234,17 @@ class ResultsModel
@matchCount += result.matches.length
@results[filePath] = result
- @emitter.emit 'did-add-result', {filePath, result, filePathInsertedIndex}
+ @emitter.emit 'did-add-result', {filePath, result, filePathInsertedIndex, filePathUpdatedIndex}
removeResult: (filePath) ->
if @results[filePath]
@pathCount--
@matchCount -= @results[filePath].matches.length
+ filePathRemovedIndex = @paths.indexOf(filePath)
@paths = _.without(@paths, filePath)
delete @results[filePath]
- @emitter.emit 'did-remove-result', {filePath}
+ @emitter.emit 'did-remove-result', {filePath, filePathRemovedIndex}
onContentsModified: (editor) =>
return unless @active and @regex

MODIFY
lib/project/results-view.js
lib/project/results-view.js
@@ -61,8 +61,13 @@ class ResultsView {
}
didClearSearchState() {
+ if (this.model.getPaths().length > 0) {
this.selectedResultIndex = 0;
this.selectedMatchIndex = 0;
+ } else {
+ this.selectedResultIndex = -1;
+ this.selectedMatchIndex = -1;
+ }
this.collapsedResultIndices.length = 0;
etch.update(this);
}
@@ -171,11 +176,40 @@ class ResultsView {
}
}
- didAddResult() {
+ didAddResult({filePathInsertedIndex, filePathUpdatedIndex}) {
+ if (this.selectedResultIndex == -1) {
+ // if no result was selected before select the first one
+ this.selectedResultIndex = 0;
+ this.selectedMatchIndex = 0;
+ } else if (filePathInsertedIndex !== null && filePathInsertedIndex <= this.selectedResultIndex) {
+ // if a result is inserted before the current selection
+ // update the selection information to still reference the same result
+ this.selectedResultIndex++;
+ } else if (filePathUpdatedIndex !== null && filePathUpdatedIndex == this.selectedResultIndex) {
+ // if the current result is updated
+ // ensure that the match index still exists or select the last one
+ const selectedResult = this.model.getResultAt(this.selectedResultIndex);
+ if (this.selectedMatchIndex >= selectedResult.matches.length) {
+ this.selectedMatchIndex = selectedResult.matches.length - 1;
+ }
+ }
etch.update(this);
}
- didRemoveResult() {
+ didRemoveResult({filePathRemovedIndex}) {
+ if (filePathRemovedIndex < this.selectedResultIndex) {
+ // if a result is removed before the current selection
+ // update the selection information to still reference the same result
+ this.selectedResultIndex--;
+ } else if (filePathRemovedIndex == this.selectedResultIndex) {
+ // if the result of the current selection is removed
+ // update the selection information to reference the next result
+ // if the last result is removed select the previous result
+ if (this.selectedResultIndex >= this.model.getPaths().length) {
+ this.selectedResultIndex = this.model.getPaths().length - 1;
+ }
+ this.selectedMatchIndex = -1;
+ }
etch.update(this);
}

keep selection indices valid when adding / removing results