Fix cW Vi mode regression deleting trailing space

Missed in 02c0455 (Fix Vi mode cw deleting trailing whitespace, 2026-02-12),

Closes #12790
Closes #12791
This commit is contained in:
Sean Reifschneider
2026-05-29 09:24:50 -06:00
committed by Johannes Altmanninger
parent cb2f279550
commit eb535322d0
4 changed files with 8 additions and 11 deletions

View File

@@ -28,7 +28,8 @@ For distributors and developers
Regression fixes:
-----------------
- (from 4.4) Vi mode ``x`` in :doc:`builtin read <cmds/read>` (:issue:`12724`).
- (from 4.4.0) Vi mode ``c,W`` key binding wrongly deleted trailing spaces (:issue:`12790`).
- (from 4.4.0) Vi mode ``x`` in :doc:`builtin read <cmds/read>` (:issue:`12724`).
- (from 4.3.3) Repeated tab would sometimes insert smartcase completions redundantly.
fish 4.7.1 (released May 08, 2026)

View File

@@ -32,11 +32,6 @@ Fish's vi mode aims to be familiar to vim users, but there are some differences:
**Word character handling**
In vim, underscore (``_``) is treated as a keyword character by default, so word motions like ``w``, ``b``, and ``e`` treat ``foo_bar`` as a single word. In fish, underscore is treated as punctuation, so word motions stop at underscores. For example, pressing ``w`` on ``foo_bar`` in fish stops at the ``_``, while in vim it would jump past the entire identifier.
**The** ``cw`` **command**
In vim, ``cw`` has special behavior: when the cursor is on a non-space character, it behaves like ``ce`` (change to end of word), but when the cursor is on a space, it behaves like ``dwi`` (delete word then insert).
In fish, ``cw`` always behaves like ``dwi`` - it deletes to the start of the next word (including trailing whitespace), then enters insert mode. To get vim's ``cw`` behavior in fish, use ``ce`` instead.
Examples
--------

View File

@@ -151,10 +151,11 @@ function fish_vi_exec_motion
end
case change
switch $motion[1]
case kill-word-vi
case kill-word-vi kill-bigword-vi
set -l end_kill (string replace -- -vi '' $motion[1])
for i in $seq_total
if test $i -eq $total
commandline -f kill-word
commandline -f $end_kill
else
$motion_cmd
end

View File

@@ -474,15 +474,15 @@ expect_prompt(
"\r\n.*XXX def\r\n", unmatched="vi mode 'ce' should change to end of word"
)
# Test 'cW' - change WORD, deletes to start of next WORD (like vim's 'dW')
# Test 'cW' - change WORD, changes to end of WORD keeping trailing space (like 'cE')
send("echo abc-def ghi")
send("\033")
sleep(0.200)
send(
"0wcWXXX\r"
) # Move to 'abc-def', 'cW' deletes 'abc-def ' (including space), type 'XXX'
) # Move to 'abc-def', 'cW' changes 'abc-def' (not the space), type 'XXX'
expect_prompt(
"\r\n.*XXXghi\r\n", unmatched="vi mode 'cW' should delete to start of next WORD"
"\r\n.*XXX ghi\r\n", unmatched="vi mode 'cW' should change to end of WORD"
)
# Test 'cE' - change to end of WORD (like vim's 'dE')