summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTim Allen <screwtape@froup.com>2020-11-24 19:14:04 +1100
committerTim Allen <screwtape@froup.com>2021-01-15 18:49:53 +1100
commita7ed1f03fbe8a65a5ab33fbbb5f8a4e5a475a7a2 (patch)
tree2dd5e2f123646d1f7991b8f87e20a58d567300f4 /src
parentdf7b33bc7b9da897d1d0127b54ae1e629d2334ff (diff)
Distinguish <c-h> and Backspace on terminals where that is possible.
Different terminals send different codes to indicate backspace, usually one of \x08 or \x7f, so Kakoune blindly treated both as backspace. However, a given terminal is only likely to use one of those, and mnemonic control codes like <c-h> are a precious resource so we should endeavour to keep backspace and <c-h> separate when we can. Luckily, termios tells us what code our terminal is currently using, and Kakoune already reads the information at startup, so we can just use that information. Thanks to @krobelus for figuring out the C++ syntax required. Fixes #3863.
Diffstat (limited to 'src')
-rw-r--r--src/ncurses_ui.cc11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc
index e52748c9..812e1612 100644
--- a/src/ncurses_ui.cc
+++ b/src/ncurses_ui.cc
@@ -610,16 +610,19 @@ Optional<Key> NCursesUI::get_next_key()
if (not c)
return {};
- static constexpr auto convert = [](Codepoint c) -> Codepoint {
+ const cc_t erase = m_original_termios.c_cc[VERASE];
+ auto convert = [erase](Codepoint c) -> Codepoint {
if (c == control('m') or c == control('j'))
return Key::Return;
if (c == control('i'))
return Key::Tab;
- if (c == control('h') or c == 127)
+ if (c == erase)
return Key::Backspace;
+ if (c == 127) // when it's not backspace
+ return Key::Delete;
return c;
};
- auto parse_key = [](unsigned char c) -> Key {
+ auto parse_key = [&convert](unsigned char c) -> Key {
if (Codepoint cp = convert(c); cp > 255)
return Key{cp};
if (c == control('z'))
@@ -652,7 +655,7 @@ Optional<Key> NCursesUI::get_next_key()
return Key{utf8::codepoint(CharIterator{c}, Sentinel{})};
};
- auto parse_csi = [this]() -> Optional<Key> {
+ auto parse_csi = [this, &convert]() -> Optional<Key> {
auto next_char = [] { return get_char().value_or((unsigned char)0xff); };
int params[16] = {};
auto c = next_char();