8000 jump motions (ctrl-o / ctrl-i) by garcg · Pull Request #397 · atom/vim-mode · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
This repository was archived by the owner on Apr 6, 2018. It is now read-only.

jump motions (ctrl-o / ctrl-i) #397

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/motions.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@
* [T](http://vimhelp.appspot.com/motion.txt.html#T)
* [;](http://vimhelp.appspot.com/motion.txt.html#%3B)
* [,](http://vimhelp.appspot.com/motion.txt.html#%2C)
* [ctrl-o](http://vimhelp.appspot.com/motion.txt.html#CTRL-O)
* [ctrl-i](http://vimhelp.appspot.com/motion.txt.html#CTRL-I)
3 changes: 3 additions & 0 deletions keymaps/vim-mode.cson
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@
'g t': 'pane:show-next-item'
'g T': 'pane:show-previous-item'

'ctrl-o': 'vim-mode:jump-older-pos'
'ctrl-i': 'vim-mode:jump-newer-pos'

'm': 'vim-mode:mark'
'`': 'vim-mode:move-to-mark-literal'
'\'': 'vim-mode:move-to-mark'
Expand Down
59 changes: 59 additions & 0 deletions lib/jumplist.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

module.exports =
class JumpList
constructor: (@maxEntries = 100) ->
@list = []
@pointer = -1
@pending = false

addJump: (editor) ->
@list.splice(@pointer, 1) unless @pointer == -1
entry = new JumpListEntry(editor)
@list.unshift entry unless entry.isEqual(@list[0])
@list.splice(0, @maxEntries) if @list.length > @maxEntries
@pointer = -1

moveToOlderPos: (editor, count=1) ->
return if @pending
if @pointer == -1
@addJump editor
@pointer = 0
@_moveToPos editor, count

moveToNewerPos: (editor, count=1) ->
return if @pending
@_moveToPos editor, -count

_moveToPos: (editor, inc) ->
dst = @pointer+inc
if dst < 0
dst = 0
if dst >= @list.length
dst = @list.length-1
if dst != @pointer
@pending = true
@list[dst].restoreCursor editor, (err, dstEditor) =>
@pointer = dst
@pending = false


class JumpListEntry
constructor: (editor) ->
{@row, @column} = editor.getCursorBufferPosition()
@uri = editor.getUri()

isEqual: (o) ->
o &&
o.row == @row &&
o.column == @column &&
o.uri == @uri

restoreCursor: (editor, cb) ->
if editor.getUri() == @uri
editor.setCursorBufferPosition [@row, @column]
cb?(null, editor)
else
atom.workspace.open(@uri, {
initialLine: @row,
initialColumn: @column
}).nodeify cb
16 changes: 15 additions & 1 deletion lib/motions/general-motions.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ class MoveToEndOfWholeWord extends Motion

class MoveToNextParagraph extends Motion
execute: (count=1) ->
atom.workspace.vimState.jumpList.addJump @editor
_.times count, =>
@editor.setCursorScreenPosition(@nextPosition())

Expand Down Expand Up @@ -369,6 +370,7 @@ class MoveToNextParagraph extends Motion

class MoveToPreviousParagraph extends Motion
execute: (count=1) ->
atom.workspace.vimState.jumpList.addJump @editor
_.times count, =>
@editor.setCursorScreenPosition(@previousPosition())

Expand Down Expand Up @@ -428,6 +430,7 @@ class MoveToLine extends Motion
new Range(startPoint, endPoint)

setCursorPosition: (count) ->
atom.workspace.vimState.jumpList.addJump @editor
@editor.setCursorBufferPosition([@getDestinationRow(count), 0])

getDestinationRow: (count) ->
Expand All @@ -439,6 +442,7 @@ class MoveToScreenLine extends MoveToLine
super(@editor, @vimState)

setCursorPosition: (count) ->
atom.workspace.vimState.jumpList.addJump @editor
@editor.setCursorScreenPosition([@getDestinationRow(count), 0])

class MoveToBeginningOfLine extends Motion
Expand Down Expand Up @@ -544,11 +548,21 @@ class MoveToMiddleOfScreen extends MoveToScreenLine
height = lastScreenRow - firstScreenRow
Math.floor(firstScreenRow + (height / 2))

class MoveToOlderJumpPos extends Motion
execute: (count=1) ->
atom.workspace.vimState.jumpList.moveToOlderPos @editor, count

class MoveToNewerJumpPos extends Motion
execute: (count=1) ->
atom.workspace.vimState.jumpList.moveToNewerPos @editor, count


module.exports = {
Motion, MotionWithInput, CurrentSelection, MoveLeft, MoveRight, MoveUp, MoveDown,
MoveToPreviousWord, MoveToPreviousWholeWord, MoveToNextWord, MoveToNextWholeWord,
MoveToEndOfWord, MoveToNextParagraph, MoveToPreviousParagraph, MoveToLine, MoveToBeginningOfLine,
MoveToFirstCharacterOfLineUp, MoveToFirstCharacterOfLineDown,
MoveToFirstCharacterOfLine, MoveToLastCharacterOfLine, MoveToStartOfFile, MoveToTopOfScreen,
MoveToBottomOfScreen, MoveToMiddleOfScreen, MoveToEndOfWholeWord, MotionError
MoveToBottomOfScreen, MoveToMiddleOfScreen, MoveToEndOfWholeWord, MotionError,
MoveToOlderJumpPos, MoveToNewerJumpPos
}
1 change: 1 addition & 0 deletions lib/motions/search-motion.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class SearchBase extends MotionWithInput
execute: (count=1) ->
@scan()
@match count, (pos) =>
atom.workspace.vimState.jumpList.addJump @editor
@editor.setCursorBufferPosition(pos.range.start)

select: (count=1) ->
Expand Down
2 changes: 2 additions & 0 deletions lib/vim-mode.coffee
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
VimState = require './vim-state'
JumpList = require './jumplist'

module.exports =
configDefaults:
Expand All @@ -9,6 +10,7 @@ module.exports =
atom.workspace.vimState ||= {}
atom.workspace.vimState.registers ||= {}
atom.workspace.vimState.searchHistory ||= []
atom.workspace.vimState.jumpList ||= new JumpList()

activate: (state) ->
@_initializeWorkspaceState()
Expand Down
2 changes: 2 additions & 0 deletions lib/vim-state.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ class VimState
'focus-pane-view-above': => new Panes.FocusPaneViewAbove()
'focus-pane-view-below': => new Panes.FocusPaneViewBelow()
'focus-previous-pane-view': => new Panes.FocusPreviousPaneView()
'jump-older-pos': (e) => new Motions.MoveToOlderJumpPos(@editor, @)
'jump-newer-pos': (e) => new Motions.MoveToNewerJumpPos(@editor, @)
'move-to-mark': (e) => new Motions.MoveToMark(@editorView, @)
'move-to-mark-literal': (e) => new Motions.MoveToMark(@editorView, @, false)
'mark': (e) => new Operators.Mark(@editorView, @)
Expand Down
144 changes: 144 additions & 0 deletions spec/motions-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -1551,3 +1551,147 @@ describe "Motions", ->
keydown('%')
expect(editor.getCursorScreenPosition()).toEqual [0, 60]
expect(editor.getText()).toEqual "( ( ) )--{ text in here; and a function call(with parameters) }\n"


describe 'jumplist behaviour', ->

keydownSeq = (seq) -> keydown(k) for k in seq

describe 'empty jumplist', ->

beforeEach ->
editor.setText( ('01234567890' for i in [1..10]).join('\n') )
editor.setCursorScreenPosition([5, 5])

it 'does nothing, ctrl-o', ->
keydown('o', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual [5, 5]

it 'does nothing, ctrl-i', ->
keydown('i', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual [5, 5]

describe 'ctrl-o / ctrl-i', ->

beforeEach ->
editor.setText( ('01234567890' for i in [1..10]).join('\n') )
editor.setCursorScreenPosition([5, 5])
# add some jumps to jumplist (it doesn't matter how)
keydownSeq('7gg')
keydownSeq('gg')
expect(editor.getCursorScreenPosition()).toEqual [0, 0]

it 'jumps to older positions', ->
keydown('o', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual [6, 0]
keydown('o', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual [5, 5]
keydown('o', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual [5, 5]

it 'jumps to newer positions', ->
keydown('o', ctrl:true)
keydown('o', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual [5, 5]
keydown('i', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual [6, 0]
keydown('i', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
keydown('i', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual [0, 0]

it 'jumps to older positions by count', ->
keydown('2')
keydown('o', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual [5, 5]

it 'jumps to older positions by count (count bigger than list)', ->
keydown('999')
keydown('o', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual [5, 5]

it 'jumps to newer positions by count', ->
keydown('o', ctrl:true)
keydown('o', ctrl:true)
keydown('2')
keydown('i', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual [0, 0]

it 'jumps to newer positions by count (count bigger than list)', ->
keydown('o', ctrl:true)
keydown('o', ctrl:true)
keydown('999')
keydown('i', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual [0, 0]


describe 'an entry is created in the jumplist', ->

beforeEach ->
editor.setText( ('01234567890' for i in [1..10]).join('\n') )
editor.setCursorScreenPosition([5, 5])

expectJumpAdded = (positionBeforeJump = [5, 5]) ->
expect(editor.getCursorScreenPosition()).not.toEqual positionBeforeJump
keydown('o', ctrl:true)
expect(editor.getCursorScreenPosition()).toEqual positionBeforeJump

it 'before moving to a line', ->
keydownSeq('2gg')
expectJumpAdded()

it 'before moving to the top of the buffer', ->
keydownSeq('gg')
expectJumpAdded()

it 'before moving to the bottom of the buffer', ->
keydown('G', {shift:true})
expectJumpAdded()

it 'before moving to the bottom of the screen', ->
keydown('L', {shift:true})
expectJumpAdded()

it 'before moving to the top of the screen', ->
keydown('L', {shift:true})
expectJumpAdded()

it 'before moving to the middle of the screen', ->
keydown('M', {shift:true})
expectJumpAdded()

it 'before doing a text search', ->
keydown('/')
editor.commandModeInputView.editor.setText '0123'
editor.commandModeInputView.editor.trigger 'core:confirm'
expectJumpAdded()

it 'before doing a reverse text search', ->
keydown('?')
editor.commandModeInputView.editor.setText '0123'
editor.commandModeInputView.editor.trigger 'core:confirm'
expectJumpAdded()

it 'before moving to the next paragraph', ->
keydown('}')
expectJumpAdded()

it 'before moving to the prevous paragraph', ->
keydown('{')
expectJumpAdded()

it 'before moving to the matching bracket', ->
editor.setText('a(c)b')
editor.setCursorScreenPosition([0, 3])
keydown('%')
expectJumpAdded([0, 3])


describe 'jumplist between buffers', ->

beforeEach ->

it 'jumps back to position in other buffer', -> throw 'TODO test'
it 'jumps forward to position in other buffer', -> throw 'TODO test'
it 'adds jump to jumplist when switching or opening buffers', -> throw 'TODO test and implementation'
it 'jumps between new unsaved buffers (no editor uri)', -> throw 'TODO test and implementation'
0