mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Redesign commands around multiple selections
Every command returns an array of buffer ranges to select from its execute method. The composite command loops through each current selection with each command, then sets the new selection to the aggregated buffer ranges returned by all commands at that step.
This commit is contained in:
@@ -42,18 +42,35 @@ describe "CommandInterpreter", ->
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[0,0], [12,2]]
|
||||
|
||||
describe ".", ->
|
||||
it 'maintains the current selection', ->
|
||||
editor.setSelectionBufferRange([[1,1], [2,2]])
|
||||
interpreter.eval(editor, '.')
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[1,1], [2,2]]
|
||||
describe "when a single selection", ->
|
||||
it 'maintains the current selection', ->
|
||||
editor.clearSelections()
|
||||
editor.setSelectionBufferRange([[1,1], [2,2]])
|
||||
interpreter.eval(editor, '.')
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[1,1], [2,2]]
|
||||
|
||||
editor.setSelectionBufferRange([[1,1], [2,2]])
|
||||
interpreter.eval(editor, '.,')
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[1,1], [12,2]]
|
||||
editor.setSelectionBufferRange([[1,1], [2,2]])
|
||||
interpreter.eval(editor, '.,')
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[1,1], [12,2]]
|
||||
|
||||
editor.setSelectionBufferRange([[1,1], [2,2]])
|
||||
interpreter.eval(editor, ',.')
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[0,0], [2,2]]
|
||||
editor.setSelectionBufferRange([[1,1], [2,2]])
|
||||
interpreter.eval(editor, ',.')
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[0,0], [2,2]]
|
||||
|
||||
describe "with multiple selections", ->
|
||||
it "maintains the current selections", ->
|
||||
preSelections = editor.getSelections()
|
||||
expect(preSelections.length).toBe 3
|
||||
[preRange1, preRange2, preRange3] = preSelections.map (s) -> s.getScreenRange()
|
||||
|
||||
interpreter.eval(editor, '.')
|
||||
|
||||
selections = editor.getSelections()
|
||||
expect(selections.length).toBe 3
|
||||
[selection1, selection2, selection3] = selections
|
||||
expect(selection1.getScreenRange()).toEqual preRange1
|
||||
expect(selection2.getScreenRange()).toEqual preRange2
|
||||
expect(selection3.getScreenRange()).toEqual preRange3
|
||||
|
||||
describe "/regex/", ->
|
||||
beforeEach ->
|
||||
@@ -69,14 +86,16 @@ describe "CommandInterpreter", ->
|
||||
interpreter.eval(editor, '/pivot')
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[6,16], [6,21]]
|
||||
|
||||
it "searches from the end of the selection furthest forward in the buffer", ->
|
||||
it "searches from the end of each selection in the buffer", ->
|
||||
editor.clearSelections()
|
||||
editor.setSelectionBufferRange([[4,16], [4,20]])
|
||||
editor.addSelectionForBufferRange([[1,16], [2,20]])
|
||||
expect(editor.getSelections().length).toBe 2
|
||||
interpreter.eval(editor, '/pivot')
|
||||
expect(editor.getSelections().length).toBe 1
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[6,16], [6,21]]
|
||||
selections = editor.getSelections()
|
||||
expect(selections.length).toBe 2
|
||||
expect(selections[0].getBufferRange()).toEqual [[3,8], [3,13]]
|
||||
expect(selections[1].getBufferRange()).toEqual [[6,16], [6,21]]
|
||||
|
||||
it "wraps around to the beginning of the buffer, but doesn't infinitely loop if no matches are found", ->
|
||||
editor.setSelectionBufferRange([[10, 0], [10,3]])
|
||||
|
||||
@@ -5,8 +5,8 @@ module.exports =
|
||||
class AddressRange extends Address
|
||||
constructor: (@startAddress, @endAddress) ->
|
||||
|
||||
getRange: (editor) ->
|
||||
new Range(@startAddress.getRange(editor).start, @endAddress.getRange(editor).end)
|
||||
getRange: (editor, currentRange) ->
|
||||
new Range(@startAddress.getRange(editor, currentRange).start, @endAddress.getRange(editor, currentRange).end)
|
||||
|
||||
isRelative: ->
|
||||
@startAddress.isRelative() or @endAddress.isRelative()
|
||||
|
||||
@@ -3,8 +3,6 @@ Command = require 'command-interpreter/command'
|
||||
module.exports =
|
||||
class Address extends Command
|
||||
execute: (editor, currentRange) ->
|
||||
range = @getRange(editor, currentRange)
|
||||
editor.clearSelections()
|
||||
editor.setSelectionBufferRange(range)
|
||||
[@getRange(editor, currentRange)]
|
||||
|
||||
isAddress: -> true
|
||||
|
||||
@@ -6,9 +6,11 @@ class CompositeCommand
|
||||
|
||||
execute: (editor) ->
|
||||
for command in @subcommands
|
||||
ranges = editor.getSelectionsOrderedByBufferPosition().map (selection) -> selection.getBufferRange()
|
||||
for range in ranges
|
||||
command.execute(editor, range)
|
||||
newRanges = []
|
||||
currentRanges = editor.getSelectionsOrderedByBufferPosition().map (selection) -> selection.getBufferRange()
|
||||
for currentRange in currentRanges
|
||||
newRanges.push(command.execute(editor, currentRange)...)
|
||||
editor.setSelectedBufferRanges(newRanges)
|
||||
|
||||
isRelativeAddress: ->
|
||||
_.all(@subcommands, (command) -> command.isAddress() and command.isRelative())
|
||||
|
||||
@@ -3,7 +3,7 @@ Range = require 'range'
|
||||
|
||||
module.exports =
|
||||
class CurrentSelectionAddress extends Address
|
||||
getRange: (editor) ->
|
||||
editor.getSelection().getBufferRange()
|
||||
getRange: (editor, currentRange) ->
|
||||
currentRange
|
||||
|
||||
isRelative: -> true
|
||||
|
||||
@@ -8,12 +8,8 @@ class SelectAllMatches extends Command
|
||||
constructor: (pattern) ->
|
||||
@regex = new RegExp(pattern, 'g')
|
||||
|
||||
execute: (editor) ->
|
||||
execute: (editor, currentRange) ->
|
||||
rangesToSelect = []
|
||||
for selection in editor.getSelections()
|
||||
editor.buffer.scanRegexMatchesInRange @regex, selection.getBufferRange(), (match, range) ->
|
||||
rangesToSelect.push(range)
|
||||
|
||||
editor.clearSelections()
|
||||
editor.setSelectionBufferRange(rangesToSelect[0])
|
||||
editor.addSelectionForBufferRange(range) for range in rangesToSelect[1..]
|
||||
editor.buffer.scanRegexMatchesInRange @regex, currentRange, (match, range) ->
|
||||
rangesToSelect.push(range)
|
||||
rangesToSelect
|
||||
|
||||
@@ -9,7 +9,7 @@ class Substitution extends Command
|
||||
@replacementText = replacementText
|
||||
@regex = new RegExp(pattern, options.join(''))
|
||||
|
||||
execute: (editor, range) ->
|
||||
editor.buffer.scanRegexMatchesInRange @regex, range, (match, matchRange, { replace }) =>
|
||||
execute: (editor, currentRange) ->
|
||||
editor.buffer.scanRegexMatchesInRange @regex, currentRange, (match, matchRange, { replace }) =>
|
||||
replace(@replacementText)
|
||||
|
||||
[currentRange]
|
||||
|
||||
@@ -19,7 +19,6 @@ class CompositeSeleciton
|
||||
getLastSelection: ->
|
||||
_.last(@selections)
|
||||
|
||||
|
||||
getSelectionsOrderedByBufferPosition: ->
|
||||
@getSelections().sort (a, b) ->
|
||||
aRange = a.getBufferRange()
|
||||
@@ -57,6 +56,13 @@ class CompositeSeleciton
|
||||
setBufferRange: (bufferRange, options) ->
|
||||
@getLastSelection().setBufferRange(bufferRange, options)
|
||||
|
||||
setBufferRanges: (bufferRanges) ->
|
||||
@clearSelections()
|
||||
@setBufferRange(bufferRanges[0])
|
||||
for bufferRange in bufferRanges[1..]
|
||||
@addSelectionForBufferRange(bufferRange)
|
||||
@mergeIntersectingSelections()
|
||||
|
||||
getBufferRange: (bufferRange) ->
|
||||
@getLastSelection().getBufferRange()
|
||||
|
||||
|
||||
@@ -388,6 +388,7 @@ class Editor extends View
|
||||
getLastSelectionInBuffer: -> @compositeSelection.getLastSelectionInBuffer()
|
||||
getSelectedText: -> @compositeSelection.getSelection().getText()
|
||||
setSelectionBufferRange: (bufferRange, options) -> @compositeSelection.setBufferRange(bufferRange, options)
|
||||
setSelectedBufferRanges: (bufferRanges) -> @compositeSelection.setBufferRanges(bufferRanges)
|
||||
addSelectionForBufferRange: (bufferRange, options) -> @compositeSelection.addSelectionForBufferRange(bufferRange, options)
|
||||
selectRight: -> @compositeSelection.selectRight()
|
||||
selectLeft: -> @compositeSelection.selectLeft()
|
||||
|
||||
Reference in New Issue
Block a user