diff --git a/lib/occurrence-manager.js b/lib/occurrence-manager.js index 902aa3230..de5c770fd 100644 --- a/lib/occurrence-manager.js +++ b/lib/occurrence-manager.js @@ -190,8 +190,10 @@ module.exports = class OccurrenceManager { // It is important to show autocomplete+ popup at proper position( popup shows up at last-selection ). // E.g. `c o f`(change occurrence in a-function) show autocomplete+ popup at closest occurrence. const closestRange = this.getClosestRangeForSelection(ranges, selection) - ranges.splice(ranges.indexOf(closestRange), 1) // remove - ranges.push(closestRange) // then push to last + if (!this.vimState.getConfig('clearMultipleCursorsToFirstPosition')) { + ranges.splice(ranges.indexOf(closestRange), 1) // remove + ranges.push(closestRange) // then push to last + } rangesToSelect.push(...ranges) diff --git a/lib/settings.js b/lib/settings.js index eb063c696..963dbd7b0 100644 --- a/lib/settings.js +++ b/lib/settings.js @@ -330,6 +330,7 @@ module.exports = new Settings('vim-mode-plus', { description: 'Start in insert-mode when editorElement matches scope' }, clearMultipleCursorsOnEscapeInsertMode: false, + clearMultipleCursorsToFirstPosition: false, autoSelectPersistentSelectionOnOperate: true, automaticallyEscapeInsertModeOnActivePaneItemChange: { default: false, diff --git a/lib/vim-state.js b/lib/vim-state.js index 35be563c2..c22fe6722 100644 --- a/lib/vim-state.js +++ b/lib/vim-state.js @@ -352,10 +352,13 @@ module.exports = class VimState { } // What's this? - // clear all selections and final cursor position becomes head of last selection. + // clear all selections and final cursor position becomes head of last selection (optionally first selection) // editor.clearSelections() does not respect last selection's head, since it merge all selections before clearing. clearSelections () { - this.editor.setCursorBufferPosition(this.editor.getCursorBufferPosition()) + const position = (this.getConfig('clearMultipleCursorsToFirstPosition')) + ? this.editor.getCursorBufferPositions()[0] + : this.editor.getCursorBufferPosition() + this.editor.setCursorBufferPosition(position) } resetNormalMode (options = {}) { diff --git a/spec/occurrence-spec.coffee b/spec/occurrence-spec.coffee index ae6a6ec85..cb3a32df8 100644 --- a/spec/occurrence-spec.coffee +++ b/spec/occurrence-spec.coffee @@ -1201,3 +1201,19 @@ describe "Occurrence", -> ensure null, mode: "normal", occurrenceText: [] atom.confirm.andCallFake ({buttons}) -> buttons.indexOf("Continue") ensure "g o", mode: "normal", occurrenceText: ['oo', 'oo', 'oo', 'oo', 'oo'] + + describe "clearMultipleCursorsToFirstPosition setting", -> + beforeEach -> + settings.set('clearMultipleCursorsToFirstPosition', true) + + it "clear multiple occurence cursors by respecting first cursor's position", -> + set + text: """ + ooo: xxx: ooo: + xxx: ooo: xxx: + """ + cursor: [0, 0] + ensure "c o a e", mode: 'insert', numCursors: 3 + editor.insertText('===') + ensure "escape" + ensure "escape", mode: 'normal', numCursors: 1, cursor: [0, 2] diff --git a/spec/vim-state-spec.coffee b/spec/vim-state-spec.coffee index 35df88f0b..f5be073c3 100644 --- a/spec/vim-state-spec.coffee +++ b/spec/vim-state-spec.coffee @@ -230,6 +230,16 @@ describe "VimState", -> set cursor: [[0, 2], [0, 1]] ensure 'escape', mode: 'normal', numCursors: 1, cursor: [0, 0] + describe "clearMultipleCursorsToFirstPosition setting", -> + beforeEach -> + settings.set('clearMultipleCursorsToFirstPosition', true) + it "clear multiple cursors by respecting first cursor's position", -> + ensure 'escape', mode: 'normal', numCursors: 1, cursor: [0, 0] + + it "clear multiple cursors by respecting first cursor's position", -> + set cursor: [[0, 2], [0, 1]] + ensure 'escape', mode: 'normal', numCursors: 1, cursor: [0, 1] + describe "when disabled", -> beforeEach -> settings.set('clearMultipleCursorsOnEscapeInsertMode', false)