Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 18 additions & 14 deletions autoload/wordmotion.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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
Expand All @@ -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

Expand Down
11 changes: 11 additions & 0 deletions tests/cpoptions.vader
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
25 changes: 20 additions & 5 deletions tests/cw.vader
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down