diff options
| author | Damien George <damien@micropython.org> | 2022-03-08 11:11:23 +1100 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2022-04-22 17:00:16 +1000 |
| commit | 6d401be4dd0164cb197a05c7419f7b6ef5bbdf51 (patch) | |
| tree | 1f7ce1e103a5072a0800aacaf3e791289ad151d3 /shared/readline/readline.c | |
| parent | a8f23f6366b7bb258c7c34a45a3a9bde99e4a32b (diff) | |
shared/readline: Disable auto-indent if space/tab follows added indent.
Auto-indent still works as the default behaviour, but it is now undone and
disabled if there is a space/tab immediately after an automatically-added
indent. This makes the REPL behaviour closer to CPython, and in particular
allows text to be pasted at the normal REPL.
Addresses issue #7925.
Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'shared/readline/readline.c')
| -rw-r--r-- | shared/readline/readline.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/shared/readline/readline.c b/shared/readline/readline.c index 915bcda84..9b8961712 100644 --- a/shared/readline/readline.c +++ b/shared/readline/readline.c @@ -42,6 +42,10 @@ #define READLINE_HIST_SIZE (MP_ARRAY_SIZE(MP_STATE_PORT(readline_hist))) +// flags for readline_t.auto_indent_state +#define AUTO_INDENT_ENABLED (0x01) +#define AUTO_INDENT_JUST_ADDED (0x02) + enum { ESEQ_NONE, ESEQ_ESC, ESEQ_ESC_BRACKET, ESEQ_ESC_BRACKET_DIGIT, ESEQ_ESC_O }; void readline_init0(void) { @@ -94,6 +98,9 @@ typedef struct _readline_t { int hist_cur; size_t cursor_pos; char escape_seq_buf[1]; + #if MICROPY_REPL_AUTO_INDENT + uint8_t auto_indent_state; + #endif const char *prompt; } readline_t; @@ -218,6 +225,17 @@ int readline_process_char(int c) { redraw_step_back = nspace; redraw_from_cursor = true; } + #if MICROPY_REPL_AUTO_INDENT + } else if ((rl.auto_indent_state & AUTO_INDENT_JUST_ADDED) && (c == 9 || c == ' ')) { + // tab/space after auto-indent: disable auto-indent + // - if it's a tab then leave existing indent + // - if it's a space then remove 3 spaces from existing indent + rl.auto_indent_state = 0; + if (c == ' ') { + redraw_step_back = 3; + vstr_cut_tail_bytes(rl.line, 3); + } + #endif #if MICROPY_HELPER_REPL } else if (c == 9) { // tab magic @@ -452,11 +470,18 @@ redraw: rl.cursor_pos += redraw_step_forward; } + #if MICROPY_REPL_AUTO_INDENT + rl.auto_indent_state &= ~AUTO_INDENT_JUST_ADDED; + #endif + return -1; } #if MICROPY_REPL_AUTO_INDENT STATIC void readline_auto_indent(void) { + if (!(rl.auto_indent_state & AUTO_INDENT_ENABLED)) { + return; + } vstr_t *line = rl.line; if (line->len > 1 && line->buf[line->len - 1] == '\n') { int i; @@ -492,6 +517,7 @@ STATIC void readline_auto_indent(void) { vstr_add_strn(line, " ", 4); mp_hal_stdout_tx_strn(" ", 4); rl.cursor_pos += 4; + rl.auto_indent_state |= AUTO_INDENT_JUST_ADDED; } } } @@ -517,6 +543,10 @@ void readline_init(vstr_t *line, const char *prompt) { rl.prompt = prompt; mp_hal_stdout_tx_str(prompt); #if MICROPY_REPL_AUTO_INDENT + if (vstr_len(line) == 0) { + // start with auto-indent enabled + rl.auto_indent_state = AUTO_INDENT_ENABLED; + } readline_auto_indent(); #endif } |
