mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-22 08:28:41 +03:00
255 lines
12 KiB
CoffeeScript
255 lines
12 KiB
CoffeeScript
CommandInterpreter = require 'command-interpreter'
|
|
Buffer = require 'buffer'
|
|
Editor = require 'editor'
|
|
|
|
describe "CommandInterpreter", ->
|
|
[interpreter, editor, buffer] = []
|
|
|
|
beforeEach ->
|
|
buffer = new Buffer(require.resolve 'fixtures/sample.js')
|
|
editor = new Editor({buffer})
|
|
interpreter = new CommandInterpreter()
|
|
|
|
describe "addresses", ->
|
|
beforeEach ->
|
|
editor.addSelectionForBufferRange([[7,0], [7,11]])
|
|
editor.addSelectionForBufferRange([[8,0], [8,11]])
|
|
|
|
describe "a line address", ->
|
|
it "selects the specified line", ->
|
|
interpreter.eval(editor, '4')
|
|
expect(editor.getSelections().length).toBe 1
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[3, 0], [4, 0]]
|
|
|
|
describe "0", ->
|
|
it "selects the zero-length string at the start of the file", ->
|
|
interpreter.eval(editor, '0')
|
|
expect(editor.getSelections().length).toBe 1
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[0,0], [0,0]]
|
|
|
|
interpreter.eval(editor, '0,1')
|
|
expect(editor.getSelections().length).toBe 1
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[0,0], [1,0]]
|
|
|
|
describe "$", ->
|
|
it "selects EOF", ->
|
|
interpreter.eval(editor, '$')
|
|
expect(editor.getSelections().length).toBe 1
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[12,2], [12,2]]
|
|
|
|
interpreter.eval(editor, '1,$')
|
|
expect(editor.getSelections().length).toBe 1
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[0,0], [12,2]]
|
|
|
|
describe ".", ->
|
|
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 [[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 ->
|
|
editor.clearSelections()
|
|
|
|
it 'selects text matching regex after current selection', ->
|
|
editor.setSelectionBufferRange([[4,16], [4,20]])
|
|
interpreter.eval(editor, '/pivot/')
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[6,16], [6,21]]
|
|
|
|
it 'does not require the trailing slash', ->
|
|
editor.setSelectionBufferRange([[4,16], [4,20]])
|
|
interpreter.eval(editor, '/pivot')
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[6,16], [6,21]]
|
|
|
|
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')
|
|
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]])
|
|
interpreter.eval(editor, '/pivot')
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[3,8], [3,13]]
|
|
|
|
interpreter.eval(editor, '/mike tyson')
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[3,8], [3,13]]
|
|
|
|
describe "address range", ->
|
|
describe "when two addresses are specified", ->
|
|
it "selects from the begining of the left address to the end of the right address", ->
|
|
interpreter.eval(editor, '4,7')
|
|
expect(editor.getSelections().length).toBe 1
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[3, 0], [7, 0]]
|
|
|
|
describe "when the left address is unspecified", ->
|
|
it "selects from the begining of buffer to the end of the right address", ->
|
|
interpreter.eval(editor, ',7')
|
|
expect(editor.getSelections().length).toBe 1
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[0, 0], [7, 0]]
|
|
|
|
describe "when the right address is unspecified", ->
|
|
it "selects from the begining of left address to the end file", ->
|
|
interpreter.eval(editor, '4,')
|
|
expect(editor.getSelections().length).toBe 1
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[3, 0], [12, 2]]
|
|
|
|
describe "when the neither address is specified", ->
|
|
it "selects the entire file", ->
|
|
interpreter.eval(editor, ',')
|
|
expect(editor.getSelections().length).toBe 1
|
|
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 "when matching /$/", ->
|
|
it "matches the end of each line in the selected region", ->
|
|
interpreter.eval(editor, '6,8 x/$/')
|
|
|
|
cursors = editor.getCursors()
|
|
expect(cursors.length).toBe 3
|
|
|
|
expect(cursors[0].getBufferPosition()).toEqual [5, 30]
|
|
expect(cursors[1].getBufferPosition()).toEqual [6, 65]
|
|
expect(cursors[2].getBufferPosition()).toEqual [7, 5]
|
|
|
|
it "loops through current selections and selects text matching the regex", ->
|
|
editor.setSelectionBufferRange [[3,0], [3,62]]
|
|
editor.addSelectionForBufferRange [[6,0], [6,65]]
|
|
|
|
interpreter.eval(editor, 'x/current')
|
|
|
|
selections = editor.getSelections()
|
|
expect(selections.length).toBe 4
|
|
|
|
expect(selections[0].getBufferRange()).toEqual [[3,31], [3,38]]
|
|
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.setSelectionBufferRange([[6, 0], [6, 44]])
|
|
interpreter.eval(editor, 's/not-in-text/foo/')
|
|
expect(buffer.lineForRow(6)).toBe ' current < pivot ? left.push(current) : right.push(current);'
|
|
|
|
describe "when not global", ->
|
|
describe "when there is a single selection", ->
|
|
it "performs a single substitution within the current selection", ->
|
|
editor.setSelectionBufferRange([[6, 0], [6, 44]])
|
|
interpreter.eval(editor, 's/current/foo/')
|
|
expect(buffer.lineForRow(6)).toBe ' foo < pivot ? left.push(current) : right.push(current);'
|
|
|
|
describe "when there are multiple selections", ->
|
|
it "performs a single substitutions within each of the selections", ->
|
|
editor.setSelectionBufferRange([[5, 0], [5, 20]])
|
|
editor.addSelectionForBufferRange([[6, 0], [6, 44]])
|
|
|
|
interpreter.eval(editor, 's/current/foo/')
|
|
expect(buffer.lineForRow(5)).toBe ' foo = items.shift();'
|
|
expect(buffer.lineForRow(6)).toBe ' foo < pivot ? left.push(current) : right.push(current);'
|
|
|
|
describe "when global", ->
|
|
it "performs a multiple substitutions within the current selection", ->
|
|
editor.setSelectionBufferRange([[6, 0], [6, 44]])
|
|
interpreter.eval(editor, 's/current/foo/g')
|
|
expect(buffer.lineForRow(6)).toBe ' foo < pivot ? left.push(foo) : right.push(current);'
|
|
|
|
describe "when prefixed with an address", ->
|
|
it "only makes substitutions within given lines", ->
|
|
interpreter.eval(editor, '4,6s/ /!/g')
|
|
expect(buffer.lineForRow(2)).toBe ' if (items.length <= 1) return items;'
|
|
expect(buffer.lineForRow(3)).toBe '!!!!var!pivot!=!items.shift(),!current,!left!=![],!right!=![];'
|
|
expect(buffer.lineForRow(4)).toBe '!!!!while(items.length!>!0)!{'
|
|
expect(buffer.lineForRow(5)).toBe '!!!!!!current!=!items.shift();'
|
|
expect(buffer.lineForRow(6)).toBe ' current < pivot ? left.push(current) : right.push(current);'
|
|
|
|
describe "when matching $", ->
|
|
it "matches the end of each line and avoids infinitely looping on a zero-width match", ->
|
|
interpreter.eval(editor, ',s/$/!!!/g')
|
|
expect(buffer.lineForRow(0)).toBe 'var quicksort = function () {!!!'
|
|
expect(buffer.lineForRow(2)).toBe ' if (items.length <= 1) return items;!!!'
|
|
expect(buffer.lineForRow(6)).toBe ' current < pivot ? left.push(current) : right.push(current);!!!'
|
|
expect(buffer.lineForRow(12)).toBe '};!!!'
|
|
|
|
describe "when matching ^", ->
|
|
it "matches the beginning of each line and avoids infinitely looping on a zero-width match", ->
|
|
interpreter.eval(editor, ',s/^/!!!/g')
|
|
expect(buffer.lineForRow(0)).toBe '!!!var quicksort = function () {'
|
|
expect(buffer.lineForRow(2)).toBe '!!! if (items.length <= 1) return items;'
|
|
expect(buffer.lineForRow(6)).toBe '!!! current < pivot ? left.push(current) : right.push(current);'
|
|
expect(buffer.lineForRow(12)).toBe '!!!};'
|
|
|
|
describe "when there are multiple selections", ->
|
|
it "performs a multiple substitutions within each of the selections", ->
|
|
editor.setSelectionBufferRange([[5, 0], [5, 20]])
|
|
editor.addSelectionForBufferRange([[6, 0], [6, 44]])
|
|
|
|
interpreter.eval(editor, 's/current/foo/g')
|
|
expect(buffer.lineForRow(5)).toBe ' foo = items.shift();'
|
|
expect(buffer.lineForRow(6)).toBe ' foo < pivot ? left.push(foo) : right.push(current);'
|
|
|
|
describe ".repeatRelativeAddress()", ->
|
|
it "repeats the last search command if there is one", ->
|
|
interpreter.repeatRelativeAddress(editor) # don't raise an exception
|
|
|
|
editor.setCursorScreenPosition([4, 0])
|
|
|
|
interpreter.eval(editor, '/current')
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[5,6], [5,13]]
|
|
|
|
interpreter.repeatRelativeAddress(editor)
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[6,6], [6,13]]
|
|
|
|
interpreter.eval(editor, 's/r/R/g')
|
|
|
|
interpreter.repeatRelativeAddress(editor)
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[6,34], [6,41]]
|
|
|
|
interpreter.eval(editor, '0')
|
|
interpreter.eval(editor, '/sort/ s/r/R/') # this contains a substitution... won't be repeated
|
|
|
|
interpreter.repeatRelativeAddress(editor)
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[3,31], [3,38]]
|
|
|