Add x command, which selects all matches in the current selection

This commit is contained in:
Nathan Sobo
2012-03-27 12:54:28 -07:00
parent 461fdd5e61
commit ad3aa0709c
4 changed files with 68 additions and 13 deletions

View File

@@ -38,13 +38,13 @@ describe "CommandInterpreter", ->
interpreter.eval(editor, '.')
expect(editor.getSelection().getBufferRange()).toEqual [[1,1], [2,2]]
# editor.getSelection().setBufferRange([[1,1], [2,2]])
# interpreter.eval(editor, '.,')
# expect(editor.getSelection().getBufferRange()).toEqual [[1,1], [12,2]]
editor.getSelection().setBufferRange([[1,1], [2,2]])
interpreter.eval(editor, '.,')
expect(editor.getSelection().getBufferRange()).toEqual [[1,1], [12,2]]
# editor.getSelection().setBufferRange([[1,1], [2,2]])
# interpreter.eval(editor, ',.')
# expect(editor.getSelection().getBufferRange()).toEqual [[0,0], [2,2]]
editor.getSelection().setBufferRange([[1,1], [2,2]])
interpreter.eval(editor, ',.')
expect(editor.getSelection().getBufferRange()).toEqual [[0,0], [2,2]]
describe "/regex/", ->
it 'selects text matching regex after current selection', ->
@@ -78,6 +78,18 @@ describe "CommandInterpreter", ->
interpreter.eval(editor, ',')
expect(editor.getSelection().getBufferRange()).toEqual [[0, 0], [12, 2]]
describe "x/regex/", ->
it "sets the current selection to every match of the regex in the current selection", ->
interpreter.eval(editor, '6,7 x/current/')
selections = editor.getSelections()
expect(selections.length).toBe 4
expect(selections[0].getBufferRange()).toEqual [[5,6], [5,13]]
expect(selections[1].getBufferRange()).toEqual [[6,6], [6,13]]
expect(selections[2].getBufferRange()).toEqual [[6,34], [6,41]]
expect(selections[3].getBufferRange()).toEqual [[6,56], [6,63]]
describe "substitution", ->
it "does nothing if there are no matches", ->
editor.getSelection().setBufferRange([[6, 0], [6, 44]])

View File

@@ -0,0 +1,39 @@
Command = require 'command-interpreter/command'
Range = require 'range'
module.exports =
class SelectAllMatches extends Command
@regex: null
constructor: (pattern) ->
@regex = new RegExp(pattern)
execute: (editor) ->
selectedText = editor.getSelectedText()
selectionStartIndex = editor.buffer.characterIndexForPosition(editor.getSelection().getBufferRange().start)
matchingRanges = @findMatchingRanges(editor, selectedText, selectionStartIndex)
return unless matchingRanges.length
editor.setSelectionBufferRange(matchingRanges[0])
editor.addSelectionForBufferRange(range) for range in matchingRanges[1..]
findMatchingRanges: (editor, text, startIndex) ->
console.log text
return [] unless match = text.match(@regex)
console.log match
console.log match[0]
matchStartIndex = startIndex + match.index
matchEndIndex = matchStartIndex + match[0].length
buffer = editor.buffer
startPosition = buffer.positionForCharacterIndex(matchStartIndex)
endPosition = buffer.positionForCharacterIndex(matchEndIndex)
range = new Range(startPosition, endPosition)
text = text[(match.index + match[0].length)..]
startIndex = matchEndIndex
[range].concat(@findMatchingRanges(editor, text, startIndex))

View File

@@ -6,16 +6,14 @@
var EofAddress = require('command-interpreter/eof-address');
var CurrentSelectionAddress = require('command-interpreter/current-selection-address')
var RegexAddress = require('command-interpreter/regex-address')
var SelectAllMatches = require('command-interpreter/select-all-matches')
}
start
= address:address? _ command:substitution? {
var commands = [];
if (address) commands.push(address);
if (command) commands.push(command);
start = expressions:(expression+) {
return new CompositeCommand(expressions)
}
return new CompositeCommand(commands);
}
expression = _ expression:(address / command) _ { return expression; }
address = addressRange / primitiveAddress
@@ -32,11 +30,16 @@ primitiveAddress
/ '.' { return new CurrentSelectionAddress() }
/ '/' pattern:pattern '/'? { return new RegexAddress(pattern)}
command = substitution / selectAllMatches
substitution
= "s" _ "/" find:pattern "/" replace:pattern "/" _ options:[g]* {
return new Substitution(find, replace, options);
}
selectAllMatches
= 'x' _ '/' pattern:pattern '/'? { return new SelectAllMatches(pattern) }
pattern
= pattern:[^/]* { return pattern.join('') }

View File

@@ -356,6 +356,7 @@ class Editor extends View
getCursorBufferPosition: -> @getCursor().getBufferPosition()
getSelection: (index) -> @compositeSelection.getSelection(index)
getSelections: -> @compositeSelection.getSelections()
getSelectedText: -> @compositeSelection.getSelection().getText()
setSelectionBufferRange: (bufferRange, options) -> @compositeSelection.setBufferRange(bufferRange, options)
addSelectionForBufferRange: (bufferRange, options) -> @compositeSelection.addSelectionForBufferRange(bufferRange, options)