Skip to content

Commit

Permalink
Version 1.20
Browse files Browse the repository at this point in the history
- ENH: In CountJump#Motion#MakeBracketMotion(), a:keyAfterBracket and a:inverseKeyAfterBracket can now be empty, the resulting mappings are then omitted. Likewise, any jump function can be empty in CountJump#Motion#MakeBracketMotionWithJumpFunctions().
- With the added CountJump#Motion#MakeBracketMotionWithJumpFunctions() motions can be defined via jump functions, similar to how text objects can be defined.
- Added CountJump/Region.vim to move to borders of a region defined by lines matching a pattern.
- FIX: CountJump#CountJump() with mode "O" didn't add original position to jump list.
- The previous visual selection is kept when the text object could not be selected. (Beforehand, a new selection of the text object's selection type was created.)
- The adjustment movements after the jumps to the text object boundaries now do not cause beeps if that movement cannot be done (e.g. a 'j' at the end of the buffer).
  • Loading branch information
Ingo Karkat authored and vim-scripts committed Oct 18, 2010
1 parent 2f38149 commit fa898eb
Show file tree
Hide file tree
Showing 5 changed files with 592 additions and 48 deletions.
29 changes: 14 additions & 15 deletions autoload/CountJump.vim
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
" Maintainer: Ingo Karkat <ingo@karkat.de>
"
" REVISION DATE REMARKS
" 1.20.009 30-Jul-2010 FIX: CountJump#CountJump() with mode "O" didn't
" add original position to jump list. Simplified
" conditional.
" 1.10.008 15-Jul-2010 Changed behavior if there aren't [count]
" matches: Instead of jumping to the last
" available match (and ringing the bell), the
Expand Down Expand Up @@ -125,11 +128,16 @@ function! CountJump#CountJump( mode, ... )
normal! gv
endif

if a:mode ==# 'O'
" Special additional treatment for operator-pending mode with a pattern
" to end.
let l:matchPos = CountJump#CountSearch(v:count1, a:000)
if l:matchPos != [0, 0]
let l:matchPos = CountJump#CountSearch(v:count1, a:000)
if l:matchPos != [0, 0]
" Add the original cursor position to the jump list.
call winrestview(l:save_view)
normal! m'
call setpos('.', [0] + l:matchPos + [0])

if a:mode ==# 'O'
" Special additional treatment for operator-pending mode with a pattern
" to end.
" The difference between normal mode, visual and operator-pending
" mode is that in the latter, the motion must go _past_ the final
" character, so that all characters are selected. This is done by
Expand All @@ -148,18 +156,9 @@ function! CountJump#CountJump( mode, ... )
normal! l
let &whichwrap = l:save_ww
endif
return l:matchPos
endif

let l:matchPosition = CountJump#CountSearch(v:count1, a:000)
if l:matchPosition != [0, 0]
" Add the original cursor position to the jump list.
call winrestview(l:save_view)
normal! m'
call setpos('.', [0] + l:matchPosition + [0])
endif

return l:matchPosition
return l:matchPos
endfunction

" vim: set sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
142 changes: 135 additions & 7 deletions autoload/CountJump/Motion.vim
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@
" Maintainer: Ingo Karkat <ingo@karkat.de>
"
" REVISION DATE REMARKS
" 1.20.004 30-Jul-2010 ENH: a:keyAfterBracket and
" a:inverseKeyAfterBracket can now be empty, the
" resulting mappings are then omitted.
" Likewise, any jump function can be empty in
" CountJump#Motion#MakeBracketMotionWithJumpFunctions().
" 1.20.003 21-Jul-2010 With the added
" CountJump#Motion#MakeBracketMotionWithJumpFunctions()
" motions can be defined via jump functions,
" similar to how text objects can be defined. This
" is a generalization of
" CountJump#Motion#MakeBracketMotion(), but the
" latter isn't now implemented through the
" generalization to avoid overhead and because the
" similarities are not as strong as with the text
" objects.
" 1.00.002 22-Jun-2010 Added missing :omaps for operator-pending mode.
" Replaced s:Escape() with string() and simplified
" building of l:dataset.
Expand Down Expand Up @@ -61,9 +76,12 @@ function! CountJump#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, inverseK
" a:keyAfterBracket Mapping key [sequence] after the mandatory ]/[ which
" start the mapping for a motion to the beginning of a
" block.
" Can be empty; the resulting mappings are then omitted.
" a:inverseKeyAfterBracket Likewise, but for the motions to the end of a
" block. Usually the uppercased version of
" a:keyAfterBracket.
" Can be empty; the resulting mappings are then
" omitted.
" If both a:keyAfterBracket and a:inverseKeyAfterBracket are empty, the
" default [[ and ]] mappings are overwritten. (Note that this is different
" from passing ']' and '[', respectively, because the back motions are
Expand Down Expand Up @@ -102,12 +120,15 @@ function! CountJump#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, inverseK
\ [ '][', a:patternToEnd, 'W' . l:endMatch ],
\]
else
let l:dataset = [
\ [ '[' . a:keyAfterBracket, a:patternToBegin, 'bW' ],
\ [ ']' . a:keyAfterBracket, a:patternToBegin, 'W' ],
\ [ '[' . a:inverseKeyAfterBracket, a:patternToEnd, 'bW' . l:endMatch ],
\ [ ']' . a:inverseKeyAfterBracket, a:patternToEnd, 'W' . l:endMatch ],
\]
let l:dataset = []
if ! empty(a:keyAfterBracket)
call add(l:dataset, [ '[' . a:keyAfterBracket, a:patternToBegin, 'bW' ])
call add(l:dataset, [ ']' . a:keyAfterBracket, a:patternToBegin, 'W' ])
endif
if ! empty(a:inverseKeyAfterBracket)
call add(l:dataset, [ '[' . a:inverseKeyAfterBracket, a:patternToEnd, 'bW' . l:endMatch ])
call add(l:dataset, [ ']' . a:inverseKeyAfterBracket, a:patternToEnd, 'W' . l:endMatch ])
endif
endif
for l:mode in l:mapModes
for l:data in l:dataset
Expand All @@ -122,7 +143,114 @@ function! CountJump#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, inverseK
endfor
endfunction

function! s:AddTupleIfValue( list, key, value )
if ! empty(a:value)
call add(a:list, [a:key, a:value])
endif
endfunction
function! CountJump#Motion#MakeBracketMotionWithJumpFunctions( mapArgs, keyAfterBracket, inverseKeyAfterBracket, JumpToBeginForward, JumpToBeginBackward, JumpToEndForward, JumpToEndBackward, isEndJumpToEnd, ... )
"*******************************************************************************
"* PURPOSE:
" Define a complete set of mappings for a [x / ]x motion (e.g. like the
" built-in ]m "Jump to start of next method") that support an optional [count]
" and are driven by two functions that jump to the beginning and end of a block.
" The mappings work in normal mode (jump), visual mode (expand selection) and
" operator-pending mode (execute operator).
"
"* ASSUMPTIONS / PRECONDITIONS:
" None.
"
"* EFFECTS / POSTCONDITIONS:
" Creates mappings for normal, visual and operator-pending mode:
" Normal mode: Jumps to the <count>th occurrence.
" Visual mode: Extends the selection to the <count>th occurrence.
" Operator-pending mode: Applies the operator to the covered text.
" If the pattern doesn't match (<count> times), a beep is emitted.
"
"* INPUTS:
" a:mapArgs Arguments to the :map command, like '<buffer>' for a
" buffer-local mapping.
" a:keyAfterBracket Mapping key [sequence] after the mandatory ]/[ which
" start the mapping for a motion to the beginning of a
" block.
" Can be empty; the resulting mappings are then omitted.
" a:inverseKeyAfterBracket Likewise, but for the motions to the end of a
" block. Usually the uppercased version of
" a:keyAfterBracket.
" Can be empty; the resulting mappings are then
" omitted.
" If both a:keyAfterBracket and a:inverseKeyAfterBracket are empty, the
" default [[ and ]] mappings are overwritten. (Note that this is different
" from passing ']' and '[', respectively, because the back motions are
" swapped.)
" a:JumpToBeginForward Function which is invoked to jump to the begin of the
" block in forward direction.
" a:JumpToBeginBackward Function which is invoked to jump to the begin of the
" block in backward direction.
" a:JumpToEndForward Function which is invoked to jump to the end of the
" block in forward direction.
" a:JumpToEndBackward Function which is invoked to jump to the end of the
" block in backward direction.
" The jump functions must take one argument:
" JumpTo...( mode )
" a:mode Mode in which the search is invoked. Either 'n', 'v' or 'o'.
" With 'O': Special additional treatment for operator-pending mode
" with a pattern to end.
" Both funcrefs must return a list [lnum, col], like searchpos(). This should
" be the jump position (or [0, 0] if a jump wasn't possible).
" They should position the cursor to the appropriate position in the current
" window.
" If no jump function is passed, the corresponding mappings are omitted.

" a:isEndJumpToEnd Flag that specifies whether a jump to the end of a block
" will be to the last character of the block delimiter
" (vs. to the first character of the block delimiter or
" completely after the block delimiter).
" a:mapModes Optional string containing 'n', 'o' and/or 'v',
" representing the modes for which mappings should be
" created. Defaults to all modes.
"
"* NOTES:
" - If your motion is linewise, the jump functions should jump to the first
" column. This results in the expected behavior in normal mode, and in
" characterwise visual mode selects up to that line, and in (more likely)
" linewise visual mode includes the complete end line.
"
"* RETURN VALUES:
" None.
"*******************************************************************************
let l:mapModes = split((a:0 ? a:1 : 'nov'), '\zs')

let l:dataset = []
if empty(a:keyAfterBracket) && empty(a:inverseKeyAfterBracket)
call s:AddTupleIfValue(l:dataset, '[[', a:JumpToBeginBackward)
call s:AddTupleIfValue(l:dataset, ']]', a:JumpToBeginForward)
call s:AddTupleIfValue(l:dataset, '[]', a:JumpToEndBackward)
call s:AddTupleIfValue(l:dataset, '][', a:JumpToEndForward)
else
if ! empty(a:keyAfterBracket)
call s:AddTupleIfValue(l:dataset, '[' . a:keyAfterBracket, a:JumpToBeginBackward)
call s:AddTupleIfValue(l:dataset, ']' . a:keyAfterBracket, a:JumpToBeginForward)
endif
if ! empty(a:inverseKeyAfterBracket)
call s:AddTupleIfValue(l:dataset, '[' . a:inverseKeyAfterBracket, a:JumpToEndBackward)
call s:AddTupleIfValue(l:dataset, ']' . a:inverseKeyAfterBracket, a:JumpToEndForward)
endif
endif

for l:mode in l:mapModes
for l:data in l:dataset
execute escape(
\ printf("%snoremap <silent> %s %s :<C-U>call %s(%s)<CR>",
\ l:mode, a:mapArgs, l:data[0],
\ string(l:data[1]),
\ string((l:mode ==# 'o' && a:isEndJumpToEnd) ? 'O' : l:mode)
\ ), '|'
\)
endfor
endfor
endfunction

let &cpo = s:save_cpo
unlet s:save_cpo

" vim: set sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
Loading

0 comments on commit fa898eb

Please sign in to comment.