Support multiple selections when "Only In Selection" option is enabled
MODIFY
lib/buffer-search.js
lib/buffer-search.js
@@ -77,7 +77,8 @@ class BufferSearch {
changedParams.wholeWord != null ||
changedParams.caseSensitive != null ||
changedParams.inCurrentSelection != null ||
- (this.findOptions.inCurrentSelection === true && !this.editor.getSelectedBufferRange().isEqual(this.selectedRange))) {
+ (this.findOptions.inCurrentSelection === true
+ && !selectionsEqual(this.editor.getSelectedBufferRanges(), this.selectedRanges))) {
this.recreateMarkers();
}
}
@@ -135,37 +136,32 @@ class BufferSearch {
createMarkers(start, end) {
let newMarkers = [];
if (this.findOptions.findPattern && this.editor) {
- this.selectedRange = this.editor.getSelectedBufferRange()
- if (this.findOptions.inCurrentSelection && !this.selectedRange.isEmpty()) {
- start = Point.max(start, this.selectedRange.start);
- end = Point.min(end, this.selectedRange.end);
+ this.selectedRanges = this.editor.getSelectedBufferRanges()
+
+ let searchRanges = []
+ if (this.findOptions.inCurrentSelection) {
+ searchRanges.push(...this.selectedRanges.filter(range => !range.isEmpty()))
+ }
+ if (searchRanges.length === 0) {
+ searchRanges.push(Range(start, end))
}
const buffer = this.editor.getBuffer()
const regex = this.getFindPatternRegex(buffer.hasAstral && buffer.hasAstral())
if (regex) {
try {
- // TODO - remove this conditional after Atom 1.25 ships
- if (buffer.findAndMarkAllInRangeSync) {
- newMarkers = this.editor.getBuffer().findAndMarkAllInRangeSync(
+ for (const range of searchRanges) {
+ const bufferMarkers = this.editor.getBuffer().findAndMarkAllInRangeSync(
this.resultsMarkerLayer.bufferMarkerLayer,
regex,
- Range(start, end),
+ range,
{invalidate: 'inside'}
);
- for (let i = 0, n = newMarkers.length; i < n; i++) {
- newMarkers[i] = this.resultsMarkerLayer.getMarker(newMarkers[i].id)
+ for (const bufferMarker of bufferMarkers) {
+ newMarkers.push(this.resultsMarkerLayer.getMarker(bufferMarker.id))
}
- } else {
- buffer.scanInRange(regex, Range(start, end), ({range}) => {
- newMarkers.push(this.createMarker(range));
- });
}
} catch (error) {
- // TODO - remove after Atom 1.25 ships.
- if (/RegExp too big$/.test(error.message)) {
- error.message = "regular expression is too large";
- }
this.emitter.emit('did-error', error);
return false;
}
@@ -291,3 +287,16 @@ class BufferSearch {
}
}
};
+
+function selectionsEqual(selectionsA, selectionsB) {
+ if (selectionsA.length === selectionsB.length) {
+ for (let i = 0; i < selectionsA.length; i++) {
+ if (!selectionsA[i].isEqual(selectionsB[i])) {
+ return false
+ }
+ }
+ return true
+ } else {
+ return false
+ }
+}

MODIFY
spec/buffer-search-spec.js
spec/buffer-search-spec.js
@@ -448,6 +448,56 @@ describe('BufferSearch', () => {
})
})
+ describe("if there are multiple non-empty selections", () => {
+ beforeEach(() => {
+ editor.setSelectedBufferRanges([
+ [[1, 3], [2, 11]],
+ [[5, 2], [8, 0]],
+ ]);
+ })
+
+ it("searches in all the selections", () => {
+ model.search("a+");
+
+ expect(getHighlightedRanges()).toEqual([
+ [[2, 4], [2, 7]],
+ [[5, 2], [5, 3]],
+ [[6, 4], [6, 7]],
+ [[7, 8], [7, 11]]
+ ]);
+ })
+
+ it("executes another search if the current selection is different from the last search's selection", () => {
+ spyOn(model, 'recreateMarkers').andCallThrough()
+
+ model.search("a+");
+ editor.setSelectedBufferRanges([
+ [[1, 3], [2, 11]],
+ [[5, 1], [8, 0]],
+ ]);
+ model.search("a+");
+
+ expect(model.recreateMarkers.callCount).toBe(2)
+ expect(getHighlightedRanges()).toEqual([
+ [[2, 4], [2, 7]],
+ [[5, 1], [5, 3]],
+ [[6, 4], [6, 7]],
+ [[7, 8], [7, 11]]
+ ]);
+ })
+
+ it("does not execute another search if the current selection is idential to the last search's selection", () => {
+ spyOn(model, 'recreateMarkers').andCallThrough()
+ editor.setSelectedBufferRanges([
+ [[1, 3], [2, 11]],
+ [[5, 1], [8, 0]],
+ ]);
+ model.search("a+");
+ model.search("a+");
+ expect(model.recreateMarkers.callCount).toBe(1)
+ })
+ })
+
describe("if the current selection is empty", () => {
beforeEach(() => {
editor.setSelectedBufferRange([[0, 0], [0, 0]]);

Support multiple selections when "Only In Selection" option is enabled