Permalink
Browse files

Version 1.30

- 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...
1 parent cbc2370 commit 0a0ac1c80f04683f33a3837d02fa19293c59fbda Ingo Karkat committed with Dec 20, 2010
Showing with 341 additions and 149 deletions.
  1. +15 −10 README
  2. +92 −9 autoload/CountJump.vim
  3. +4 −4 autoload/CountJump/Motion.vim
  4. +72 −108 autoload/CountJump/Region.vim
  5. +125 −0 autoload/CountJump/Region/Motion.vim
  6. +33 −18 doc/CountJump.txt
View
25 README
@@ -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
View
@@ -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.
@@ -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
@@ -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
@@ -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, ... )
"*******************************************************************************
@@ -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
@@ -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 :
@@ -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.
@@ -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
Oops, something went wrong.

0 comments on commit 0a0ac1c

Please sign in to comment.