Defer escape bindings as well

This allows rebinding escape in the user list without breaking e.g.
arrow keys (which send escape and then `[A` and similar, so escape is
a prefix of them).

Fixes #8428.
This commit is contained in:
Fabian Homborg 2021-11-10 20:39:28 +01:00
parent 197f93e784
commit aa470e12b2
2 changed files with 28 additions and 1 deletions

View File

@ -597,6 +597,7 @@ maybe_t<input_mapping_t> inputter_t::find_mapping(event_queue_peeker_t *peeker)
const input_mapping_t *generic = nullptr;
const auto &vars = parser_->vars();
const wcstring bind_mode = input_get_bind_mode(vars);
const input_mapping_t *escape = nullptr;
auto ml = input_mappings()->all_mappings();
for (const auto &m : *ml) {
@ -611,10 +612,25 @@ maybe_t<input_mapping_t> inputter_t::find_mapping(event_queue_peeker_t *peeker)
}
if (try_peek_sequence(peeker, m.seq)) {
return m;
// A binding for just escape should also be deferred
// so escape sequences take precedence.
if (m.seq == L"\x1B") {
if (!escape) {
escape = &m;
}
} else {
return m;
}
}
peeker->restart();
}
if (escape) {
// We need to reconsume the escape.
peeker->next();
return *escape;
}
return generic ? maybe_t<input_mapping_t>(*generic) : none();
}

View File

@ -319,6 +319,17 @@ send("\x07") # ctrl-g, kill bigword
sendline("echo")
expect_prompt("\nb c d")
# Test that overriding the escape binding works
# and does not inhibit other escape sequences (up-arrow in this case).
sendline("bind \\x1b 'echo foo'")
expect_prompt()
send("\x1b")
expect_str("foo")
send("\x1b[A")
expect_str("bind \\x1b 'echo foo'")
sendline("")
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")