Skip to content

Commit

Permalink
Version 1.30
Browse files Browse the repository at this point in the history
- ENH: Added CountJump#Region#Motion#MakeBracketMotion() to easily define bracket motions for regions.
- Interface changes:
  - Jump functions don't necessarily return jump position any more; this special case is only required for text objects.
  - Moved CountJump#Region#Jump() to CountJump#JumpFunc().
  - Added a:isToEndOfLine argument to CountJump#Region#JumpToRegionEnd() and CountJump#Region#JumpToNextRegion(), which is useful for operator-pending and characterwise visual mode mappings; the entire last line will then be operated on / selected.
  - Added a:isMatch argument to CountJump#Region#SearchForRegionEnd(), CountJump#Region#JumpToRegionEnd(), CountJump#Region#SearchForNextRegion(), CountJump#Region#JumpToNextRegion(). This allows definition of regions via non-matches, which can be substantially simpler (and faster to match) than coming up with a "negative" regular expression.
  • Loading branch information
Ingo Karkat authored and vim-scripts committed Dec 20, 2010
1 parent cbc2370 commit 0a0ac1c
Show file tree
Hide file tree
Showing 6 changed files with 341 additions and 149 deletions.
25 changes: 15 additions & 10 deletions README
Expand Up @@ -77,26 +77,31 @@ Often, a region can be defined as a block of continuous lines that all match a
certain pattern. The following functions aid in implementing movements to the
boundaries of these regions and text objects consisting of the region:

CountJump#Region#JumpToRegionEnd( count, pattern, step )
CountJump#Region#JumpToRegionEnd( count, pattern, isMatch, step, isToEndOfLine )

Starting from the current line, search for the position where the count'th
region ends. Use this function to build Funcrefs for forward / backward jumps
that can then be passed to CountJump#TextObject#MakeWithJumpFunctions().

CountJump#Region#JumpToNextRegion( count, pattern, step, isAcrossRegion )
CountJump#Region#JumpToNextRegion( count, pattern, isMatch, step, isAcrossRegion, isToEndOfLine )

Starting from the current line, search for the position where the count'th
region begins/ends.

CountJump#Region#Jump( mode, JumpFunc, ... )
CountJump#Region#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, inverseKeyAfterBracket, pattern, isMatch, ... )

Implement a custom motion by jumping to the <count>th occurrence of the passed
pattern. This function allows to implement jump functions working on text
regions. These can then be passed to
CountJump#Motion#MakeBracketMotionWithJumpFunctions().
function! s:JumpToBeginForward( mode )
return CountJump#Region#Jump(a:mode, function('CountJump#Region#JumpToNextRegion'), '^\s*#', 1, 0)
endfunction
This function sets up mappings starting with [ and ] for movement (with
optional [count]) relative to the current cursor position, targeting a text
region defined by contiguous lines that (don't) match a:pattern.

CountJump#Region#TextObject#Make( mapArgs, textObjectKey, types, selectionMode, pattern, isMatch )

Defines a complete set of mappings for inner and/or outer text objects that
support an optional [count] and select regions of lines which are defined by
contiguous lines that (don't) match a:pattern.
The inner text object comprises all lines of the region itself, while the
outer text object also includes all adjacent lines above and below which do
not themselves belong to a region.

EXAMPLE
Let's illustrate the usage by developing custom motions and text objects for
Expand Down
101 changes: 92 additions & 9 deletions autoload/CountJump.vim
Expand Up @@ -8,6 +8,22 @@
" Maintainer: Ingo Karkat <ingo@karkat.de>
"
" REVISION DATE REMARKS
" 1.30.011 19-Dec-2010 Removed return value of jump position from
" CountJump#CountJump() and CountJump#JumpFunc();
" it isn't needed, as these functions are
" typically used directly in motion mappings.
" CountJump#JumpFunc() now uses cursor position
" after invoking jump function, and doesn't
" require a returned position any more. This is
" only a special case for CountJump#TextObject,
" and should not be generally required of a jump
" function. The jump function is now also expected
" to beep, so removed that here.
" 1.30.010 18-Dec-2010 Moved CountJump#Region#Jump() here as
" CountJump#JumpFunc(). It fits here much better
" because of the similarity to
" CountJump#CountJump(), and actually has nothing
" to do with regions.
" 1.20.009 30-Jul-2010 FIX: CountJump#CountJump() with mode "O" didn't
" add original position to jump list. Simplified
" conditional.
Expand Down Expand Up @@ -62,8 +78,8 @@ function! CountJump#CountSearch( count, searchArguments )
let l:searchArguments = copy(a:searchArguments)

for l:i in range(1, a:count)
let l:matchPos = call('searchpos', l:searchArguments)
if l:matchPos == [0, 0]
let l:matchPosition = call('searchpos', l:searchArguments)
if l:matchPosition == [0, 0]
if l:i > 1
" (Due to the count,) we've already moved to an intermediate
" match. Undo that to behave like the old vi-compatible
Expand All @@ -80,7 +96,7 @@ function! CountJump#CountSearch( count, searchArguments )
" \<Esc>", which only works in normal mode.
execute "normal \<Plug>RingTheBell"

return l:matchPos
return l:matchPosition
endif

if len(l:searchArguments) > 1 && l:i == 1
Expand All @@ -97,7 +113,7 @@ function! CountJump#CountSearch( count, searchArguments )
" a match inside a closed fold.
normal! zv

return l:matchPos
return l:matchPosition
endfunction
function! CountJump#CountJump( mode, ... )
"*******************************************************************************
Expand All @@ -120,20 +136,20 @@ function! CountJump#CountJump( mode, ... )
" ... Arguments to search().
"
"* RETURN VALUES:
" List with the line and column position, or [0, 0], like searchpos().
" None.
"*******************************************************************************
let l:save_view = winsaveview()

if a:mode ==# 'v'
normal! gv
endif

let l:matchPos = CountJump#CountSearch(v:count1, a:000)
if l:matchPos != [0, 0]
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:matchPos + [0])
call setpos('.', [0] + l:matchPosition + [0])

if a:mode ==# 'O'
" Special additional treatment for operator-pending mode with a pattern
Expand All @@ -157,8 +173,75 @@ function! CountJump#CountJump( mode, ... )
let &whichwrap = l:save_ww
endif
endif
endfunction
function! CountJump#JumpFunc( mode, JumpFunc, ... )
"*******************************************************************************
"* PURPOSE:
" Implement a custom motion by invoking a jump function that is passed the
" <count> and the optional arguments.
"
"* ASSUMPTIONS / PRECONDITIONS:
" None.
"
"* EFFECTS / POSTCONDITIONS:
" Normal mode: Jumps to the <count>th occurrence.
" Visual mode: Extends the selection to the <count>th occurrence.
" If the jump doesn't work, a beep is emitted.
"
"* INPUTS:
" 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 characterwise jump.
" a:JumpFunc Function which is invoked to jump.
" The jump function must take at least one argument:
" a:count Number of matches to jump to.
" It can take more arguments which must then be passed in here:
" ... Arguments to the passed a:JumpFunc
" The jump function should position the cursor to the appropriate position in
" the current window, and open any folds there. It is expected to beep and
" keep the cursor at its original position when no appropriate position can be
" found.
"
"* RETURN VALUES:
" None.
"*******************************************************************************
let l:save_view = winsaveview()
let l:originalPosition = getpos('.')

if a:mode ==# 'v'
normal! gv
endif

return l:matchPos
call call(a:JumpFunc, [v:count1] + a:000)
let l:matchPosition = getpos('.')
if l:matchPosition != l:originalPosition
" Add the original cursor position to the jump list.
call winrestview(l:save_view)
normal! m'
call setpos('.', l:matchPosition)

if a:mode ==# 'O'
" Special additional treatment for operator-pending mode with a
" characterwise jump.
" 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
" appending a 'l' motion after the search.
"
" In operator-pending mode, the 'l' motion only works properly
" at the end of the line (i.e. when the moved-over "word" is at
" the end of the line) when the 'l' motion is allowed to move
" over to the next line. Thus, the 'l' motion is added
" temporarily to the global 'whichwrap' setting.
" Without this, the motion would leave out the last character in
" the line. I've also experimented with temporarily setting
" "set virtualedit=onemore", but that didn't work.
let l:save_ww = &whichwrap
set whichwrap+=l
normal! l
let &whichwrap = l:save_ww
endif
endif
endfunction

" vim: set sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
8 changes: 4 additions & 4 deletions autoload/CountJump/Motion.vim
Expand Up @@ -9,6 +9,8 @@
" Maintainer: Ingo Karkat <ingo@karkat.de>
"
" REVISION DATE REMARKS
" 1.30.006 19-Dec-2010 Clarified interface of jump function arguments;
" no need to return jump position here.
" 1.22.005 06-Aug-2010 No more motion mappings for select mode; as the
" mappings start with a printable character, no
" select-mode mapping should be defined.
Expand Down Expand Up @@ -202,10 +204,8 @@ function! CountJump#Motion#MakeBracketMotionWithJumpFunctions( mapArgs, keyAfter
" 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.
" All funcrefs 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
Expand Down

0 comments on commit 0a0ac1c

Please sign in to comment.