diff --git a/menus/darwin.cson b/menus/darwin.cson index 8cd314c1e..c20379e54 100644 --- a/menus/darwin.cson +++ b/menus/darwin.cson @@ -99,6 +99,7 @@ submenu: [ { label: 'Add Selection Above', command: 'editor:add-selection-above' } { label: 'Add Selection Below', command: 'editor:add-selection-below' } + { label: 'Split into Lines', command: 'editor:split-selection-into-lines'} { type: 'separator' } { label: 'Select to Top', command: 'core:select-to-top' } { label: 'Select to Bottom', command: 'core:select-to-bottom' } diff --git a/menus/win32.cson b/menus/win32.cson index e4017fc42..8263f99a5 100644 --- a/menus/win32.cson +++ b/menus/win32.cson @@ -106,6 +106,7 @@ submenu: [ { label: 'Add Selection &Above', command: 'editor:add-selection-above' } { label: 'Add Selection &Below', command: 'editor:add-selection-below' } + { label: 'S&plit into Lines', command: 'editor:split-selection-into-lines'} { type: 'separator' } { label: 'Select to &Top', command: 'core:select-to-top' } { label: 'Select to Botto&m', command: 'core:select-to-bottom' } diff --git a/spec/editor-spec.coffee b/spec/editor-spec.coffee index 821c9becb..93d19e815 100644 --- a/spec/editor-spec.coffee +++ b/spec/editor-spec.coffee @@ -1181,6 +1181,27 @@ describe "Editor", -> [[10, 0], [10, 0]] ] + describe ".splitSelectionsIntoLines()", -> + it "splits all multi-line selections into one selection per line", -> + editor.setSelectedBufferRange([[0, 3], [2, 4]]) + editor.splitSelectionsIntoLines() + expect(editor.getSelectedBufferRanges()).toEqual [ + [[0, 3], [0, 29]] + [[1, 0], [1, 30]] + [[2, 0], [2, 4]] + ] + + editor.setSelectedBufferRange([[0, 3], [1, 10]]) + editor.splitSelectionsIntoLines() + expect(editor.getSelectedBufferRanges()).toEqual [ + [[0, 3], [0, 29]] + [[1, 0], [1, 10]] + ] + + editor.setSelectedBufferRange([[0, 0], [0, 3]]) + editor.splitSelectionsIntoLines() + expect(editor.getSelectedBufferRanges()).toEqual [[[0, 0], [0, 3]]] + describe ".consolidateSelections()", -> it "destroys all selections but the most recent, returning true if any selections were destroyed", -> editor.setSelectedBufferRange([[3, 16], [3, 21]]) diff --git a/src/editor-view.coffee b/src/editor-view.coffee index 9c51a5554..f198b2df4 100644 --- a/src/editor-view.coffee +++ b/src/editor-view.coffee @@ -183,6 +183,7 @@ class EditorView extends View 'editor:newline-above': @insertNewlineAbove 'editor:add-selection-below': @addSelectionBelow 'editor:add-selection-above': @addSelectionAbove + 'editor:split-selection-into-lines': => @editor.splitSelectionsIntoLines() 'editor:toggle-soft-tabs': @toggleSoftTabs 'editor:toggle-soft-wrap': @toggleSoftWrap 'editor:fold-all': @foldAll diff --git a/src/editor.coffee b/src/editor.coffee index cff06ddfc..bbefa2f69 100644 --- a/src/editor.coffee +++ b/src/editor.coffee @@ -1190,6 +1190,23 @@ class Editor extends Model addSelectionAbove: -> @expandSelectionsBackward (selection) => selection.addSelectionAbove() + # Public: Split any multi-line selections into one selection per line. + # + # This methods break apart all multi-line selections to create multiple + # single-line selections that cumulatively cover the same original area. + splitSelectionsIntoLines: -> + for selection in @getSelections() + range = selection.getBufferRange() + continue if range.isSingleLine() + + selection.destroy() + {start, end} = range + @addSelectionForBufferRange([start, [start.row, Infinity]]) + {row} = start + while ++row < end.row + @addSelectionForBufferRange([[row, 0], [row, Infinity]]) + @addSelectionForBufferRange([[end.row, 0], [end.row, end.column]]) + # Public: Transposes the current text selections. # # The text in each selection is reversed so `abcd` would become `dcba`. The