On Sun, Oct 22, 2017 at 10:15:54PM -0400, Aron Griffis wrote: [...] > Thanks Eduardo. The clue there about bind-tty-special-chars is helpful, > since previously I hadn't been able to make unix-word-rubout work either! > > However this doesn't seem to explain the case where ctrl-w doesn't work at > all, which is the bug I'm reporting.
Yes, you're right. I'm looking at the POSIX specification for the shell vi-mode: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html#tag_20_117_13_03 (emphasis is mine) | <control>-W | Delete the characters from /the one preceding the cursor/ to the preceding | word boundary. The word boundary in this case is the closer to the cursor of | either the beginning of the line or a character that is in neither the blank | nor punct character classification of the current locale. And function `rl_vi_unix_word_rubout': | dualbus@ubuntu:~/src/gnu/bash/lib/readline$ cat -n vi_mode.c | sed -n 1601,1605p | 1601 /* If we're at the start of a word, move back to word boundary so we | 1602 move back to the `preceding' word */ | 1603 if (rl_point > 0 && (vi_unix_word_boundary (rl_line_buffer[rl_point]) == 0) && | 1604 vi_unix_word_boundary (rl_line_buffer[rl_point - 1])) | 1605 rl_point--; So if we have: v-- cursor here >>true --foo=bar<< ^-- character preceding the cursor Then: - rl_line_buffer[rl_point] -> `=' & vi_unix_word_boundary(...) -> 1 - rl_line_buffer[rl_point - 1] -> `o' & vi_unix_word_boundary(...) -> 0 So the test in lines 1603-1604 fails, and rl_point is not decreased. According to my reading of the standard, it should decrease rl_point unconditionally. See my proposed fix below. diff --git a/lib/readline/vi_mode.c b/lib/readline/vi_mode.c index 3cb7e8c9..238a77e9 100644 --- a/lib/readline/vi_mode.c +++ b/lib/readline/vi_mode.c @@ -1598,10 +1598,8 @@ rl_vi_unix_word_rubout (int count, int key) while (--rl_point > 0 && whitespace (rl_line_buffer[rl_point])) ; - /* If we're at the start of a word, move back to word boundary so we - move back to the `preceding' word */ - if (rl_point > 0 && (vi_unix_word_boundary (rl_line_buffer[rl_point]) == 0) && - vi_unix_word_boundary (rl_line_buffer[rl_point - 1])) + /* We start deleting at the character preceding the cursor */ + if (rl_point > 0) rl_point--; /* If we are at a word boundary (whitespace/punct), move backward
signature.asc
Description: PGP signature