mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-10 10:17:11 +03:00
Merge branch 'master' of github.com:github/atom
Conflicts: src/app/edit-session.coffee
This commit is contained in:
commit
daa688b1e1
@ -530,14 +530,22 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([9, 2])).toEqual [12, 2]
|
||||
|
||||
describe ".destroyFoldsContainingBufferRow(row)", ->
|
||||
describe "when two folds start on the given buffer row", ->
|
||||
it "destroys both folds", ->
|
||||
it "destroys all folds containing the given row", ->
|
||||
displayBuffer.createFold(2, 4)
|
||||
displayBuffer.createFold(2, 6)
|
||||
displayBuffer.createFold(7, 8)
|
||||
displayBuffer.createFold(1, 9)
|
||||
displayBuffer.createFold(11, 12)
|
||||
|
||||
expect(displayBuffer.lineForRow(1).text).toBe '1'
|
||||
expect(displayBuffer.lineForRow(2).text).toBe '10'
|
||||
|
||||
expect(displayBuffer.lineForRow(3).text).toBe '7'
|
||||
displayBuffer.destroyFoldsContainingBufferRow(2)
|
||||
expect(displayBuffer.lineForRow(3).text).toBe '3'
|
||||
expect(displayBuffer.lineForRow(1).text).toBe '1'
|
||||
expect(displayBuffer.lineForRow(2).text).toBe '2'
|
||||
expect(displayBuffer.lineForRow(7).fold).toBeDefined()
|
||||
expect(displayBuffer.lineForRow(8).text).toMatch /^9-+/
|
||||
expect(displayBuffer.lineForRow(10).fold).toBeDefined()
|
||||
|
||||
describe ".clipScreenPosition(screenPosition, wrapBeyondNewlines: false, wrapAtSoftNewlines: false, skipAtomicTokens: false)", ->
|
||||
beforeEach ->
|
||||
|
@ -856,8 +856,6 @@ describe "EditSession", ->
|
||||
editSession.setSelectedBufferRange([[3,0], [4,0]])
|
||||
editSession.backspace()
|
||||
|
||||
buffer.logLines()
|
||||
|
||||
expect(buffer.lineForRow(3)).toBe " return sort(left).concat(pivot).concat(sort(right));"
|
||||
expect(buffer.lineForRow(4)).toBe " };"
|
||||
expect(editSession.getCursorScreenPosition()).toEqual [3, 0]
|
||||
|
@ -105,6 +105,11 @@ describe "CommandInterpreter", ->
|
||||
interpreter.eval(editor, '/mike tyson')
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[3,8], [3,13]]
|
||||
|
||||
it "searches in reverse when prefixed with a -", ->
|
||||
editor.setSelectedBufferRange([[6, 16], [6, 22]])
|
||||
interpreter.eval(editor, '-/pivot')
|
||||
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", ->
|
||||
@ -229,26 +234,14 @@ describe "CommandInterpreter", ->
|
||||
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]]
|
||||
describe "when command selects folded text", ->
|
||||
it "unfolds lines that command selects", ->
|
||||
editor.createFold(1, 9)
|
||||
editor.createFold(5, 8)
|
||||
editor.setSelectedBufferRange([[0,0], [0,0]])
|
||||
|
||||
interpreter.eval(editor, '/push/')
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[6,29], [6,33]]
|
||||
expect(editor.lineForScreenRow(1).fold).toBeUndefined()
|
||||
expect(editor.lineForScreenRow(5).fold).toBeUndefined()
|
||||
expect(editor.lineForScreenRow(6).text).toBe buffer.lineForRow(6)
|
||||
|
@ -2,12 +2,13 @@ RootView = require 'root-view'
|
||||
CommandPanel = require 'command-panel'
|
||||
|
||||
describe "CommandPanel", ->
|
||||
[rootView, commandPanel] = []
|
||||
[rootView, editor, commandPanel] = []
|
||||
|
||||
beforeEach ->
|
||||
rootView = new RootView
|
||||
rootView.open()
|
||||
rootView.open(require.resolve 'fixtures/sample.js')
|
||||
rootView.enableKeymap()
|
||||
editor = rootView.activeEditor()
|
||||
commandPanel = rootView.activateExtension(CommandPanel)
|
||||
|
||||
describe "serialization", ->
|
||||
@ -46,10 +47,39 @@ describe "CommandPanel", ->
|
||||
expect(commandPanel.miniEditor.getCursorScreenPosition()).toEqual [0, 0]
|
||||
|
||||
describe "when command-panel:repeat-relative-address is triggered on the root view", ->
|
||||
it "calls .repeatRelativeAddress on the command interpreter with the active editor", ->
|
||||
spyOn(commandPanel.commandInterpreter, 'repeatRelativeAddress')
|
||||
it "repeats the last search command if there is one", ->
|
||||
rootView.trigger 'command-panel:repeat-relative-address'
|
||||
expect(commandPanel.commandInterpreter.repeatRelativeAddress).toHaveBeenCalledWith(rootView.activeEditor())
|
||||
|
||||
editor.setCursorScreenPosition([4, 0])
|
||||
|
||||
commandPanel.execute("/current")
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[5,6], [5,13]]
|
||||
|
||||
rootView.trigger 'command-panel:repeat-relative-address'
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[6,6], [6,13]]
|
||||
|
||||
commandPanel.execute('s/r/R/g')
|
||||
|
||||
rootView.trigger 'command-panel:repeat-relative-address'
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[6,34], [6,41]]
|
||||
|
||||
commandPanel.execute('0')
|
||||
commandPanel.execute('/sort/ s/r/R/') # this contains a substitution... won't be repeated
|
||||
|
||||
rootView.trigger 'command-panel:repeat-relative-address'
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[3,31], [3,38]]
|
||||
|
||||
describe "when command-pane:repeat-relative-address-in-reverse is triggered on the root view", ->
|
||||
it "it repeats the last relative address in the reverse direction", ->
|
||||
rootView.trigger 'command-panel:repeat-relative-address-in-reverse'
|
||||
|
||||
editor.setCursorScreenPosition([6, 0])
|
||||
|
||||
commandPanel.execute("/current")
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[6,6], [6,13]]
|
||||
|
||||
rootView.trigger 'command-panel:repeat-relative-address-in-reverse'
|
||||
expect(editor.getSelection().getBufferRange()).toEqual [[5,6], [5,13]]
|
||||
|
||||
describe "when command-panel:set-selection-as-regex-address is triggered on the root view", ->
|
||||
it "sets the @lastRelativeAddress to a RegexAddress of the current selection", ->
|
||||
|
@ -108,8 +108,9 @@ class DisplayBuffer
|
||||
@trigger 'change', oldRange: oldScreenRange, newRange: newScreenRange, lineNumbersChanged: true
|
||||
|
||||
destroyFoldsContainingBufferRow: (bufferRow) ->
|
||||
folds = @activeFolds[bufferRow] ? []
|
||||
fold.destroy() for fold in new Array(folds...)
|
||||
for row, folds of @activeFolds
|
||||
for fold in new Array(folds...)
|
||||
fold.destroy() if fold.getBufferRange().containsRow(bufferRow)
|
||||
|
||||
registerFold: (fold) ->
|
||||
@activeFolds[fold.startRow] ?= []
|
||||
|
@ -193,7 +193,7 @@ class EditSession
|
||||
destroyFoldsContainingBufferRow: (bufferRow) ->
|
||||
@displayBuffer.destroyFoldsContainingBufferRow(bufferRow)
|
||||
|
||||
unfoldCurrentRow: (row) ->
|
||||
unfoldCurrentRow: ->
|
||||
@displayBuffer.largestFoldStartingAtBufferRow(@getLastCursor().getCurrentBufferRow())?.destroy()
|
||||
|
||||
destroyFold: (foldId) ->
|
||||
|
@ -217,6 +217,7 @@ class Editor extends View
|
||||
softWrapColumn ?= @calcSoftWrapColumn()
|
||||
@activeEditSession.setSoftWrapColumn(softWrapColumn) if softWrapColumn
|
||||
|
||||
lineForScreenRow: (screenRow) -> @activeEditSession.lineForScreenRow(screenRow)
|
||||
linesForScreenRows: (start, end) -> @activeEditSession.linesForScreenRows(start, end)
|
||||
screenLineCount: -> @activeEditSession.screenLineCount()
|
||||
maxScreenLineLength: -> @activeEditSession.maxScreenLineLength()
|
||||
|
@ -7,5 +7,6 @@ window.keymap.bindKeys '.command-panel .editor',
|
||||
|
||||
window.keymap.bindKeys '.editor',
|
||||
'meta-g': 'command-panel:repeat-relative-address'
|
||||
'meta-G': 'command-panel:repeat-relative-address-in-reverse'
|
||||
'meta-e': 'command-panel:set-selection-as-regex-address'
|
||||
'meta-f': 'command-panel:find-in-file'
|
||||
|
@ -50,6 +50,9 @@ class Range
|
||||
point = Point.fromObject(point)
|
||||
point.isGreaterThanOrEqual(@start) and point.isLessThanOrEqual(@end)
|
||||
|
||||
containsRow: (row) ->
|
||||
@start.row <= row <= @end.row
|
||||
|
||||
union: (otherRange) ->
|
||||
start = if @start.isLessThan(otherRange.start) then @start else otherRange.start
|
||||
end = if @end.isGreaterThan(otherRange.end) then @end else otherRange.end
|
||||
|
@ -14,3 +14,5 @@ class CommandInterpreter
|
||||
repeatRelativeAddress: (editor) ->
|
||||
@lastRelativeAddress?.execute(editor)
|
||||
|
||||
repeatRelativeAddressInReverse: (editor) ->
|
||||
@lastRelativeAddress?.reverse().execute(editor)
|
||||
|
@ -9,4 +9,4 @@ class AddressRange extends Address
|
||||
new Range(@startAddress.getRange(editor, currentRange).start, @endAddress.getRange(editor, currentRange).end)
|
||||
|
||||
isRelative: ->
|
||||
@startAddress.isRelative() or @endAddress.isRelative()
|
||||
@startAddress.isRelative() and @endAddress.isRelative()
|
||||
|
@ -28,7 +28,10 @@ primitiveAddress
|
||||
= lineNumber:integer { return new LineAddress(lineNumber) }
|
||||
/ '$' { return new EofAddress() }
|
||||
/ '.' { return new CurrentSelectionAddress() }
|
||||
/ '/' pattern:pattern '/'? { return new RegexAddress(pattern)}
|
||||
/ regexAddress
|
||||
|
||||
regexAddress
|
||||
= reverse:'-'? '/' pattern:pattern '/'? { return new RegexAddress(pattern, reverse.length > 0)}
|
||||
|
||||
command = substitution / selectAllMatches
|
||||
|
||||
|
@ -10,8 +10,16 @@ class CompositeCommand
|
||||
currentRanges = editor.getSelectionsOrderedByBufferPosition().map (selection) -> selection.getBufferRange()
|
||||
for currentRange in currentRanges
|
||||
newRanges.push(command.execute(editor, currentRange)...)
|
||||
|
||||
for range in newRanges
|
||||
for row in [range.start.row..range.end.row]
|
||||
editor.destroyFoldsContainingBufferRow(row)
|
||||
|
||||
editor.setSelectedBufferRanges(newRanges)
|
||||
|
||||
reverse: ->
|
||||
new CompositeCommand(@subcommands.map (command) -> command.reverse())
|
||||
|
||||
isRelativeAddress: ->
|
||||
_.all(@subcommands, (command) -> command.isAddress() and command.isRelative())
|
||||
|
||||
|
@ -4,24 +4,33 @@ Range = require 'range'
|
||||
module.exports =
|
||||
class RegexAddress extends Address
|
||||
regex: null
|
||||
reverse: null
|
||||
|
||||
constructor: (pattern) ->
|
||||
constructor: (pattern, isReversed) ->
|
||||
@isReversed = isReversed
|
||||
@regex = new RegExp(pattern)
|
||||
|
||||
getRange: (editor, currentRange) ->
|
||||
rangeToSearch = new Range(currentRange.end, editor.getEofPosition())
|
||||
rangeBefore = new Range([0, 0], currentRange.start)
|
||||
rangeAfter = new Range(currentRange.end, editor.getEofPosition())
|
||||
|
||||
rangeToSearch = if @isReversed then rangeBefore else rangeAfter
|
||||
|
||||
rangeToReturn = null
|
||||
editor.buffer.scanInRange @regex, rangeToSearch, (match, range) ->
|
||||
scanMethodName = if @isReversed then "backwardsScanInRange" else "scanInRange"
|
||||
editor[scanMethodName] @regex, rangeToSearch, (match, range) ->
|
||||
rangeToReturn = range
|
||||
|
||||
if rangeToReturn
|
||||
rangeToReturn
|
||||
else
|
||||
rangeToSearch = new Range([0, 0], rangeToSearch.start)
|
||||
editor.buffer.scanInRange @regex, rangeToSearch, (match, range) ->
|
||||
rangeToSearch = if @isReversed then rangeAfter else rangeBefore
|
||||
editor[scanMethodName] @regex, rangeToSearch, (match, range) ->
|
||||
rangeToReturn = range
|
||||
|
||||
rangeToReturn or currentRange
|
||||
|
||||
isRelative: -> true
|
||||
|
||||
reverse: ->
|
||||
new RegexAddress(@regex, !@isReversed)
|
@ -42,6 +42,7 @@ class CommandPanel extends View
|
||||
@rootView.on 'command-panel:execute', => @execute()
|
||||
@rootView.on 'command-panel:find-in-file', => @show("/")
|
||||
@rootView.on 'command-panel:repeat-relative-address', => @repeatRelativeAddress()
|
||||
@rootView.on 'command-panel:repeat-relative-address-in-reverse', => @repeatRelativeAddressInReverse()
|
||||
@rootView.on 'command-panel:set-selection-as-regex-address', => @setSelectionAsLastRelativeAddress()
|
||||
|
||||
@miniEditor.off 'move-up move-down'
|
||||
@ -88,6 +89,9 @@ class CommandPanel extends View
|
||||
repeatRelativeAddress: ->
|
||||
@commandInterpreter.repeatRelativeAddress(@rootView.activeEditor())
|
||||
|
||||
repeatRelativeAddressInReverse: ->
|
||||
@commandInterpreter.repeatRelativeAddressInReverse(@rootView.activeEditor())
|
||||
|
||||
setSelectionAsLastRelativeAddress: ->
|
||||
selection = @rootView.activeEditor().getSelectedText()
|
||||
regex = _.escapeRegExp(selection)
|
||||
|
Loading…
Reference in New Issue
Block a user