Introduce char_event_type_t::readline

Baby steps towards eliminating readline actions as characters.
This commit is contained in:
ridiculousfish 2019-03-16 16:48:23 -07:00
parent 14663089c8
commit c2be5e8986
5 changed files with 28 additions and 16 deletions

View File

@ -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());
}
}

View File

@ -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.

View File

@ -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); }

View File

@ -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");
}
};

View File

@ -2507,8 +2507,10 @@ maybe_t<wcstring> 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;