From 4d03db0de9dddc903be46bfe1db82e8e06e109ba Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Sun, 19 Jul 2020 20:41:39 +0100 Subject: [PATCH] readline: Allow linefeeds to be used to end lines Currently readline ignores linefeeds which works well for \r\n (and \r) data but has problems with linefeed seperations (which, amoung other things, is used by Gadgetbridge's BangleJS driver. Add support for executing commands on a linefeed whilst ensuring that we continue to treat \r\n as a single line. Signed-off-by: Daniel Thompson --- lib/mp-readline/readline.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/mp-readline/readline.c b/lib/mp-readline/readline.c index 296c8aa4a..60ee2ee45 100644 --- a/lib/mp-readline/readline.c +++ b/lib/mp-readline/readline.c @@ -42,7 +42,7 @@ #define READLINE_HIST_SIZE (MP_ARRAY_SIZE(MP_STATE_PORT(readline_hist))) -enum { ESEQ_NONE, ESEQ_ESC, ESEQ_ESC_BRACKET, ESEQ_ESC_BRACKET_DIGIT, ESEQ_ESC_O }; +enum { ESEQ_NONE, ESEQ_ESC, ESEQ_ESC_BRACKET, ESEQ_ESC_BRACKET_DIGIT, ESEQ_ESC_O, ESEQ_CR }; void readline_init0(void) { memset(MP_STATE_PORT(readline_hist), 0, READLINE_HIST_SIZE * sizeof(const char*)); @@ -133,6 +133,8 @@ int readline_process_char(int c) { int redraw_step_back = 0; bool redraw_from_cursor = false; int redraw_step_forward = 0; + if (rl.escape_seq == ESEQ_CR && c != '\n') + rl.escape_seq = ESEQ_NONE; if (rl.escape_seq == ESEQ_NONE) { if (CHAR_CTRL_A <= c && c <= CHAR_CTRL_E && vstr_len(rl.line) == rl.orig_line_len) { // control character with empty line @@ -182,7 +184,12 @@ int readline_process_char(int c) { } else if (c == CHAR_CTRL_W) { goto backward_kill_word; #endif - } else if (c == '\r') { + } else if (c == '\r' || c == '\n') { + // Treat carriage return as a special escape sequence so that we + // can skip a subsequent linefeed (if there is one) + if (c == '\r') + rl.escape_seq = ESEQ_CR; + // newline mp_hal_stdout_tx_str("\r\n"); readline_push_history(vstr_null_terminated_str(rl.line) + rl.orig_line_len);