Fix bigword bindings with single-character words

With a commandline like

```
a b c d
```

and the cursor at the beginning, this would eat "a b", which isn't a
sensible bigword.

Bigword should be "a word, with optional leading whitespace".

This was caused by an overly zealous state-machine that always ate one
char and only *then* started eating leading whitespace.

Instead eat *a character*, and if it was whitespace go on eating
whitespace, and if it was a printable go straight to only eating
printables.

Fixes #7325.
This commit is contained in:
Fabian Homborg 2020-09-11 20:13:06 +02:00
parent d688093f7a
commit 0e9b496bba
2 changed files with 21 additions and 1 deletions

View File

@ -807,6 +807,7 @@ bool move_word_state_machine_t::consume_char_path_components(wchar_t c) {
}
bool move_word_state_machine_t::consume_char_whitespace(wchar_t c) {
// Consume a "word" of printable characters plus any leading whitespace.
enum { s_always_one = 0, s_blank, s_graph, s_end };
bool consumed = false;
@ -814,7 +815,13 @@ bool move_word_state_machine_t::consume_char_whitespace(wchar_t c) {
switch (state) {
case s_always_one: {
consumed = true; // always consume the first character
state = s_blank;
// If it's a graphical char, only consume those from here.
if (iswgraph(c)) {
state = s_graph;
} else {
// If it's whitespace, keep consuming whitespace until the graphs.
state = s_blank;
}
break;
}
case s_blank: {

View File

@ -276,3 +276,16 @@ sendline("bind q self-insert-notfirst")
expect_prompt()
sendline("qqqecho qqq")
expect_prompt("qqq", unmatched="Leading qs not stripped")
# Test bigword with single-character words.
sendline("bind \cg kill-bigword")
expect_prompt()
send("a b c d\x01") # ctrl-a, move back to the beginning of the line
send("\x07") # ctrl-g, kill bigword
sendline("echo")
expect_prompt("^b c d")
send(" a b c d\x01") # ctrl-a, move back to the beginning of the line
send("\x07") # ctrl-g, kill bigword
sendline("echo")
expect_prompt("^b c d")