diff options
Diffstat (limited to 'autoload')
-rw-r--r-- | autoload/camelcasemotion.vim | 296 |
1 files changed, 147 insertions, 149 deletions
diff --git a/autoload/camelcasemotion.vim b/autoload/camelcasemotion.vim index ef4929c..248ba39 100644 --- a/autoload/camelcasemotion.vim +++ b/autoload/camelcasemotion.vim @@ -1,173 +1,171 @@ -" camelcasemotion.vim: Motion through CamelCaseWords and underscore_notation. +" camelcasemotion.vim: Motion through CamelCaseWords and underscore_notation. " " DEPENDENCIES: -" - Requires Vim 7.0 or higher. +" - Requires Vim 7.0 or higher. " " Copyright: (C) 2007-2009 by Ingo Karkat -" The VIM LICENSE applies to this script; see ':help copyright'. +" The VIM LICENSE applies to this script; see ':help copyright'. " -" Maintainer: Ingo Karkat <ingo@karkat.de> -" REVISION DATE REMARKS -" 1.50.001 05-May-2009 Do not create mappings for select mode; -" according to|Select-mode|, printable character -" commands should delete the selection and insert -" the typed characters. -" Moved functions from plugin to separate autoload -" script. -" file creation +" Maintainer: Ingo Karkat <ingo@karkat.de> +" REVISION DATE REMARKS +" 1.50.001 05-May-2009 Do not create mappings for select mode; +" according to|Select-mode|, printable character +" commands should delete the selection and insert +" the typed characters. +" Moved functions from plugin to separate autoload +" script. +" file creation "- functions ------------------------------------------------------------------" function! s:Move( direction, count, mode ) - " Note: There is no inversion of the regular expression character class - " 'keyword character' (\k). We need an inversion "non-keyword" defined as - " "any non-whitespace character that is not a keyword character" (e.g. - " [!@#$%^&*()]). This can be specified via a non-whitespace character in - " whose place no keyword character matches (\k\@!\S). + " Note: There is no inversion of the regular expression character class + " 'keyword character' (\k). We need an inversion "non-keyword" defined as + " "any non-whitespace character that is not a keyword character" (e.g. + " [!@#$%^&*()]). This can be specified via a non-whitespace character in + " whose place no keyword character matches (\k\@!\S). - "echo "count is " . a:count - let l:i = 0 - while l:i < a:count - if a:direction == 'e' - " "Forward to end" motion. - "call search( '\>\|\(\a\|\d\)\+\ze_', 'We' ) - " end of ... - " number | ACRONYM followed by CamelCase or number | CamelCase | underscore_notation | non-keyword | word - call search( '\m\d\+\|\u\+\ze\%(\u\l\|\d\)\|\l\+\ze\%(\u\|\d\)\|\u\l\+\|\%(\a\|\d\)\+\ze[-_]\|\%(\k\@!\S\)\+\|\%([-_]\@!\k\)\+\>', 'We' ) - " Note: word must be defined as '\k\>'; '\>' on its own somehow - " dominates over the previous branch. Plus, \k must exclude the - " underscore, or a trailing one will be incorrectly moved over: - " '\%(_\@!\k\)'. - if a:mode == 'o' - " Note: Special additional treatment for operator-pending mode - " "forward to end" motion. - " The difference between normal mode, operator-pending and visual - " mode 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". - " - " 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 - else - " Forward (a:direction == '') and backward (a:direction == 'b') - " motion. + "echo "count is " . a:count + let l:i = 0 + while l:i < a:count + if a:direction == 'e' || a:direction == 'ge' + " "Forward to end" motion. + " number | ACRONYM followed by CamelCase or number | CamelCase | underscore_notation | non-keyword | word + let l:direction = (a:direction == 'e' ? a:direction : 'be') + call search('\m\d\+\|\u\+\ze\%(\u\l\|\d\)\|\l\+\ze\%(\u\|\d\)\|\u\l\+\|\%(\a\|\d\)\+\ze[-_]\|\%(\k\@!\S\)\+\|\%([-_]\@!\k\)\+\>', 'W' . l:direction) + " Note: word must be defined as '\k\>'; '\>' on its own somehow + " dominates over the previous branch. Plus, \k must exclude the + " underscore, or a trailing one will be incorrectly moved over: + " '\%(_\@!\k\)'. + if a:mode == 'o' + " Note: Special additional treatment for operator-pending mode + " "forward to end" motion. + " The difference between normal mode, operator-pending and visual + " mode 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". + " + " 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 + else + " Forward (a:direction == '') and backward (a:direction == 'b') + " motion. - let l:direction = (a:direction == 'w' ? '' : a:direction) + let l:direction = (a:direction == 'w' ? '' : a:direction) - " CamelCase: Jump to beginning of either (start of word, Word, WORD, - " 123). - " Underscore_notation: Jump to the beginning of an underscore-separated - " word or number. - "call search( '\<\|\u', 'W' . l:direction ) - "call search( '\<\|\u\(\l\+\|\u\+\ze\u\)\|\d\+', 'W' . l:direction ) - "call search( '\<\|\u\(\l\+\|\u\+\ze\u\)\|\d\+\|_\zs\(\a\|\d\)\+', 'W' . l:direction ) - " beginning of ... - " word | empty line | non-keyword after whitespaces | non-whitespace after word | number | lowercase folowed by capital letter or number | ACRONYM followed by CamelCase or number | CamelCase | ACRONYM | underscore followed by ACRONYM, Camel, lowercase or number - call search( '\m\<\D\|^$\|\%(^\|\s\)\+\zs\k\@!\S\|\>\<\|\d\+\|\l\+\zs\%(\u\|\d\)\|\u\+\zs\%(\u\l\|\d\)\|\u\l\+\|\u\@<!\u\+\|[-_]\zs\%(\u\+\|\u\l\+\|\l\+\|\d\+\)', 'W' . l:direction) - " Note: word must be defined as '\<\D' to avoid that a word like - " 1234Test is moved over as [1][2]34[T]est instead of [1]234[T]est - " because \< matches with zero width, and \d\+ will then start - " matching '234'. To fix that, we make \d\+ be solely responsible - " for numbers by taken this away from \< via \<\D. (An alternative - " would be to replace \d\+ with \D\%#\zs\d\+, but that one is more - " complex.) All other branches are not affected, because they match - " multiple characters and not the same character multiple times. - endif - let l:i = l:i + 1 - endwhile + " CamelCase: Jump to beginning of either (start of word, Word, WORD, + " 123). + " Underscore_notation: Jump to the beginning of an underscore-separated + " word or number. + "call search( '\<\|\u', 'W' . l:direction ) + "call search( '\<\|\u\(\l\+\|\u\+\ze\u\)\|\d\+', 'W' . l:direction ) + "call search( '\<\|\u\(\l\+\|\u\+\ze\u\)\|\d\+\|_\zs\(\a\|\d\)\+', 'W' . l:direction ) + " beginning of ... + " word | empty line | non-keyword after whitespaces | non-whitespace after word | number | lowercase folowed by capital letter or number | ACRONYM followed by CamelCase or number | CamelCase | ACRONYM | underscore followed by ACRONYM, Camel, lowercase or number + call search( '\m\<\D\|^$\|\%(^\|\s\)\+\zs\k\@!\S\|\>\<\|\d\+\|\l\+\zs\%(\u\|\d\)\|\u\+\zs\%(\u\l\|\d\)\|\u\l\+\|\u\@<!\u\+\|[-_]\zs\%(\u\+\|\u\l\+\|\l\+\|\d\+\)', 'W' . l:direction) + " Note: word must be defined as '\<\D' to avoid that a word like + " 1234Test is moved over as [1][2]34[T]est instead of [1]234[T]est + " because \< matches with zero width, and \d\+ will then start + " matching '234'. To fix that, we make \d\+ be solely responsible + " for numbers by taken this away from \< via \<\D. (An alternative + " would be to replace \d\+ with \D\%#\zs\d\+, but that one is more + " complex.) All other branches are not affected, because they match + " multiple characters and not the same character multiple times. + endif + let l:i = l:i + 1 + endwhile endfunction function! camelcasemotion#Motion( direction, count, mode ) -"******************************************************************************* -"* PURPOSE: -" Perform the motion over CamelCaseWords or underscore_notation. -"* ASSUMPTIONS / PRECONDITIONS: -" none -"* EFFECTS / POSTCONDITIONS: -" Move cursor / change selection. -"* INPUTS: -" a:direction one of 'w', 'b', 'e' -" a:count number of "words" to move over -" a:mode one of 'n', 'o', 'v', 'iv' (latter one is a special visual mode -" when inside the inner "word" text objects. -"* RETURN VALUES: -" none -"******************************************************************************* - " Visual mode needs special preparations and postprocessing; - " normal and operator-pending mode breeze through to s:Move(). - - if a:mode == 'v' - " Visual mode was left when calling this function. Reselecting the current - " selection returns to visual mode and allows to call search() and issue - " normal mode motions while staying in visual mode. - normal! gv - endif - if a:mode == 'v' || a:mode == 'iv' + "******************************************************************************* + "* PURPOSE: + " Perform the motion over CamelCaseWords or underscore_notation. + "* ASSUMPTIONS / PRECONDITIONS: + " none + "* EFFECTS / POSTCONDITIONS: + " Move cursor / change selection. + "* INPUTS: + " a:direction one of 'w', 'b', 'e' + " a:count number of "words" to move over + " a:mode one of 'n', 'o', 'v', 'iv' (latter one is a special visual mode + " when inside the inner "word" text objects. + "* RETURN VALUES: + " none + "******************************************************************************* + " Visual mode needs special preparations and postprocessing; + " normal and operator-pending mode breeze through to s:Move(). - " Note_1a: - if &selection != 'exclusive' && a:direction == 'w' - normal! l - endif + if a:mode == 'v' + " Visual mode was left when calling this function. Reselecting the current + " selection returns to visual mode and allows to call search() and issue + " normal mode motions while staying in visual mode. + normal! gv + endif + if a:mode == 'v' || a:mode == 'iv' + " Note_1a: + if &selection != 'exclusive' && a:direction == 'w' + normal! l endif + endif - call s:Move( a:direction, a:count, a:mode ) + call s:Move( a:direction, a:count, a:mode ) - if a:mode == 'v' || a:mode == 'iv' - " Note: 'selection' setting. - if &selection == 'exclusive' && a:direction == 'e' - " When set to 'exclusive', the "forward to end" motion (',e') does not - " include the last character of the moved-over "word". To include that, an - " additional 'l' motion is appended to the motion; similar to the - " special treatment in operator-pending mode. - normal! l - elseif &selection != 'exclusive' && a:direction != 'e' - " Note_1b: - " The forward and backward motions move to the beginning of the next "word". - " When 'selection' is set to 'inclusive' or 'old', this is one character too far. - " The appended 'h' motion undoes this. Because of this backward step, - " though, the forward motion finds the current "word" again, and would - " be stuck on the current "word". An 'l' motion before the CamelCase - " motion (see Note_1a) fixes that. - normal! h - endif + if a:mode == 'v' || a:mode == 'iv' + " Note: 'selection' setting. + if &selection == 'exclusive' && (a:direction == 'e' || a:direction == 'ge') + " When set to 'exclusive', the "forward to end" motion (',e') does not + " include the last character of the moved-over "word". To include that, an + " additional 'l' motion is appended to the motion; similar to the + " special treatment in operator-pending mode. + normal! l + elseif &selection != 'exclusive' && a:direction != 'e' && a:direction == 'ge' + " Note_1b: + " The forward and backward motions move to the beginning of the next "word". + " When 'selection' is set to 'inclusive' or 'old', this is one character too far. + " The appended 'h' motion undoes this. Because of this backward step, + " though, the forward motion finds the current "word" again, and would + " be stuck on the current "word". An 'l' motion before the CamelCase + " motion (see Note_1a) fixes that. + normal! h endif + endif endfunction function! camelcasemotion#InnerMotion( direction, count ) - " If the cursor is positioned on the first character of a CamelWord, the - " backward motion would move to the previous word, which would result in a - " wrong selection. To fix this, first move the cursor to the right, so that - " the backward motion definitely will cover the current "word" under the - " cursor. - normal! l - - " Move "word" backwards, enter visual mode, then move "word" forward. This - " selects the inner "word" in visual mode; the operator-pending mode takes - " this selection as the area covered by the motion. - if a:direction == 'b' - " Do not do the selection backwards, because the backwards "word" motion - " in visual mode + selection=inclusive has an off-by-one error. - call camelcasemotion#Motion( 'b', a:count, 'n' ) - normal! v - " We decree that 'b' is the opposite of 'e', not 'w'. This makes more - " sense at the end of a line and for underscore_notation. - call camelcasemotion#Motion( 'e', a:count, 'iv' ) - else - call camelcasemotion#Motion( 'b', 1, 'n' ) - normal! v - call camelcasemotion#Motion( a:direction, a:count, 'iv' ) - endif + " If the cursor is positioned on the first character of a CamelWord, the + " backward motion would move to the previous word, which would result in a + " wrong selection. To fix this, first move the cursor to the right, so that + " the backward motion definitely will cover the current "word" under the + " cursor. + normal! l + + " Move "word" backwards, enter visual mode, then move "word" forward. This + " selects the inner "word" in visual mode; the operator-pending mode takes + " this selection as the area covered by the motion. + if a:direction == 'b' + " Do not do the selection backwards, because the backwards "word" motion + " in visual mode + selection=inclusive has an off-by-one error. + call camelcasemotion#Motion( 'b', a:count, 'n' ) + normal! v + " We decree that 'b' is the opposite of 'e', not 'w'. This makes more + " sense at the end of a line and for underscore_notation. + call camelcasemotion#Motion( 'e', a:count, 'iv' ) + else + call camelcasemotion#Motion( 'b', 1, 'n' ) + normal! v + call camelcasemotion#Motion(a:direction, a:count, 'iv') + endif endfunction -" vim: set sts=4 sw=4 noexpandtab ff=unix fdm=syntax : +" vim: set sts=2 sw=2 expandtab ff=unix fdm=syntax : |