Permalink
Browse files

Version 1.60

- ENH: Allow motions that do not start with [ / ] and text objects that do not start with i / a by passing keys that begin with <Plug>. With this, plugins using CountJump can offer the expected customizability.
  • Loading branch information...
1 parent 7547c57 commit 660d37b789bb0f5fb4407ee557221f448a8fd5f9 Ingo Karkat committed with Mar 27, 2012
View
83 README
@@ -4,64 +4,73 @@ DESCRIPTION
Though it is not difficult to write a custom movement (basically a :map
that executes some kind of search or jump) and a custom text-object (an
:omap that selects a range of text), this is too complex for a novice user
-and often repetitive.
+and often repetitive.
This plugin covers the common use case where the movement and boundaries of a
text object can be specified via start and end patterns, and offers a single
function to set up related mappings. With it, you can enhance some built-in
Vim mappings to take an optional [count], and quickly define new mappings for
-help file sections, diff hunks, embedded macros, and so on...
+help file sections, diff hunks, embedded macros, and so on...
As a generalization of the start and end patterns, the movement and boundaries
of a text object can also be specified via jump functions, i.e. Funcrefs of
functions that position the cursor on the appropriate location and return that
location. This can be used where the jump is difficult to express with a
single regular expression, the jump may need adapting depending on the
-context, or other uses.
+context, or other uses.
This plugin contains some support for movement and text objects consisting of
text regions that can be defined by continuous lines that match a particular
-pattern, e.g. comment blocks that all start with /^\s*#/.
+pattern, e.g. comment blocks that all start with /^\s*#/.
SEE ALSO
-The following ftplugins use this plugin:
+The following ftplugins use this plugin:
-diff_movement (vimscript #3180): Movement over diff hunks with ]] etc.
+diff_movement (vimscript #3180): Movement over diff hunks with ]] etc.
fortunes_movement (vimscript #3181): Movement over email fortunes with ]] etc.
help_movement (vimscript #3179): Movement over Vim help sections with ]] etc.
mail_movement (vimscript #3182): Movement over email quotes with ]] etc.
+JumpToTrailingWhitespace (vimscript #3968): Motions to locate unwanted
+ whitespace at the end of lines.
+TaskMotion (vimscript #3990): Motions to task and TODO markers.
+ConflictMotion (vimscript #3991): Motions to and inside SCM conflict markers.
+vim_movement (vimscript #4002): Movement over Vim functions with ]m etc.
+vbs_movement (vimscript #4003): Movement over VBScript classes /
+ functions / properties / subs with ]m etc.
+dosbatch_movement (vimscript #4004): Movement over MSDOS batch file functions
+ / labels with ]m etc.
RELATED WORKS
- motpat.vim (vimscript #3030) offers similar functions to setup motion
- mappings, but no text objects (yet).
+ mappings, but no text objects (yet).
- textobj-user (vimscript #2100) has support for user-defined text objects via
- regular expressions.
+ regular expressions.
USAGE
The plugin defines several functions, which set up the appropriate mappings
based on the arguments that you supply. The following is an overview; you'll
find the details directly in the implementation files in the
-.vim/autoload/CountJump/ directory.
+.vim/autoload/CountJump/ directory.
CountJump#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, inverseKeyAfterBracket, patternToBegin, patternToEnd, isEndPatternToEnd, ... )
This function sets up mappings starting with [ and ] for movement (with
optional [count]) relative to the current cursor position, targeting either a
text pattern at the beginning ([{keyAfterBracket} mapping) or a text pattern
at the end (]{inverseKeyAfterBracket} mapping) of whatever you want to treat
-as a text block.
+as a text block.
CountJump#Motion#MakeBracketMotionWithJumpFunctions( mapArgs, keyAfterBracket, inverseKeyAfterBracket, JumpToBeginForward, JumpToBeginBackward, JumpToEndForward, JumpToEndBackward, isEndJumpToEnd, ... )
This function sets up mappings starting with [ and ] for movement (with
optional [count]) relative to the current cursor position, but rely on four
-passed jump functions instead of text patterns to do the movement.
+passed jump functions instead of text patterns to do the movement.
CountJump#TextObject#MakeWithCountSearch( mapArgs, textObjectKey, types, selectionMode, patternToBegin, patternToEnd )
Defines a complete set of mappings for inner and/or outer text objects that
support an optional [count] and are driven by search patterns for the
beginning and end of a block. Outer text objects include the matched pattern
-text, inner ones not. Selection can be characterwise, linewise or blockwise.
+text, inner ones not. Selection can be characterwise, linewise or blockwise.
CountJump#TextObject#MakeWithJumpFunctions( mapArgs, textObjectKey, types, selectionMode, JumpToBegin, JumpToEnd )
@@ -70,63 +79,65 @@ This is a generalization of CountJump#TextObject#MakeWithCountSearch() that
invokes custom functions instead of searching for a fixed pattern. This is
useful if the check for a match is too complex for a single regular
expression, or if you need to adjust the match position depending on the
-circumstances.
+circumstances.
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:
+certain pattern (or, even more generic, where a provided predicate function
+returns a match position). 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, isMatch, step, isToEndOfLine )
+CountJump#Region#JumpToRegionEnd( count, Expr, 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().
+that can then be passed to CountJump#TextObject#MakeWithJumpFunctions().
-CountJump#Region#JumpToNextRegion( count, pattern, isMatch, step, isAcrossRegion, isToEndOfLine )
+CountJump#Region#JumpToNextRegion( count, Expr, isMatch, step, isAcrossRegion, isToEndOfLine )
Starting from the current line, search for the position where the count'th
-region begins/ends.
+region begins/ends.
-CountJump#Region#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, inverseKeyAfterBracket, pattern, isMatch, ... )
+CountJump#Region#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, inverseKeyAfterBracket, Expr, isMatch, ... )
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.
+region defined by contiguous lines that (don't) match a:Expr.
-CountJump#Region#TextObject#Make( mapArgs, textObjectKey, types, selectionMode, pattern, isMatch )
+CountJump#Region#TextObject#Make( mapArgs, textObjectKey, types, selectionMode, Expr, 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.
+contiguous lines that (don't) match a:Expr.
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.
+not themselves belong to a region.
EXAMPLE
Let's illustrate the usage by developing custom motions and text objects for
-Pascal begin..end blocks.
+Pascal begin..end blocks.
We want to move around blocks, and override the default section movements for
-it:
-]] Go to [count] next start of a block.
-][ Go to [count] next end of a block.
-[[ Go to [count] previous start of a block.
-[] Go to [count] previous end of a block.
+it:
+]] Go to [count] next start of a block.
+][ Go to [count] next end of a block.
+[[ Go to [count] previous start of a block.
+[] Go to [count] previous end of a block.
call CountJump#Motion#MakeBracketMotion('<buffer>', '', '', '\c^begin\n\zs', '\c^.*\nend', 0)
The begin pattern positions the cursor on the beginning of the line following
the "begin" keyword, the end pattern on the beginning of the line
-preceding the "end" keyword.
+preceding the "end" keyword.
We want to select a block, either including or excluding the lines with the
-begin..end keywords:
-ib "inner block" text object, select [count] contents of
- a block.
-ab "a block" text object, select [count] blocks.
+begin..end keywords:
+ib "inner block" text object, select [count] contents of
+ a block.
+ab "a block" text object, select [count] blocks.
call CountJump#TextObject#MakeWithCountSearch('<buffer>', 'b', 'ai', 'V', '\c^begin\n', '\c^end.*$')
If there is a filetype detection for Pascal files, we can simply put the
-above calls in a ~/.vim/ftplugin/pascal_movement.vim script and are done.
+above calls in a ~/.vim/ftplugin/pascal_movement.vim script and are done.
View
2 autoload/CountJump.vim
@@ -242,4 +242,4 @@ function! CountJump#JumpFunc( mode, JumpFunc, ... )
endif
endfunction
-" vim: set sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
View
42 autoload/CountJump/Mappings.vim
@@ -0,0 +1,42 @@
+" CountJump/Mappings.vim: Utility functions to create the mappings.
+"
+" DEPENDENCIES:
+"
+" Copyright: (C) 2012 Ingo Karkat
+" The VIM LICENSE applies to this script; see ':help copyright'.
+"
+" Maintainer: Ingo Karkat <ingo@karkat.de>
+"
+" REVISION DATE REMARKS
+" 1.60.001 27-Mar-2012 file creation
+let s:save_cpo = &cpo
+set cpo&vim
+
+function! CountJump#Mappings#MakeMotionKey( isForward, keys )
+ return (a:keys =~# '^<Plug>' ?
+ \ printf(a:keys, (a:isForward ? 'Forward' : 'Backward')) :
+ \ (a:isForward ? ']' : '[') . a:keys
+ \)
+endfunction
+function! CountJump#Mappings#MakeTextObjectKey( type, keys )
+ return (a:keys =~# '^<Plug>' ?
+ \ printf(a:keys, (a:type ==# 'i' ? 'Inner' : 'Outer')) :
+ \ a:type . a:keys
+ \)
+endfunction
+function! CountJump#Mappings#EscapeForFunctionName( text )
+ let l:text = a:text
+
+ " Strip off a <Plug> prefix.
+ let l:text = substitute(l:text, '^<Plug>', '', '')
+
+ " Convert all non-alphabetical characters to their hex value to create a
+ " valid function name.
+ let l:text = substitute(l:text, '\A', '\=char2nr(submatch(0))', 'g')
+
+ return l:text
+endfunction
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
View
38 autoload/CountJump/Motion.vim
@@ -1,14 +1,16 @@
-" CountJump#Motion.vim: Create custom motions via repeated jumps (or searches).
+" CountJump/Motion.vim: Create custom motions via repeated jumps (or searches).
"
" DEPENDENCIES:
-" - CountJump.vim autoload script.
+" - CountJump.vim, CountJump/Mappings.vim autoload scripts.
"
-" Copyright: (C) 2009-2010 Ingo Karkat
+" Copyright: (C) 2009-2012 Ingo Karkat
" The VIM LICENSE applies to this script; see ':help copyright'.
"
" Maintainer: Ingo Karkat <ingo@karkat.de>
"
" REVISION DATE REMARKS
+" 1.60.007 27-Mar-2012 ENH: When keys start with <Plug>, insert Forward
+" / Backward instead of prepending [ / ].
" 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
@@ -78,9 +80,14 @@ function! CountJump#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, inverseK
"* INPUTS:
" a:mapArgs Arguments to the :map command, like '<buffer>' for a
" buffer-local mapping.
-" a:keyAfterBracket Mapping key [sequence] after the mandatory ]/[ which
+" a:keyAfterBracket Mapping key [sequence] after the mandatory ] / [ which
" start the mapping for a motion to the beginning of a
" block.
+" When this starts with <Plug>, the key sequence is taken
+" as a template and a %s is replaced with "Forward" /
+" "Backward" instead of prepending ] / [. Through this,
+" plugins can define configurable mappings that not
+" necessarily start with ] / [.
" 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
@@ -127,12 +134,12 @@ function! CountJump#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, inverseK
else
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' ])
+ call add(l:dataset, [ CountJump#Mappings#MakeMotionKey(0, a:keyAfterBracket), a:patternToBegin, 'bW' ])
+ call add(l:dataset, [ CountJump#Mappings#MakeMotionKey(1, 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 ])
+ call add(l:dataset, [ CountJump#Mappings#MakeMotionKey(0, a:inverseKeyAfterBracket), a:patternToEnd, 'bW' . l:endMatch ])
+ call add(l:dataset, [ CountJump#Mappings#MakeMotionKey(1, a:inverseKeyAfterBracket), a:patternToEnd, 'W' . l:endMatch ])
endif
endif
for l:mode in l:mapModes
@@ -181,6 +188,11 @@ function! CountJump#Motion#MakeBracketMotionWithJumpFunctions( mapArgs, keyAfter
" a:keyAfterBracket Mapping key [sequence] after the mandatory ]/[ which
" start the mapping for a motion to the beginning of a
" block.
+" When this starts with <Plug>, the key sequence is taken
+" as a template and a %s is replaced with "Forward" /
+" "Backward" instead of prepending ] / [. Through this,
+" plugins can define configurable mappings that not
+" necessarily start with ] / [.
" 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
@@ -235,12 +247,12 @@ function! CountJump#Motion#MakeBracketMotionWithJumpFunctions( mapArgs, keyAfter
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)
+ call s:AddTupleIfValue(l:dataset, CountJump#Mappings#MakeMotionKey(0, a:keyAfterBracket), a:JumpToBeginBackward)
+ call s:AddTupleIfValue(l:dataset, CountJump#Mappings#MakeMotionKey(1, 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)
+ call s:AddTupleIfValue(l:dataset, CountJump#Mappings#MakeMotionKey(0, a:inverseKeyAfterBracket), a:JumpToEndBackward)
+ call s:AddTupleIfValue(l:dataset, CountJump#Mappings#MakeMotionKey(1, a:inverseKeyAfterBracket), a:JumpToEndForward)
endif
endif
@@ -261,4 +273,4 @@ endfunction
let &cpo = s:save_cpo
unlet s:save_cpo
-" vim: set sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
View
4 autoload/CountJump/Region.vim
@@ -1,4 +1,4 @@
-" Region.vim: Move to borders of a region defined by lines matching a pattern.
+" CountJump/Region.vim: Move to borders of a region defined by lines matching a pattern.
"
" DEPENDENCIES:
"
@@ -319,4 +319,4 @@ function! CountJump#Region#JumpToNextRegion( count, Expr, isMatch, step, isAcros
return s:DoJump(l:position, a:isToEndOfLine)
endfunction
-" vim: set sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
View
23 autoload/CountJump/Region/Motion.vim
@@ -1,15 +1,17 @@
-" CountJump#Region#Motion.vim: Create custom motions via jumps over matching
+" CountJump/Region/Motion.vim: Create custom motions via jumps over matching
" lines.
"
" DEPENDENCIES:
-" - CountJump.vim, CountJump/Region.vim autoload scripts.
+" - CountJump.vim, CountJump/Mappings.vim, CountJump/Region.vim autoload scripts.
"
-" Copyright: (C) 2010-2011 Ingo Karkat
+" Copyright: (C) 2010-2012 Ingo Karkat
" The VIM LICENSE applies to this script; see ':help copyright'.
"
" Maintainer: Ingo Karkat <ingo@karkat.de>
"
" REVISION DATE REMARKS
+" 1.60.004 27-Mar-2012 ENH: When keys start with <Plug>, insert Forward
+" / Backward instead of prepending [ / ].
" 1.50.003 30-Aug-2011 Also support a match()-like Funcref instead of a
" pattern to define the range.
" 1.30.002 19-Dec-2010 Added a:isToEndOfLine argument to
@@ -66,6 +68,11 @@ function! CountJump#Region#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, i
" a:keyAfterBracket Mapping key [sequence] after the mandatory ]/[ which
" start the mapping for a motion to the beginning of a
" block.
+" When this starts with <Plug>, the key sequence is taken
+" as a template and a %s is replaced with "Forward" /
+" "Backward" instead of prepending ] / [. Through this,
+" plugins can define configurable mappings that not
+" necessarily start with ] / [.
" 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
@@ -98,12 +105,12 @@ function! CountJump#Region#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, i
call add(l:dataset, ['][', 1, 1, 1])
else
if ! empty(a:keyAfterBracket)
- call add(l:dataset, ['[' . a:keyAfterBracket, -1, 1, 0])
- call add(l:dataset, [']' . a:keyAfterBracket, 1, 0, 0])
+ call add(l:dataset, [CountJump#Mappings#MakeMotionKey(0, a:keyAfterBracket), -1, 1, 0])
+ call add(l:dataset, [CountJump#Mappings#MakeMotionKey(1, a:keyAfterBracket) , 1, 0, 0])
endif
if ! empty(a:inverseKeyAfterBracket)
- call add(l:dataset, ['[' . a:inverseKeyAfterBracket, -1, 0, 0])
- call add(l:dataset, [']' . a:inverseKeyAfterBracket, 1, 1, 1])
+ call add(l:dataset, [CountJump#Mappings#MakeMotionKey(0, a:inverseKeyAfterBracket), -1, 0, 0])
+ call add(l:dataset, [CountJump#Mappings#MakeMotionKey(1, a:inverseKeyAfterBracket), 1, 1, 1])
endif
endif
@@ -127,4 +134,4 @@ function! CountJump#Region#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, i
endfor
endfunction
-" vim: set sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
View
20 autoload/CountJump/Region/TextObject.vim
@@ -1,14 +1,16 @@
-" TextObject.vim: Create custom text objects via jumps over matching lines.
+" CountJump/Region/TextObject.vim: Create custom text objects via jumps over matching lines.
"
" DEPENDENCIES:
-" - CountJump/Region.vim, CountJump/TextObjects.vim autoload scripts.
+" - CountJump/Mappings.vim, CountJump/Region.vim, CountJump/TextObjects.vim autoload scripts
"
-" Copyright: (C) 2010-2011 Ingo Karkat
+" Copyright: (C) 2010-2012 Ingo Karkat
" The VIM LICENSE applies to this script; see ':help copyright'.
"
" Maintainer: Ingo Karkat <ingo@karkat.de>
"
" REVISION DATE REMARKS
+" 1.60.003 27-Mar-2012 ENH: When keys start with <Plug>, insert Inner /
+" Outer instead of prepending i / a.
" 1.50.002 30-Aug-2011 Also support a match()-like Funcref instead of a
" pattern to define the range.
" 1.40.001 20-Dec-2010 file creation
@@ -44,6 +46,11 @@ function! CountJump#Region#TextObject#Make( mapArgs, textObjectKey, types, selec
" buffer-local mapping.
" a:textObjectKey Mapping key [sequence] after the mandatory i/a which
" start the mapping for the text object.
+" When this starts with <Plug>, the key sequence is taken
+" as a template and a %s is replaced with "Inner" /
+" "Outer" instead of prepending i / a. Through this,
+" plugins can define configurable text objects that not
+" necessarily start with i / a.
" a:types String containing 'i' for inner and 'a' for outer text
" objects.
" a:selectionMode Type of selection used between the patterns:
@@ -71,9 +78,10 @@ function! CountJump#Region#TextObject#Make( mapArgs, textObjectKey, types, selec
" function). If the same region definition is used for both inner and outer
" text objects, no such distinction need to be made.
let l:typePrefix = (strlen(a:types) == 1 ? a:types : '')
+ let l:functionName = CountJump#Mappings#EscapeForFunctionName(CountJump#Mappings#MakeTextObjectKey(l:typePrefix, a:textObjectKey))
- let l:functionToBeginName = printf('%sJumpToBegin_%s%s', l:scope, l:typePrefix, s:EscapeForFunctionName(a:textObjectKey))
- let l:functionToEndName = printf('%sJumpToEnd_%s%s', l:scope, l:typePrefix, s:EscapeForFunctionName(a:textObjectKey))
+ let l:functionToBeginName = printf('%sJumpToBegin_%s', l:scope, l:functionName)
+ let l:functionToEndName = printf('%sJumpToEnd_%s', l:scope, l:functionName)
let l:regionFunction = "
\ function! %s( count, isInner )\n
@@ -122,4 +130,4 @@ function! CountJump#Region#TextObject#Make( mapArgs, textObjectKey, types, selec
return CountJump#TextObject#MakeWithJumpFunctions(a:mapArgs, a:textObjectKey, l:types, a:selectionMode, s:function(l:functionToBeginName), s:function(l:functionToEndName))
endfunction
-" vim: set sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
View
32 autoload/CountJump/TextObject.vim
@@ -1,14 +1,16 @@
-" CountJump#TextObject.vim: Create custom text objects via repeated jumps (or searches).
+" CountJump/TextObject.vim: Create custom text objects via repeated jumps (or searches).
"
" DEPENDENCIES:
-" - CountJump.vim autoload script.
+" - CountJump.vim, CountJump/Mappings.vim autoload scripts
"
-" Copyright: (C) 2009-2011 Ingo Karkat
+" Copyright: (C) 2009-2012 Ingo Karkat
" The VIM LICENSE applies to this script; see ':help copyright'.
"
" Maintainer: Ingo Karkat <ingo@karkat.de>
"
" REVISION DATE REMARKS
+" 1.60.012 27-Mar-2012 ENH: When keys start with <Plug>, insert Inner /
+" Outer instead of prepending i / a.
" 1.50.011 30-Aug-2011 Initialize global g:CountJump_Context object for
" custom use by Funcrefs.
" 1.40.010 20-Dec-2010 Replaced s:Escape() function with string().
@@ -229,6 +231,11 @@ function! CountJump#TextObject#MakeWithJumpFunctions( mapArgs, textObjectKey, ty
" buffer-local mapping.
" a:textObjectKey Mapping key [sequence] after the mandatory i/a which
" start the mapping for the text object.
+" When this starts with <Plug>, the key sequence is taken
+" as a template and a %s is replaced with "Inner" /
+" "Outer" instead of prepending i / a. Through this,
+" plugins can define configurable text objects that not
+" necessarily start with i / a.
" a:types String containing 'i' for inner and 'a' for outer text
" objects.
" Use 'I' if you want the inner jump _include_ the text
@@ -279,7 +286,7 @@ function! CountJump#TextObject#MakeWithJumpFunctions( mapArgs, textObjectKey, ty
\ printf("%snoremap <silent> %s %s :<C-U>call CountJump#TextObject#TextObjectWithJumpFunctions('%s', %s, %s, '%s', %s, %s)<CR>",
\ (l:mode ==# 'v' ? 'x' : l:mode),
\ a:mapArgs,
- \ (tolower(l:type) . a:textObjectKey),
+ \ CountJump#Mappings#MakeTextObjectKey(tolower(l:type), a:textObjectKey),
\ l:mode,
\ l:isInner,
\ l:isExcludeBoundaries,
@@ -292,11 +299,6 @@ function! CountJump#TextObject#MakeWithJumpFunctions( mapArgs, textObjectKey, ty
endfor
endfunction
-function! s:EscapeForFunctionName( text )
- " Convert all non-alphabetical characters to their hex value to create a
- " valid function name.
- return substitute(a:text, '\A', '\=char2nr(submatch(0))', 'g')
-endfunction
function! s:function(name)
return function(substitute(a:name, '^s:', matchstr(expand('<sfile>'), '<SNR>\d\+_\zefunction$'),''))
endfunction
@@ -320,6 +322,11 @@ function! CountJump#TextObject#MakeWithCountSearch( mapArgs, textObjectKey, type
" buffer-local mapping.
" a:textObjectKey Mapping key [sequence] after the mandatory i/a which
" start the mapping for the text object.
+" When this starts with <Plug>, the key sequence is taken
+" as a template and a %s is replaced with "Inner" /
+" "Outer" instead of prepending i / a. Through this,
+" plugins can define configurable text objects that not
+" necessarily start with i / a.
" a:types String containing 'i' for inner and 'a' for outer text
" objects.
" a:selectionMode Type of selection used between the patterns:
@@ -356,9 +363,10 @@ function! CountJump#TextObject#MakeWithCountSearch( mapArgs, textObjectKey, type
" function). If the same pattern to begin / end can be used for both inner
" and outer text objects, no such distinction need to be made.
let l:typePrefix = (strlen(a:types) == 1 ? a:types : '')
+ let l:functionName = CountJump#Mappings#EscapeForFunctionName(CountJump#Mappings#MakeTextObjectKey(l:typePrefix, a:textObjectKey))
- let l:functionToBeginName = printf('%sJumpToBegin_%s%s', l:scope, l:typePrefix, s:EscapeForFunctionName(a:textObjectKey))
- let l:functionToEndName = printf('%sJumpToEnd_%s%s', l:scope, l:typePrefix, s:EscapeForFunctionName(a:textObjectKey))
+ let l:functionToBeginName = printf('%sJumpToBegin_%s', l:scope, l:functionName)
+ let l:functionToEndName = printf('%sJumpToEnd_%s', l:scope, l:functionName)
" In case of an inner jump, we first make an outer jump, store the position,
" then go to the other (inner) side of the boundary text, and return the
@@ -397,4 +405,4 @@ endfunction
let &cpo = s:save_cpo
unlet s:save_cpo
-" vim: set sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
View
173 doc/CountJump.txt
@@ -1,10 +1,11 @@
-*CountJump.txt* Create custom motions and text objects via repeated jumps.
+*CountJump.txt* Create custom motions and text objects via repeated jumps.
COUNT JUMP by Ingo Karkat
*CountJump.vim*
description |CountJump-description|
usage |CountJump-usage|
example |CountJump-example|
+integration |CountJump-integration|
installation |CountJump-installation|
limitations |CountJump-limitations|
known problems |CountJump-known-problems|
@@ -17,69 +18,70 @@ DESCRIPTION *CountJump-description*
Though it is not difficult to write a custom |movement| (basically a |:map|
that executes some kind of search or jump) and a custom |text-object| (an
|:omap| that selects a range of text), this is too complex for a novice user
-and often repetitive.
+and often repetitive.
This plugin covers the common use case where the movement and boundaries of a
text object can be specified via start and end patterns, and offers a single
function to set up related mappings. With it, you can enhance some built-in
Vim mappings to take an optional [count], and quickly define new mappings for
-help file sections, diff hunks, embedded macros, and so on...
+help file sections, diff hunks, embedded macros, and so on...
As a generalization of the start and end patterns, the movement and boundaries
of a text object can also be specified via jump functions, i.e. Funcrefs of
functions that position the cursor on the appropriate location and return that
location. This can be used where the jump is difficult to express with a
single regular expression, the jump may need adapting depending on the
-context, or other uses.
+context, or other uses.
This plugin contains some support for movement and text objects consisting of
text regions that can be defined by continuous lines that match a particular
-pattern, e.g. comment blocks that all start with /^\s*#/.
+pattern, e.g. comment blocks that all start with /^\s*#/.
-SEE ALSO *
+SEE ALSO *
-The following ftplugins use this plugin:
+The following ftplugins use this plugin:
diff_movement (vimscript #3180): Movement over diff hunks with ]] etc.
fortunes_movement (vimscript #3181): Movement over email fortunes with ]] etc.
help_movement (vimscript #3179): Movement over Vim help sections with ]] etc.
mail_movement (vimscript #3182): Movement over email quotes with ]] etc.
+JumpToTrailingWhitespace (vimscript #3968): Motions to locate unwanted
+ whitespace at the end of lines.
-
-RELATED WORKS *
+RELATED WORKS *
- motpat.vim (vimscript #3030) offers similar functions to setup motion
- mappings, but no text objects (yet).
+ mappings, but no text objects (yet).
- textobj-user (vimscript #2100) has support for user-defined text objects via
- regular expressions.
+ regular expressions.
==============================================================================
USAGE *CountJump-usage*
The plugin defines several functions, which set up the appropriate mappings
based on the arguments that you supply. The following is an overview; you'll
find the details directly in the implementation files in the
-.vim/autoload/CountJump/ directory.
+.vim/autoload/CountJump/ directory.
CountJump#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, inverseKeyAfterBracket, patternToBegin, patternToEnd, isEndPatternToEnd, ... )
This function sets up mappings starting with [ and ] for movement (with
optional [count]) relative to the current cursor position, targeting either a
text pattern at the beginning ([{keyAfterBracket} mapping) or a text pattern
at the end (]{inverseKeyAfterBracket} mapping) of whatever you want to treat
-as a text block.
+as a text block.
CountJump#Motion#MakeBracketMotionWithJumpFunctions( mapArgs, keyAfterBracket, inverseKeyAfterBracket, JumpToBeginForward, JumpToBeginBackward, JumpToEndForward, JumpToEndBackward, isEndJumpToEnd, ... )
This function sets up mappings starting with [ and ] for movement (with
optional [count]) relative to the current cursor position, but rely on four
-passed jump functions instead of text patterns to do the movement.
+passed jump functions instead of text patterns to do the movement.
CountJump#TextObject#MakeWithCountSearch( mapArgs, textObjectKey, types, selectionMode, patternToBegin, patternToEnd )
Defines a complete set of mappings for inner and/or outer text objects that
support an optional [count] and are driven by search patterns for the
beginning and end of a block. Outer text objects include the matched pattern
-text, inner ones not. Selection can be characterwise, linewise or blockwise.
+text, inner ones not. Selection can be characterwise, linewise or blockwise.
CountJump#TextObject#MakeWithJumpFunctions( mapArgs, textObjectKey, types, selectionMode, JumpToBegin, JumpToEnd )
@@ -88,40 +90,40 @@ This is a generalization of CountJump#TextObject#MakeWithCountSearch() that
invokes custom functions instead of searching for a fixed pattern. This is
useful if the check for a match is too complex for a single regular
expression, or if you need to adjust the match position depending on the
-circumstances.
+circumstances.
Often, a region can be defined as a block of continuous lines that all match a
certain pattern (or, even more generic, where a provided predicate function
returns a match position). The following functions aid in implementing
movements to the boundaries of these regions and text objects consisting of
-the region:
+the region:
CountJump#Region#JumpToRegionEnd( count, Expr, 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().
+that can then be passed to CountJump#TextObject#MakeWithJumpFunctions().
CountJump#Region#JumpToNextRegion( count, Expr, isMatch, step, isAcrossRegion, isToEndOfLine )
Starting from the current line, search for the position where the count'th
-region begins/ends.
+region begins/ends.
CountJump#Region#Motion#MakeBracketMotion( mapArgs, keyAfterBracket, inverseKeyAfterBracket, Expr, isMatch, ... )
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:Expr.
+region defined by contiguous lines that (don't) match a:Expr.
CountJump#Region#TextObject#Make( mapArgs, textObjectKey, types, selectionMode, Expr, 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:Expr.
+contiguous lines that (don't) match a:Expr.
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.
+not themselves belong to a region.
*g:CountJump_Context*
The custom Funcrefs for jumps and predicates of lines belonging to a range may
@@ -130,37 +132,37 @@ destination. To help the Funcrefs to determine where in this sequence they
are, an empty g:CountJump_Context |dictionary| is initialized at the start of
each CountJump function. Funcrefs can put custom information (e.g. the
particular comment prefix on the current line) in there and evaluate this in
-subsequent invocations.
+subsequent invocations.
==============================================================================
EXAMPLE *CountJump-example*
Let's illustrate the usage by developing custom motions and text objects for
-Pascal begin..end blocks.
+Pascal begin..end blocks.
We want to move around blocks, and override the default section movements for
-it:
-]] Go to [count] next start of a block.
-][ Go to [count] next end of a block.
-[[ Go to [count] previous start of a block.
-[] Go to [count] previous end of a block.
+it:
+]] Go to [count] next start of a block.
+][ Go to [count] next end of a block.
+[[ Go to [count] previous start of a block.
+[] Go to [count] previous end of a block.
>
call CountJump#Motion#MakeBracketMotion('<buffer>', '', '', '\c^begin\n\zs', '\c^.*\nend', 0)
The begin pattern positions the cursor on the beginning of the line following
the "begin" keyword, the end pattern on the beginning of the line
-preceding the "end" keyword.
+preceding the "end" keyword.
We want to select a block, either including or excluding the lines with the
-begin..end keywords:
+begin..end keywords:
ib "inner block" text object, select [count] contents of
- a block.
-ab "a block" text object, select [count] blocks.
+ a block.
+ab "a block" text object, select [count] blocks.
>
call CountJump#TextObject#MakeWithCountSearch('<buffer>', 'b', 'ai', 'V', '\c^begin\n', '\c^end.*$')
If there is a filetype detection for Pascal files, we can simply put the
-above calls in a ~/.vim/ftplugin/pascal_movement.vim script and are done.
+above calls in a ~/.vim/ftplugin/pascal_movement.vim script and are done.
==============================================================================
INSTALLATION *CountJump-installation*
@@ -171,68 +173,107 @@ the archive first, e.g. using WinZip. Inside Vim, install by sourcing the
vimball or via the |:UseVimball| command. >
vim CountJump.vba.gz
:so %
-To uninstall, use the |:RmVimball| command.
+To uninstall, use the |:RmVimball| command.
DEPENDENCIES *CountJump-dependencies*
-- Requires Vim 7.0 or higher.
+- Requires Vim 7.0 or higher.
==============================================================================
+INTEGRATION *CountJump-integration*
+ *CountJump-remap-motions* *CountJump-plug-motions*
+If you want to define motions that do not start with [ / ], and the plugin
+that employs CountJump offers a configuration variable like
+g:PluginName_mapping to influence the mapped key(s), you can define
+intermediate <Plug>-mappings (|using-<Plug>|), and then define your own custom
+mappings based on them: >
+ let g:PluginName_mapping = '<Plug>PluginName%s'
+ nmap { <Plug>PluginNameBackward
+ nmap } <Plug>PluginNameForward
+ omap { <Plug>PluginNameBackward
+ omap } <Plug>PluginNameForward
+ vmap { <Plug>PluginNameBackward
+ vmap } <Plug>PluginNameForward
+<
+ *CountJump-remap-text-objects* *CountJump-plug-text-objects*
+If you want to define text objects that do not start with i / a, and the plugin
+that employs CountJump offers a configuration variable like
+g:PluginName_mapping to influence the mapped key(s), you can define
+intermediate <Plug>-mappings (|using-<Plug>|), and then define your own custom
+mappings based on them: >
+ let g:PluginName_mapping = '<Plug>PluginName%s'
+ omap ,p <Plug>PluginNameInner
+ omap ,P <Plug>PluginNameOuter
+ vmap ,p <Plug>PluginNameInner
+ vmap ,P <Plug>PluginNameOuter
+<
+==============================================================================
LIMITATIONS *CountJump-limitations*
KNOWN PROBLEMS *CountJump-known-problems*
- An outer text object cannot consist of the same, multiple characters;
nothing will be selected (because the end pattern also matches at the begin
- position). A same single character pattern works, though.
+ position). A same single character pattern works, though.
- For blockwise text objects, the original cursor position should be required
to be inside the selection. However, this requires translation of the
- byte-indices here into screen columns, and is thus non-trivial to implement.
+ byte-indices here into screen columns, and is thus non-trivial to implement.
TODO *CountJump-todo*
IDEAS *CountJump-ideas*
-- Add configuration to change behavior when there are no [count] matches:
+- Add configuration to change behavior when there are no [count] matches:
1. obey the 'wrapscan' option, like |]s| and/or
2. jump as many matches as possible, still beep to indicate the actual
target was not reached
- Add customization parameter so that the motion / text object includes the
start / end of buffer in case patternToBegin / patternToEnd do not match any
- more.
+ more.
==============================================================================
HISTORY *CountJump-history*
+1.60 27-Mar-2012
+- ENH: Allow motions that do not start with [ / ] and text objects that do not
+ start with i / a by passing keys that begin with <Plug>. With this, plugins
+ using CountJump can offer the expected customizability. Since most users
+ probably still prefer the default keys, it is recommended that plugins do
+ not use <Plug> mappings from the start, but make the a:keyAfterBracket /
+ a:inverseKeyAfterBracket / a:textObjectKey configurable via a
+ g:PluginName_mapping variable, and instruct users to set this to
+ "<Plug>PluginName%s" and create their own mappings based on them, as
+ described in |CountJump-integration|.
+
1.50 30-Aug-2011
- For regions of lines, also support a match()-like Funcref instead of a
pattern to define the range. This for example enables to define a range of
- diff changes via a predicate function that checks diff_hlID() != 0.
-- Initialize global g:CountJump_Context object for custom use by Funcrefs.
+ diff changes via a predicate function that checks diff_hlID() != 0.
+- Initialize global g:CountJump_Context object for custom use by Funcrefs.
1.41 13-Jun-2011
-- FIX: Directly ring the bell to avoid problems when running under :silent!.
+- FIX: Directly ring the bell to avoid problems when running under :silent!.
1.40 20-Dec-2010
- ENH: Added CountJump#Region#TextObject#Make() to easily define text objects
- for regions.
+ for regions.
- Interface change: Jump functions again return position (and actual,
corrected one for a:isToEndOfLine). Though the position is not used for
motions, it is necessary for text objects to differentiate between "already
- at the begin/end position" and "no such position".
+ at the begin/end position" and "no such position".
1.30 20-Dec-2010
- ENH: Added CountJump#Region#Motion#MakeBracketMotion() to easily define
- bracket motions for regions.
-- Interface changes:
+ 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().
+ 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.
+ operated on / selected.
- Added a:isMatch argument to CountJump#Region#SearchForRegionEnd(),
CountJump#Region#JumpToRegionEnd(),
CountJump#Region#SearchForNextRegion(),
@@ -242,16 +283,16 @@ HISTORY *CountJump-history*
1.22 06-Aug-2010
- No more motion mappings and text objects for select mode; as the mappings
- start with a printable character, no select-mode mapping should be defined.
+ start with a printable character, no select-mode mapping should be defined.
1.21 03-Aug-2010
- FIX: A 2]] jump inside a region (unless last line) jumped like a 1]] jump.
The search for next region must not decrease the iteration counter when
- _not_ searching _across_ the region.
+ _not_ searching _across_ the region.
- FIX: Must not do (characterwise) end position adaptation for linewise text
- object that does not exclude boundaries.
+ object that does not exclude boundaries.
- Switched example from email fortunes to Pascal begin..end blocks, as they
- are conceptually easier.
+ are conceptually easier.
1.20 02-Aug-2010
- ENH: In CountJump#Motion#MakeBracketMotion(), a:keyAfterBracket and
@@ -260,36 +301,36 @@ HISTORY *CountJump-history*
CountJump#Motion#MakeBracketMotionWithJumpFunctions().
- With the added CountJump#Motion#MakeBracketMotionWithJumpFunctions() motions
can be defined via jump functions, similar to how text objects can be
- defined.
+ defined.
- Added CountJump/Region.vim to move to borders of a region defined by lines
- matching a pattern.
+ matching a pattern.
- FIX: CountJump#CountJump() with mode "O" didn't add original position to
- jump list.
+ 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.)
+ 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).
+ the buffer).
1.10 19-Jul-2010
- Changed behavior if there aren't [count] matches: Instead of jumping to the
last available match (and ringing the bell), the cursor stays at the
- original position, like with the old vi-compatible motions.
+ original position, like with the old vi-compatible motions.
- ENH: Only adding to jump list if there actually is a match. This is like the
- built-in Vim motions work.
+ built-in Vim motions work.
- FIX: For a linewise text object, the end cursor column is not important; do
- not compare with the original cursor column in this case.
+ not compare with the original cursor column in this case.
1.00 22-Jun-2010
-First published version.
+First published version.
0.01 14-Feb-2009
-Started development.
+Started development.
==============================================================================
-Copyright: (C) 2009-2011 Ingo Karkat
-The VIM LICENSE applies to this script; see|copyright|.
+Copyright: (C) 2009-2012 Ingo Karkat
+The VIM LICENSE applies to this script; see|copyright|.
Maintainer: Ingo Karkat <ingo@karkat.de>
==============================================================================

0 comments on commit 660d37b

Please sign in to comment.