diff --git a/spec/editor-spec.coffee b/spec/editor-spec.coffee index f2cf94142..007dc52f6 100644 --- a/spec/editor-spec.coffee +++ b/spec/editor-spec.coffee @@ -1261,6 +1261,29 @@ describe "Editor", -> expect(editor.isFoldedAtBufferRow(1)).toBeTruthy() expect(editor.isFoldedAtBufferRow(6)).toBeTruthy() + describe ".setSelectedScreenRanges(ranges)", -> + beforeEach -> + editor.foldBufferRow(4) + + it "clears existing selections and creates selections for each of the given ranges", -> + editor.setSelectedScreenRanges([[[3, 4], [3, 7]], [[5, 4], [5, 7]]]) + expect(editor.getSelectedBufferRanges()).toEqual [[[3, 4], [3, 7]], [[8, 4], [8, 7]]] + + editor.setSelectedScreenRanges([[[6, 2], [6, 4]]]) + expect(editor.getSelectedScreenRanges()).toEqual [[[6, 2], [6, 4]]] + + it "merges intersecting selections and unfolds the fold", -> + editor.setSelectedScreenRanges([[[2, 2], [3, 3]], [[3, 0], [5, 5]]]) + expect(editor.getSelectedScreenRanges()).toEqual [[[2, 2], [8, 5]]] + + it "recyles existing selection instances", -> + selection = editor.getSelection() + editor.setSelectedScreenRanges([[[2, 2], [3, 4]], [[4, 4], [5, 5]]]) + + [selection1, selection2] = editor.getSelections() + expect(selection1).toBe selection + expect(selection1.getScreenRange()).toEqual [[2, 2], [3, 4]] + describe ".setSelectedBufferRange(range)", -> describe "when the 'autoscroll' option is true", -> it "autoscrolls to the selection", -> diff --git a/src/editor.coffee b/src/editor.coffee index 6ed2e4e53..f405e88ad 100644 --- a/src/editor.coffee +++ b/src/editor.coffee @@ -1868,6 +1868,27 @@ class Editor extends Model setSelectedScreenRange: (screenRange, options) -> @setSelectedBufferRange(@bufferRangeForScreenRange(screenRange, options), options) + # Essential: Set the selected ranges in screen coordinates. If there are multiple + # selections, they are replaced by new selections with the given ranges. + # + # * `screenRanges` An {Array} of {Range}s or range-compatible {Array}s. + # * `options` (optional) An options {Object}: + # * `reversed` A {Boolean} indicating whether to create the selection in a + # reversed orientation. + setSelectedScreenRanges: (screenRanges, options={}) -> + throw new Error("Passed an empty array to setSelectedScreenRanges") unless screenRanges.length + + selections = @getSelections() + selection.destroy() for selection in selections[screenRanges.length...] + + @mergeIntersectingSelections options, => + for screenRange, i in screenRanges + screenRange = Range.fromObject(screenRange) + if selections[i] + selections[i].setScreenRange(screenRange, options) + else + @addSelectionForScreenRange(screenRange, options) + # Essential: Add a selection for the given range in buffer coordinates. # # * `bufferRange` A {Range} @@ -1882,6 +1903,20 @@ class Editor extends Model selection.autoscroll() if @manageScrollPosition selection + # Essential: Add a selection for the given range in screen coordinates. + # + # * `screenRange` A {Range} + # * `options` (optional) An options {Object}: + # * `reversed` A {Boolean} indicating whether to create the selection in a + # reversed orientation. + # + # Returns the added {Selection}. + addSelectionForScreenRange: (screenRange, options={}) -> + @markScreenRange(screenRange, _.defaults(@getSelectionMarkerAttributes(), options)) + selection = @getLastSelection() + selection.autoscroll() if @manageScrollPosition + selection + # Essential: Select from the current cursor position to the given position in # screen coordinates. #