diff --git a/src/input.cpp b/src/input.cpp index 0a4d08a0c..58e98cdf8 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -597,6 +597,7 @@ maybe_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 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(*generic) : none(); } diff --git a/tests/pexpects/bind.py b/tests/pexpects/bind.py index acad9373c..841eae959 100644 --- a/tests/pexpects/bind.py +++ b/tests/pexpects/bind.py @@ -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")