From 92d324e2a105731d23dcb6bda4547cde14e67f6d Mon Sep 17 00:00:00 2001 From: Edward Fernandez Date: Wed, 22 Oct 2025 10:50:17 +0900 Subject: [PATCH 1/2] Consider punctuation when moving forward Adding these two entries to forward_to_next_list should cause forward motion to additionally stop at punctuation. This prevents the occasional undesired behavior of consuming punctuation when using dw or cw. Tested using Neovim v0.11.4 --- autoload/camelcasemotion.vim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/autoload/camelcasemotion.vim b/autoload/camelcasemotion.vim index 7a9bd61..18c0e7e 100644 --- a/autoload/camelcasemotion.vim +++ b/autoload/camelcasemotion.vim @@ -32,6 +32,8 @@ let s:forward_to_next_list = [] call add(s:forward_to_next_list, '<\D') " word call add(s:forward_to_next_list, '^$') " empty line call add(s:forward_to_next_list, '%(^|\s)+\zs\k@!\S') " non-keyword after whitespaces +call add(s:forward_to_next_list, '>\zs\k@!\S') " punctuation right after a word 10/22/2025 Strike-F8 +call add(s:forward_to_next_list, '\k@!\S\ze<') " punctuation right before a word 10/22/2025 Strike-F8 call add(s:forward_to_next_list, '><') " non-whitespace after word call add(s:forward_to_next_list, '[\{\}\[\]\(\)\<\>\&"'."'".']') " brackets, parens, braces, quotes call add(s:forward_to_next_list, '\d+') " number From 921d00a2ac4dfe30ce2ee63aa213d5dfddb66637 Mon Sep 17 00:00:00 2001 From: Edward Fernandez Date: Wed, 5 Nov 2025 13:57:26 +0900 Subject: [PATCH 2/2] Improve dw motion Ensure that dw deletes the last character of the last word of the line without touching the next line. CamelCaseMotion was inconsistently grabbing the next line when deleting the last word of the line but this should prevent that from happening. --- autoload/camelcasemotion.vim | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/autoload/camelcasemotion.vim b/autoload/camelcasemotion.vim index 18c0e7e..d98de1f 100644 --- a/autoload/camelcasemotion.vim +++ b/autoload/camelcasemotion.vim @@ -89,7 +89,38 @@ function! s:Move(direction, count, mode) let l:direction = (a:direction == 'w' ? '' : a:direction) + let l:pos_before = getpos('.') call search(s:forward_to_next, 'W' . l:direction) + " Ensure the last character of the last word of the line is + " deleted without affecting the next line when using dw + " This should mirror default vim behavior + if a:mode == 'o' && a:direction == 'w' && l:i == a:count - 1 + let l:pos_after = getpos('.') + if l:pos_after[1] == l:pos_before[1] + let l:line_text = getline(l:pos_after[1]) + let l:last_col = len(l:line_text) + let l:save_ve = &virtualedit + let l:ve_changed = 0 + while l:pos_after[2] <= l:last_col + \ && matchstr(l:line_text, '\%' . l:pos_after[2] . 'c.') =~# '\k@!\S' + if l:pos_after[2] == l:last_col && !l:ve_changed + if empty(l:save_ve) + set virtualedit=onemore + elseif l:save_ve !~# '\' + execute 'set virtualedit=' . l:save_ve . ',onemore' + endif + let l:ve_changed = 1 + endif + normal! l + let l:pos_after = getpos('.') + let l:line_text = getline(l:pos_after[1]) + let l:last_col = len(l:line_text) + endwhile + if l:ve_changed + let &virtualedit = l:save_ve + endif + endif + endif " 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