From a7ed1f03fbe8a65a5ab33fbbb5f8a4e5a475a7a2 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Tue, 24 Nov 2020 19:14:04 +1100 Subject: [PATCH] Distinguish 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 are a precious resource so we should endeavour to keep backspace and 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. --- src/ncurses_ui.cc | 11 +++++++---- 1 file 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 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 NCursesUI::get_next_key() return Key{utf8::codepoint(CharIterator{c}, Sentinel{})}; }; - auto parse_csi = [this]() -> Optional { + auto parse_csi = [this, &convert]() -> Optional { auto next_char = [] { return get_char().value_or((unsigned char)0xff); }; int params[16] = {}; auto c = next_char();