summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2023-03-13 20:55:31 +1100
committerMaxime Coste <mawww@kakoune.org>2023-03-13 20:55:31 +1100
commit6548846950598f9173f254fcdf31326aac02bb4f (patch)
tree096d1f8cf6c8ef731722491d9310511f4ba076d9 /src
parentf05ab99d4d7322055f7eb9b9d86b529062885208 (diff)
Slight refactoring of bracketed paste feature
Handle begin/end paste directly in paste csi, manage paste buffer out of get_char, filter Key::Invalid earlier. get_next_key returning Key::Invalid means there was some input but it could not be represented as a Key. An empty optional means there was no input at all.
Diffstat (limited to 'src')
-rw-r--r--src/client.cc1
-rw-r--r--src/input_handler.cc3
-rw-r--r--src/terminal_ui.cc70
3 files changed, 26 insertions, 48 deletions
diff --git a/src/client.cc b/src/client.cc
index ec90982c..f022c699 100644
--- a/src/client.cc
+++ b/src/client.cc
@@ -46,6 +46,7 @@ Client::Client(std::unique_ptr<UserInterface>&& ui,
m_ui->set_ui_options(m_window->options()["ui_options"].get<UserInterface::Options>());
m_ui->set_on_key([this](Key key) {
+ kak_assert(key != Key::Invalid);
if (key == ctrl('c'))
{
auto prev_handler = set_signal_handler(SIGINT, SIG_IGN);
diff --git a/src/input_handler.cc b/src/input_handler.cc
index 877517e2..97db92c6 100644
--- a/src/input_handler.cc
+++ b/src/input_handler.cc
@@ -1750,8 +1750,7 @@ static bool is_valid(Key key)
{
constexpr Key::Modifiers valid_mods = (Key::Modifiers::Control | Key::Modifiers::Alt | Key::Modifiers::Shift);
- return key != Key::Invalid and
- ((key.modifiers & ~valid_mods) or key.key <= 0x10FFFF);
+ return ((key.modifiers & ~valid_mods) or key.key <= 0x10FFFF);
}
void InputHandler::handle_key(Key key)
diff --git a/src/terminal_ui.cc b/src/terminal_ui.cc
index 612029e8..13a8af4b 100644
--- a/src/terminal_ui.cc
+++ b/src/terminal_ui.cc
@@ -447,9 +447,9 @@ TerminalUI::TerminalUI()
while (auto key = get_next_key())
{
- if (key == ctrl('z'))
+ if (*key == ctrl('z'))
kill(0, SIGTSTP); // We suspend at this line
- else
+ else if (*key != Key::Invalid)
m_on_key(*key);
}
}},
@@ -689,11 +689,7 @@ Optional<Key> TerminalUI::get_next_key()
return {};
if (unsigned char c = 0; read(STDIN_FILENO, &c, 1) == 1)
- {
- if (m_paste_buffer)
- m_paste_buffer->push_back(c);
return c;
- }
stdin_closed = 1;
return {};
@@ -759,16 +755,7 @@ Optional<Key> TerminalUI::get_next_key()
return mod;
};
- enum class PasteEvent { Begin, End };
- struct KeyOrPasteEvent {
- KeyOrPasteEvent() = default;
- KeyOrPasteEvent(Key key) : key(key) {}
- KeyOrPasteEvent(Optional<Key> key) : key(key) {}
- KeyOrPasteEvent(PasteEvent paste) : paste(paste) {}
- const Optional<Key> key;
- const Optional<PasteEvent> paste;
- };
- auto parse_csi = [this]() -> KeyOrPasteEvent {
+ auto parse_csi = [this]() -> Optional<Key> {
auto next_char = [] { return get_char().value_or((unsigned char)0xff); };
int params[16][4] = {};
auto c = next_char();
@@ -878,9 +865,15 @@ Optional<Key> TerminalUI::get_next_key()
case 33: case 34:
return Key{Key::Modifiers::Shift, Key::F9 + params[0][0] - 33}; // rxvt style
case 200:
- return PasteEvent::Begin;
+ m_paste_buffer = String{};
+ return Key{Key::Invalid};
case 201:
- return PasteEvent::End;
+ if (m_paste_buffer)
+ {
+ m_on_paste(*m_paste_buffer);
+ m_paste_buffer.reset();
+ }
+ return Key{Key::Invalid};
}
return {};
case 'u':
@@ -962,41 +955,26 @@ Optional<Key> TerminalUI::get_next_key()
}
};
- if (m_paste_buffer)
+ if (*c == 27)
{
- if (*c == 27 and get_char() == '[' and parse_csi().paste == PasteEvent::End)
+ if (auto next = get_char())
{
- m_paste_buffer->resize(m_paste_buffer->length() - "\033[201~"_str.length(), '\0');
- m_on_paste(*m_paste_buffer);
- m_paste_buffer.reset();
+ if (*next == '[') // potential CSI
+ return parse_csi().value_or(alt('['));
+ if (*next == 'O') // potential SS3
+ return parse_ss3().value_or(alt('O'));
+ return alt(parse_key(*next));
}
- return get_next_key();
+ else if (not m_paste_buffer)
+ return Key{Key::Escape};
}
- if (*c != 27)
- return parse_key(*c);
-
- if (auto next = get_char())
+ if (m_paste_buffer)
{
- if (*next == 'O') // potential SS3
- return parse_ss3().value_or(alt('O'));
- if (*next != '[')
- return alt(parse_key(*next));
- // potential CSI
- KeyOrPasteEvent csi = parse_csi();
- if (csi.paste == PasteEvent::Begin)
- {
- m_paste_buffer = String{};
- return get_next_key();
- }
- if (csi.paste == PasteEvent::End) // Unmatched bracketed paste sequence.
- return {};
- if (csi.key)
- return *csi.key;
- return alt('[');
+ m_paste_buffer->push_back(*c);
+ return Key{Key::Invalid};
}
-
- return Key{Key::Escape};
+ return parse_key(*c);
}
template<typename T>