diff --git a/autoload/wordmotion.vim b/autoload/wordmotion.vim index 9db0333..3de792b 100644 --- a/autoload/wordmotion.vim +++ b/autoload/wordmotion.vim @@ -87,13 +87,19 @@ function wordmotion#motion(count, mode, flags, uppercase, extra, ...) set cpoptions+=c let l:flags = a:flags + let l:s = a:uppercase ? s:us : s:s - if a:mode == 'o' && v:operator == 'c' && l:flags == '' - " special case (see :help cw) - let l:flags = 'e' - let l:cw = 1 - else - let l:cw = 0 + " cw special case + " see :help cw, :help cpo-z (vim), :help cpo-_ (neovim) + let l:cpo_z = has('nvim') ? stridx(l:cpo, '_') : stridx(l:cpo, 'z') + let l:cw_special_case = 0 + + if l:cpo_z != -1 && a:mode == 'o' && v:operator == 'c' && l:flags == '' + let l:cursor_on_s = getline('.') =~# '\%.c' . l:s + if !l:cursor_on_s + let l:flags = 'e' + let l:cw_special_case = 1 + endif endif if a:mode == 'x' @@ -114,7 +120,7 @@ function wordmotion#motion(count, mode, flags, uppercase, extra, ...) let l:pos = getpos('.') let l:count = a:count - if l:cw + if l:cw_special_case " cw on the last character of a word will match the cursor position call search('\m'.l:pattern, l:flags.'cW') let l:count -= 1 @@ -124,19 +130,17 @@ function wordmotion#motion(count, mode, flags, uppercase, extra, ...) let l:count -= 1 endwhile - " dw at the end of a line should not consume the newline or leading white - " space on the next line - let l:is_dw = a:mode == 'o' && v:operator == 'd' && l:flags == '' + " operator-pending w at the end of a line should not include the newline or leading + " white space on the next line let l:next_line = l:pos[1] < getpos('.')[1] - if l:is_dw && l:next_line - let l:s = a:uppercase ? s:us : s:s + if a:mode == 'o' && l:flags == '' && l:next_line " newline, leading whitespace, cursor if search('\m\n\%('.l:s.'\)*\%#', 'bW') != 0 - let l:dwpos = getpos('.') + let l:wpos = getpos('.') " need to make range inclusive call setpos('.', l:pos) normal! v - call setpos('.', l:dwpos) + call setpos('.', l:wpos) endif endif diff --git a/tests/cpoptions.vader b/tests/cpoptions.vader index 4bc3683..ce491bc 100644 --- a/tests/cpoptions.vader +++ b/tests/cpoptions.vader @@ -28,6 +28,17 @@ Execute (w with cpo-<): normal w AssertEqual 5, col('.') +Execute (cw without cpo-z): + if has('nvim') + set cpoptions-=_ + else + set cpoptions-=z + endif + normal cw + +Expect (Delete the space): + bar + Given (Leading spaces): foo diff --git a/tests/cw.vader b/tests/cw.vader index 06d4ec1..bb944b5 100644 --- a/tests/cw.vader +++ b/tests/cw.vader @@ -262,18 +262,33 @@ Then (Assert that cursor is at z): Expect ("b c\nd e" changed to z): a z f +Given (Snake case word): + foo_bar + +Execute (cw on underscore): + normal lllcw + AssertEqual 3, col('.') + +Expect (Only underscore deleted): + foobar + Given (Leading spaces): foo + bar -Execute (FIXME: cw): - normal cw +Execute (cw): + normal jcw AssertEqual 1, col('.') Expect (Leading spaces deleted): - foo + foo + bar -Execute (reference cw): - normal! cw +Given (Leading spaces with only 1 line): + foo + +Execute (cw at the first line and col of the file): + normal cw AssertEqual 1, col('.') Expect (Leading spaces deleted):