Permalink
Browse files

Version 1.52

- FIX: Correct forward-to-end motion over lowercase part in "lowerCamel". Found this by chance in GitHub fork by Kevin Lee (bkad).
- BUG: Correct wrong stop on second letter of ACRONYM at the beginning of a word "AXBCText".
- The motion functionality is automatically tested via a runVimTests (vimscript #2565) test suite.
  • Loading branch information...
Ingo Karkat authored and vim-scripts committed Nov 12, 2011
1 parent e810454 commit 8db17bdee3f42bd71839ead2a84b2ee1916e45c2
Showing with 99 additions and 49 deletions.
  1. +2 −2 README
  2. +15 −5 autoload/camelcasemotion.vim
  3. +70 −33 doc/camelcasemotion.txt
  4. +12 −9 plugin/camelcasemotion.vim
View
4 README
@@ -8,7 +8,7 @@ for identifiers. The best way to navigate inside those identifiers using Vim
built-in motions is the [count]f{char} motion, i.e. f{uppercase-char} or f_,
respectively. But we can make this easier:
This script defines motions ',w', ',b' and ',e' (similar to 'w', 'b', 'e'),
This plugin defines motions ',w', ',b' and ',e' (similar to 'w', 'b', 'e'),
which do not move word-wise (forward/backward), but Camel-wise; i.e. to word
boundaries and uppercase letters. The motions also work on underscore notation,
where words are delimited by underscore ('_') characters. From here on, both
@@ -18,7 +18,7 @@ over multiple "words" at once. Outside of "words" (e.g. in non-keyword
characters like // or ;), the new motions move just like the regular motions.
Vim provides a built-in 'iw' text object called 'inner word', which works in
operator-pending and visual mode. Analog to that, this script defines inner
operator-pending and visual mode. Analog to that, this plugin defines inner
"word" motions 'i,w', 'i,b' and 'i,e', which select the "word" (or multiple
"words" if a [count] is given) where the cursor is located.
@@ -3,11 +3,16 @@
" DEPENDENCIES:
" - Requires Vim 7.0 or higher.
"
" Copyright: (C) 2007-2009 by Ingo Karkat
" Copyright: (C) 2007-2011 Ingo Karkat
" The VIM LICENSE applies to this script; see ':help copyright'.
"
" Maintainer: Ingo Karkat <ingo@karkat.de>
" REVISION DATE REMARKS
" 1.52.002 18-Oct-2011 FIX: Correct forward-to-end motion over
" lowercase part in "lowerCamel". Found this by
" chance in GitHub fork by Kevin Lee (bkad).
" BUG: Correct wrong stop on second letter of
" ACRONYM at the beginning of a word "AXBCText".
" 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
@@ -31,8 +36,11 @@ function! s:Move( direction, count, mode )
" "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( '\d\+\|\u\+\ze\%(\u\l\|\d\)\|\u\l\+\|\%(\a\|\d\)\+\ze_\|\%(\k\@!\S\)\+\|\%(_\@!\k\)\+\>', 'We' )
" number | ACRONYM followed by CamelCase or number | lowercase followed by CamelCase, ACRONYM, or number | CamelCase | underscore_notation | non-keyword | word
" Note: Branches are ordered from specific to unspecific so that
" in case of multiple matches, the more specific (and usually
" longer) one it used.
call search( '\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:
@@ -73,8 +81,10 @@ function! s:Move( direction, count, mode )
"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 | ACRONYM followed by CamelCase or number | CamelCase | underscore followed by ACRONYM, Camel, lowercase or number
call search( '\<\D\|^$\|\%(^\|\s\)\+\zs\k\@!\S\|\>\S\|\d\+\|\u\+\ze\%(\u\l\|\d\)\|\u\l\+\|_\zs\%(\u\+\|\u\l\+\|\l\+\|\d\+\)', 'W' . l:direction )
" word | empty line | non-keyword after whitespaces | non-whitespace after word | number | start of ACRONYM followed by CamelCase or number | CamelCase | underscore followed by ACRONYM, Camel, lowercase or number
" Note: Branches are ordered from unspecific to specific, so that
" the cursor moves the least amount of text.
call search( '\<\D\|^$\|\%(^\|\s\)\+\zs\k\@!\S\|\>\S\|\d\+\|\u\@<!\u\+\ze\%(\u\l\|\d\)\|\u\l\+\|_\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
View
@@ -3,9 +3,9 @@
CAMEL CASE MOTION by Ingo Karkat
*camelcasemotion.vim*
description |camelcasemotion-description|
usage |camelcasemotion-usage|
installation |camelcasemotion-installation|
configuration |camelcasemotion-configuration|
usage |camelcasemotion-usage|
installation |camelcasemotion-installation|
configuration |camelcasemotion-configuration|
known problems |camelcasemotion-known-problems|
todo |camelcasemotion-todo|
history |camelcasemotion-history|
@@ -20,7 +20,7 @@ for identifiers. The best way to navigate inside those identifiers using Vim
built-in motions is the [count]f{char} motion, i.e. f{uppercase-char} or f_,
respectively. But we can make this easier:
This script defines motions|,w|,|,b| and|,e|(similar to |w|,|b|,|e|), which do
This plugin defines motions |,w| |,b| and |,e| (similar to |w| |b| |e|), which do
not move word-wise (forward/backward), but Camel-wise; i.e. to word boundaries
and uppercase letters. The motions also work on underscore notation, where
words are delimited by underscore ('_') characters. From here on, both
@@ -29,17 +29,17 @@ double quotes). Just like with the regular motions, a [count] can be prepended
to move over multiple "words" at once. Outside of "words" (e.g. in non-keyword
characters like // or ;), the new motions move just like the regular motions.
Vim provides a built-in|iw|text object called 'inner word', which works in
operator-pending and visual mode. Analog to that, this script defines inner
"word" motions |i,w|,|i,b| and|i,e|, which select the "word" (or multiple
Vim provides a built-in |iw| text object called 'inner word', which works in
operator-pending and visual mode. Analog to that, this plugin defines inner
"word" motions |i,w| |i,b| and |i,e|, which select the "word" (or multiple
"words" if a [count] is given) where the cursor is located.
==============================================================================
USAGE *camelcasemotion-usage*
*,w* *,b* *,e*
Use the new motions|,w|,|,b| and|,e| in normal mode, operator-pending mode
(cp.|operator|), and visual mode. For example, type 'bc,w' to change 'Camel'
in 'CamelCase' to something else.
Use the new motions |,w| |,b| and |,e| in normal mode, operator-pending mode
(cp. |operator|), and visual mode. For example, type bc,w to change "Camel"
in "CamelCase" to something else.
EXAMPLE: motions
@@ -70,13 +70,13 @@ gU3i,w to upper-case, and so on.
==============================================================================
INSTALLATION *camelcasemotion-installation*
This script is packaged as a|vimball|. If you have the "gunzip" decompressor
This script is packaged as a |vimball|. If you have the "gunzip" decompressor
in your PATH, simply edit the *.vba.gz package in Vim; otherwise, decompress
the archive first, e.g. using WinZip. Inside Vim, install by sourcing the
vimball or via the|:UseVimball|command. >
vimball or via the |:UseVimball| command. >
vim camelcasemotion.vba.gz
:so %
To uninstall, use the|:RmVimball|command.
To uninstall, use the |:RmVimball| command.
DEPENDENCIES *camelcasemotion-dependencies*
@@ -85,26 +85,37 @@ DEPENDENCIES *camelcasemotion-dependencies*
==============================================================================
CONFIGURATION *camelcasemotion-configuration*
By default, all mappings start with |,| (comma) as the map leader instead of
using <Leader>. I personally find the default <Leader> key too far off the
keyboard to be useful for custom motions (which also cannot be repeated via
the |.| (dot) command, so they should be very fast to type repeatedly), but
quite suitable for general, less frequently used custom mappings.
To avoid losing the (rarely used) |,| mapping (which repeats latest f, t, F or
T in opposite direction), you can remap it to ,,: >
nnoremap ,, ,
xnoremap ,, ,
onoremap ,, ,
If you want to use different mappings, map your keys to the
<Plug>CamelCaseMotion_? mapping targets _before_ sourcing this script (e.g. in
your|vimrc|).
your |vimrc|).
EXAMPLE: Replace the default|w|,|b| and|e| mappings instead of defining
additional mappings|,w|,|,b| and|,e|: >
map <silent> w <Plug>CamelCaseMotion_w
map <silent> b <Plug>CamelCaseMotion_b
map <silent> e <Plug>CamelCaseMotion_e
EXAMPLE: Replace the default |w|, |b| and |e| mappings instead of defining
additional mappings |,w|, |,b| and |,e| : >
map w <Plug>CamelCaseMotion_w
map b <Plug>CamelCaseMotion_b
map e <Plug>CamelCaseMotion_e
sunmap w
sunmap b
sunmap e
EXAMPLE: Replace default|iw|text-object and define|ib|and |ie|motions: >
omap <silent> iw <Plug>CamelCaseMotion_iw
xmap <silent> iw <Plug>CamelCaseMotion_iw
omap <silent> ib <Plug>CamelCaseMotion_ib
xmap <silent> ib <Plug>CamelCaseMotion_ib
omap <silent> ie <Plug>CamelCaseMotion_ie
xmap <silent> ie <Plug>CamelCaseMotion_ie
EXAMPLE: Replace default |iw| text-object and define |ib| and |ie| motions: >
omap iw <Plug>CamelCaseMotion_iw
xmap iw <Plug>CamelCaseMotion_iw
omap ib <Plug>CamelCaseMotion_ib
xmap ib <Plug>CamelCaseMotion_ib
omap ie <Plug>CamelCaseMotion_ie
xmap ie <Plug>CamelCaseMotion_ie
==============================================================================
KNOWN PROBLEMS *camelcasemotion-known-problems*
@@ -116,7 +127,8 @@ KNOWN PROBLEMS *camelcasemotion-known-problems*
CamelCaseWords, anyway.
- The operator-pending and visual mode ,e mapping doesn't work properly when
it reaches the end of the buffer; the final character of the moved-over
"word" remains. As a workaround, use the default 'e' motion instead of ',e'.
"word" remains, and a beep is issued. As a workaround, use the default 'e'
motion instead of ',e'.
- When the Vim setting 'selection' is not set to "exclusive", a
forward-backward combination in visual mode (e.g. 'v,w,b') selects one
additional character to the left, instead of only the character where the
@@ -126,15 +138,40 @@ KNOWN PROBLEMS *camelcasemotion-known-problems*
==============================================================================
TODO *camelcasemotion-todo*
IDEAS *camelcasemotion-ideas*
- Use search('\%#.\%$', 'cnW') to detect the operator-pending motion to the
end of the buffer and temporarily append a new line / space character to
work around the end-of-buffer problem. Unfortunately, the addition cannot be
undone as part of the motion (won't work then), so we'd have to use an
autocmd to remove it later.
- Make separator character (currently underscore) configurable so that dashes,
asterisks, etc. can be added as well. Idea is to replace the single /_/ with
a collection /[-_*]/ built from g:CamelCaseMotion_SeparatorCharacters. Check
out interference with containment in 'iskeyword' and think through need to
buffer-local setting. (Submitted anonymously 13-Nov-2010 on Vim Tips Wiki.)
==============================================================================
HISTORY *camelcasemotion-history*
1.52 12-Nov-2011
- FIX: Correct forward-to-end motion over lowercase part in "lowerCamel".
Found this by chance in GitHub fork by Kevin Lee (bkad).
- BUG: Correct wrong stop on second letter of ACRONYM at the beginning of a
word "AXBCText".
- The motion functionality is automatically tested via a runVimTests
(vimscript #2565) test suite.
1.51 30-Sep-2011
Use <silent> for <Plug> mapping instead of default mapping.
1.50 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. Now using :xmap to only target visual mode.
- Do not create mappings for select mode; according to |Select-mode|,
printable character commands should delete the selection and insert the
typed characters. Now using :xmap to only target visual mode.
- Moved functions from plugin to separate autoload script.
- Split off documentation into separate help file.
- Split off documentation into separate help file. Now packaging as VimBall.
1.40 30-Jun-2008
BF: Now using :normal! to be independent from any user mappings. Thanks to
@@ -175,8 +212,8 @@ First published version.
Started development based on vimtip #1016 by Anthony Van Ham.
==============================================================================
Copyright: (C) 2007-2009 by Ingo Karkat
The VIM LICENSE applies to this script; see|copyright|.
Copyright: (C) 2007-2011 Ingo Karkat
The VIM LICENSE applies to this script; see |copyright|.
Maintainer: Ingo Karkat <ingo@karkat.de>
==============================================================================
View
@@ -2,13 +2,16 @@
"
" DEPENDENCIES:
" - Requires Vim 7.0 or higher.
" - camelcasemotion.vim autoload script.
"
" Copyright: (C) 2007-2009 by Ingo Karkat
" Copyright: (C) 2007-2011 Ingo Karkat
" The VIM LICENSE applies to this script; see ':help copyright'.
"
" Source: Based on vimtip #1016 by Anthony Van Ham.
" Maintainer: Ingo Karkat <ingo@karkat.de>
" REVISION DATE REMARKS
" 1.51.020 30-Sep-2011 Use <silent> for <Plug> mapping instead of
" default mapping.
" 1.50.019 05-May-2009 Do not create mappings for select mode;
" according to|Select-mode|, printable character
" commands should delete the selection and insert
@@ -149,17 +152,17 @@ function! s:CreateMotionMappings()
" Create mappings according to this template:
" (* stands for the mode [nov], ? for the underlying motion [wbe].)
"
" *noremap <Plug>CamelCaseMotion_? :<C-U>call camelcasemotion#Motion('?',v:count1,'*')<CR>
" *noremap <silent> <Plug>CamelCaseMotion_? :<C-U>call camelcasemotion#Motion('?',v:count1,'*')<CR>
" if ! hasmapto('<Plug>CamelCaseMotion_?', '*')
" *map <silent> ,? <Plug>CamelCaseMotion_?
" *map ,? <Plug>CamelCaseMotion_?
" endif
for l:mode in ['n', 'o', 'v']
for l:motion in ['w', 'b', 'e']
let l:targetMapping = '<Plug>CamelCaseMotion_' . l:motion
execute l:mode . 'noremap ' . l:targetMapping . ' :<C-U>call camelcasemotion#Motion(''' . l:motion . ''',v:count1,''' . l:mode . ''')<CR>'
execute l:mode . 'noremap <silent> ' . l:targetMapping . ' :<C-U>call camelcasemotion#Motion(''' . l:motion . ''',v:count1,''' . l:mode . ''')<CR>'
if ! hasmapto(l:targetMapping, l:mode)
execute (l:mode ==# 'v' ? 'x' : l:mode) . 'map <silent> ,' . l:motion . ' ' . l:targetMapping
execute (l:mode ==# 'v' ? 'x' : l:mode) . 'map ,' . l:motion . ' ' . l:targetMapping
endif
endfor
endfor
@@ -179,17 +182,17 @@ function! s:CreateInnerMotionMappings()
" Create mappings according to this template:
" (* stands for the mode [ov], ? for the underlying motion [wbe].)
"
" *noremap <Plug>CamelCaseMotion_i? :<C-U>call camelcasemotion#InnerMotion('?',v:count1)<CR>
" *noremap <silent> <Plug>CamelCaseMotion_i? :<C-U>call camelcasemotion#InnerMotion('?',v:count1)<CR>
" if ! hasmapto('<Plug>CamelCaseInnerMotion_i?', '*')
" *map <silent> i,? <Plug>CamelCaseInnerMotion_i?
" *map i,? <Plug>CamelCaseInnerMotion_i?
" endif
for l:mode in ['o', 'v']
for l:motion in ['w', 'b', 'e']
let l:targetMapping = '<Plug>CamelCaseMotion_i' . l:motion
execute l:mode . 'noremap ' . l:targetMapping . ' :<C-U>call camelcasemotion#InnerMotion(''' . l:motion . ''',v:count1)<CR>'
execute l:mode . 'noremap <silent> ' . l:targetMapping . ' :<C-U>call camelcasemotion#InnerMotion(''' . l:motion . ''',v:count1)<CR>'
if ! hasmapto(l:targetMapping, l:mode)
execute (l:mode ==# 'v' ? 'x' : l:mode) . 'map <silent> i,' . l:motion . ' ' . l:targetMapping
execute (l:mode ==# 'v' ? 'x' : l:mode) . 'map i,' . l:motion . ' ' . l:targetMapping
endif
endfor
endfor

0 comments on commit 8db17bd

Please sign in to comment.