Skip to content

Commit

Permalink
Version 1.83
Browse files Browse the repository at this point in the history
- Use more canonical way of invoking the Funcrefs in CountJump#Motion#MakeBracketMotionWithJumpFunctions(); this will then also work with passed String function names.
- FIX: Need to save v:count1 before issuing the normal mode "gv" command.
- Minor: Make substitute() robust against 'ignorecase'.
- Add optional dependency to ingo-library (vimscript #4433).
- FIX: In text objects, when the end position is before the begin position, that's not a valid selection. Test for this and abort in that case.
- For linewise selections, always position the cursor at the start of the end line to be consistent with the built-in text objects, and to avoid complicating the search patterns when attempting to do this through them.
  • Loading branch information
Ingo Karkat authored and vim-scripts committed Jan 29, 2014
1 parent 87ba8a4 commit c2c7725
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 88 deletions.
28 changes: 20 additions & 8 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,29 @@ 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.
diffwindow_movement: Movement over changes in a diff window.
(vimscript #3719)
JumpToTrailingWhitespace: Motions to locate unwanted whitespace at the end of lines.
(vimscript #3968)
TaskMotion (vimscript #3990): Motions to task and TODO markers.
ConflictMotions (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.
SameSyntaxMotion (vimscript #4338): Motions to the borders of the same syntax highlighting.
JumpToVerticalOccurrence: Like f{char}, but searching the same
(vimscript #4841) screen column, not line.

RELATED WORKS
- motpat.vim (vimscript #3030) offers similar functions to setup motion
mappings, but no text objects (yet).
- textobj-user (vimscript #2100) has support for user-defined text objects via
regular expressions.
- movealong.vim (vimscript #4691) provides a :Movealong command (and optional
mappings) that repeatedly executes a motion until a condition of a syntax,
pattern match, or arbitrary expression is met.

USAGE
The plugin defines several functions, which set up the appropriate mappings
Expand All @@ -64,15 +72,13 @@ 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.


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.


CountJump#TextObject#MakeWithJumpFunctions( mapArgs, textObjectKey, types, selectionMode, JumpToBegin, JumpToEnd )

This is a generalization of CountJump#TextObject#MakeWithCountSearch() that
Expand All @@ -81,7 +87,6 @@ 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.


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
Expand Down Expand Up @@ -114,6 +119,14 @@ 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.

The custom Funcrefs for jumps and predicates of lines belonging to a range may
be invoked multiple times until the CountJump function arrives at its
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.

EXAMPLE
Let's illustrate the usage by developing custom motions and text objects for
Pascal begin..end blocks.
Expand All @@ -124,19 +137,18 @@ it:
][ 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.


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.

>
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
Expand Down
74 changes: 43 additions & 31 deletions autoload/CountJump.vim
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
" CountJump.vim: Move to a buffer position via repeated jumps (or searches).
"
" DEPENDENCIES:
" - ingo/motion/helper.vim autoload script (optional)
"
" Copyright: (C) 2009-2012 Ingo Karkat
" Copyright: (C) 2009-2014 Ingo Karkat
" The VIM LICENSE applies to this script; see ':help copyright'.
"
" Maintainer: Ingo Karkat <ingo@karkat.de>
"
" REVISION DATE REMARKS
" 1.83.019 11-Jan-2014 Factor out special treatment for visual and
" operator-pending motions to
" ingo#motion#helper#AdditionalMovement(), but
" keep internal fallback to keep the dependency to
" ingo-library optional.
" 1.83.018 14-Jun-2013 Minor: Make substitute() robust against
" 'ignorecase'.
" FIX: Need to save v:count1 before issuing the
" normal mode "gv" command.
" 1.81.017 15-Oct-2012 BUG: Wrong variable scope for copied
" a:isBackward in
" CountJump#CountSearchWithWrapMessage().
Expand Down Expand Up @@ -144,7 +154,7 @@ function! CountJump#CountSearchWithWrapMessage( count, searchName, searchArgumen
" (i.e. search(..., 'c')), the flag must only be active on the very
" first iteration; otherwise, all subsequent iterations will just
" stay put at the current match.
let l:searchArguments[1] = substitute(l:searchArguments[1], 'c', '', 'g')
let l:searchArguments[1] = substitute(l:searchArguments[1], '\Cc', '', 'g')
endif

" Note: No need to check s:searchArguments and 'wrapscan'; the wrapping
Expand Down Expand Up @@ -179,6 +189,30 @@ endfunction
function! CountJump#CountSearch( count, searchArguments )
return CountJump#CountSearchWithWrapMessage(a:count, '', a:searchArguments)
endfunction
silent! call ingo#motion#helper#DoesNotExist() " Execute a function to force autoload.
if exists('*ingo#motion#helper#AdditionalMovement')
function! s:AdditionalMovement( isSpecialLastLineTreatment )
return ingo#motion#helper#AdditionalMovement(a:isSpecialLastLineTreatment)
endfunction
else
function! s:AdditionalMovement( isSpecialLastLineTreatment )
let l:save_ww = &whichwrap
set whichwrap+=l
if a:isSpecialLastLineTreatment && line('.') == line('$') && &virtualedit !=# 'onemore' && &virtualedit !=# 'all'
" For the last line in the buffer, that still doesn't work in
" operator-pending mode, unless we can do virtual editing.
let l:save_ve = &virtualedit
set virtualedit=onemore
normal! l
augroup IngoLibraryTempVirtualEdit
execute 'autocmd! CursorMoved * set virtualedit=' . l:save_ve . ' | autocmd! IngoLibraryTempVirtualEdit'
augroup END
else
normal! l
endif
let &whichwrap = l:save_ww
endfunction
endif
function! CountJump#CountJumpWithWrapMessage( mode, searchName, ... )
"*******************************************************************************
"* PURPOSE:
Expand Down Expand Up @@ -206,12 +240,13 @@ function! CountJump#CountJumpWithWrapMessage( mode, searchName, ... )
" None.
"*******************************************************************************
let l:save_view = winsaveview()
let l:count = v:count1

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

let l:matchPosition = CountJump#CountSearchWithWrapMessage(v:count1, a:searchName, a:000)
let l:matchPosition = CountJump#CountSearchWithWrapMessage(l:count, a:searchName, a:000)
if l:matchPosition != [0, 0]
" Add the original cursor position to the jump list.
call winrestview(l:save_view)
Expand All @@ -220,37 +255,12 @@ function! CountJump#CountJumpWithWrapMessage( mode, searchName, ... )

if a:mode ==# 'V' && &selection ==# 'exclusive' || a:mode ==# 'O'
" Special additional treatment for end patterns to end.
" The difference between normal mode, operator-pending and visual
" mode with 'selection' set to "exclusive" is that in the latter
" two, the motion must go _past_ the final "word" character, so that
" all characters of the "word" are selected. This is done by
" appending a 'l' motion after the search for the next "word".
"
" 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.
let l:save_ww = &whichwrap
set whichwrap+=l
if a:mode ==# 'O' && line('.') == line('$') && &virtualedit !=# 'onemore' && &virtualedit !=# 'all'
" For the last line in the buffer, that still doesn't work in
" operator-pending mode, unless we can do virtual editing.
let l:save_ve = &virtualedit
set virtualedit=onemore
normal! l
augroup TempVirtualEdit
execute 'autocmd! CursorMoved * set virtualedit=' . l:save_ve . ' | autocmd! TempVirtualEdit'
augroup END
else
normal! l
endif
let &whichwrap = l:save_ww
call s:AdditionalMovement(a:mode ==# 'O')
endif
endif
endfunction
function! CountJump#CountJump( mode, ... )
" See CountJump#CountJumpWithWrapMessage().
return call('CountJump#CountJumpWithWrapMessage', [a:mode, ''] + a:000)
endfunction
function! CountJump#JumpFunc( mode, JumpFunc, ... )
Expand Down Expand Up @@ -286,12 +296,13 @@ function! CountJump#JumpFunc( mode, JumpFunc, ... )
"*******************************************************************************
let l:save_view = winsaveview()
let l:originalPosition = getpos('.')
let l:count = v:count1

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

call call(a:JumpFunc, [v:count1] + a:000)
call call(a:JumpFunc, [l:count] + a:000)
let l:matchPosition = getpos('.')
if l:matchPosition != l:originalPosition
" Add the original cursor position to the jump list.
Expand Down Expand Up @@ -411,6 +422,7 @@ function! CountJump#CountJumpFuncWithWrapMessage( count, searchName, isBackward,
return l:matchPosition
endfunction
function! CountJump#CountJumpFunc( count, SingleJumpFunc, ... )
" See CountJump#CountJumpFuncWithWrapMessage().
return call('CountJump#CountJumpFuncWithWrapMessage', [a:count, '', 0, a:SingleJumpFunc] + a:000)
endfunction

Expand Down
6 changes: 4 additions & 2 deletions autoload/CountJump/Mappings.vim
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
"
" DEPENDENCIES:
"
" Copyright: (C) 2012 Ingo Karkat
" Copyright: (C) 2012-2013 Ingo Karkat
" The VIM LICENSE applies to this script; see ':help copyright'.
"
" Maintainer: Ingo Karkat <ingo@karkat.de>
"
" REVISION DATE REMARKS
" 1.83.002 14-Jun-2013 Minor: Make substitute() robust against
" 'ignorecase'.
" 1.60.001 27-Mar-2012 file creation
let s:save_cpo = &cpo
set cpo&vim
Expand All @@ -28,7 +30,7 @@ function! CountJump#Mappings#EscapeForFunctionName( text )
let l:text = a:text

" Strip off a <Plug> prefix.
let l:text = substitute(l:text, '^<Plug>', '', '')
let l:text = substitute(l:text, '^\C<Plug>', '', '')

" Convert all non-alphabetical characters to their hex value to create a
" valid function name.
Expand Down
11 changes: 8 additions & 3 deletions autoload/CountJump/Motion.vim
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
" DEPENDENCIES:
" - CountJump.vim, CountJump/Mappings.vim autoload scripts.
"
" Copyright: (C) 2009-2012 Ingo Karkat
" Copyright: (C) 2009-2014 Ingo Karkat
" The VIM LICENSE applies to this script; see ':help copyright'.
"
" Maintainer: Ingo Karkat <ingo@karkat.de>
"
" REVISION DATE REMARKS
" 1.83.010 02-Jan-2014 Use more canonical way of invoking the Funcrefs
" in
" CountJump#Motion#MakeBracketMotionWithJumpFunctions();
" this will then also work with passed String
" function names.
" 1.81.009 16-Oct-2012 ENH: Add optional a:searchName argument to
" CountJump#Motion#MakeBracketMotion() to make
" searches wrap around when 'wrapscan' is set.
Expand Down Expand Up @@ -241,7 +246,7 @@ function! CountJump#Motion#MakeBracketMotionWithJumpFunctions( mapArgs, keyAfter
" Uppercase letters indicate special additional treatment for end
" jump to end.
" All Funcrefs should position the cursor to the appropriate position in the
" current window.
" current window. See also CountJump#CountJumpFuncWithWrapMessage().
" 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 Expand Up @@ -283,7 +288,7 @@ function! CountJump#Motion#MakeBracketMotionWithJumpFunctions( mapArgs, keyAfter
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>",
\ printf("%snoremap <silent> %s %s :<C-u>call call(%s, [%s])<CR>",
\ (l:mode ==# 'v' ? 'x' : l:mode),
\ a:mapArgs,
\ l:data[1],
Expand Down
Loading

0 comments on commit c2c7725

Please sign in to comment.