diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index 151488367..5ace2a730 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -2997,11 +2997,11 @@ static void test_input() { // Now test. auto evt = input_readch(); - if (!evt.is_char()) { - err(L"Event is not a char"); - } else if (evt.get_char() != R_DOWN_LINE) { + if (!evt.is_readline()) { + err(L"Event is not a readline"); + } else if (evt.get_readline() != R_DOWN_LINE) { err(L"Expected to read char R_DOWN_LINE, but instead got %ls\n", - describe_char(evt.get_char()).c_str()); + describe_char(evt.get_readline()).c_str()); } } diff --git a/src/input.cpp b/src/input.cpp index 4b183b80c..227620dd7 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -311,7 +311,7 @@ void input_function_push_args(int code) { wchar_t arg{}; for (;;) { auto evt = input_common_readch(); - if (evt.is_char() && !evt.is_readline()) { + if (evt.is_char()) { arg = evt.get_char(); break; } @@ -479,7 +479,7 @@ char_event_t input_readch(bool allow_commands) { auto evt = input_common_readch(); if (evt.is_readline()) { - switch (evt.get_char()) { + switch (evt.get_readline()) { case R_SELF_INSERT: { // Issue #1595: ensure we only insert characters, not readline functions. The // common case is that this will be empty. diff --git a/src/input_common.cpp b/src/input_common.cpp index 29826459a..df3bbfcd1 100644 --- a/src/input_common.cpp +++ b/src/input_common.cpp @@ -192,7 +192,7 @@ char_event_t input_common_readch() { mbstate_t state = {}; while (1) { auto evt = readb(); - if (!evt.is_char() || evt.is_readline()) { + if (!evt.is_char()) { return evt; } @@ -239,7 +239,7 @@ char_event_t input_common_readch_timed(bool dequeue_timeouts) { if (!dequeue_timeouts) lookahead_push_front(char_event_type_t::timeout); return char_event_type_t::timeout; } - return result.get_char(); + return result; } void input_common_queue_ch(char_event_t ch) { lookahead_push_back(ch); } diff --git a/src/input_common.h b/src/input_common.h index 85db7b5c6..550143ce3 100644 --- a/src/input_common.h +++ b/src/input_common.h @@ -82,6 +82,9 @@ enum class char_event_type_t { /// A character was entered. charc, + /// A readline event. + readline, + /// A timeout was hit. timeout, @@ -94,7 +97,7 @@ enum class char_event_type_t { }; class char_event_t { - /// Set if the type is charc. + /// Set if the type is charc or readline. wchar_t c_; public: @@ -108,19 +111,26 @@ class char_event_t { bool is_check_exit() const { return type == char_event_type_t::check_exit; } - bool is_readline() const { - return is_char() && c_ >= R_BEGIN_INPUT_FUNCTIONS && c_ < R_END_INPUT_FUNCTIONS; - } + bool is_readline() const { return type == char_event_type_t::readline; } wchar_t get_char() const { assert(type == char_event_type_t::charc && "Not a char type"); return c_; } - /* implicit */ char_event_t(wchar_t c) : c_(c), type(char_event_type_t::charc) {} + wchar_t get_readline() const { + assert(type == char_event_type_t::readline && "Not a readline type"); + return c_; + } + + /* implicit */ char_event_t(wchar_t c) + : c_(c), + type(R_BEGIN_INPUT_FUNCTIONS <= c && c < R_END_INPUT_FUNCTIONS + ? char_event_type_t::readline + : char_event_type_t::charc) {} /* implicit */ char_event_t(char_event_type_t type) : c_(0), type(type) { - assert(type != char_event_type_t::charc && + assert(type != char_event_type_t::charc && type != char_event_type_t::readline && "Cannot create a char event with this constructor"); } }; diff --git a/src/reader.cpp b/src/reader.cpp index b911f2a2f..d2b4ddbad 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -2507,8 +2507,10 @@ maybe_t reader_data_t::readline(int nchars) { reader_force_exit(); continue; } - assert(event_needing_handling->is_char() && "Should have a char event"); - wchar_t c = event_needing_handling->get_char(); + assert((event_needing_handling->is_char() || event_needing_handling->is_readline()) && + "Should have a char or readline"); + wchar_t c = event_needing_handling->is_char() ? event_needing_handling->get_char() + : event_needing_handling->get_readline(); // If we get something other than a repaint, then stop coalescing them. if (c != R_REPAINT) coalescing_repaints = false;