diff --git a/lib/mp-readline/readline.c b/lib/mp-readline/readline.c index 9d254d8cfebe7..96d4d90ae6284 100644 --- a/lib/mp-readline/readline.c +++ b/lib/mp-readline/readline.c @@ -33,6 +33,10 @@ #include "py/mphal.h" #include "lib/mp-readline/readline.h" +#if MICROPY_REPL_EMACS_KEYS +#include "py/unicode.h" +#endif + #if 0 // print debugging info #define DEBUG_PRINT (1) #define DEBUG_printf printf @@ -98,6 +102,31 @@ typedef struct _readline_t { STATIC readline_t rl; +#if MICROPY_REPL_EMACS_KEYS +STATIC int get_next_word_cursor_offset(int direction) { + int buf_idx_offset = direction == 1 ? 0 : -1; + size_t cursor_pos = rl.cursor_pos; + bool in_leading_nonalphanum = true; + while (1) { + char c = rl.line->buf[cursor_pos + buf_idx_offset]; + if (unichar_isalpha(c) || unichar_isdigit(c)) { + in_leading_nonalphanum = false; + } else if (!in_leading_nonalphanum) { + break; + } + if (direction == 1) { + if (cursor_pos >= rl.line->len) { + break; + } + } else if (cursor_pos <= 0) { + break; + } + cursor_pos += direction; + } + return cursor_pos - rl.cursor_pos; +} +#endif + int readline_process_char(int c) { size_t last_line_len = rl.line->len; int redraw_step_back = 0; @@ -218,6 +247,41 @@ int readline_process_char(int c) { case '[': rl.escape_seq = ESEQ_ESC_BRACKET; break; + #if MICROPY_REPL_EMACS_KEYS + case 'b': + // backword-word (M-b) + redraw_step_back = -get_next_word_cursor_offset(-1); + rl.escape_seq = ESEQ_NONE; + break; + case 'f': + // forward-word (M-f) + redraw_step_forward = get_next_word_cursor_offset(1); + rl.escape_seq = ESEQ_NONE; + break; + case 'd': { + // kill-word (M-d) + size_t num_chars; + num_chars = get_next_word_cursor_offset(1); + if (num_chars) { + vstr_cut_out_bytes(rl.line, rl.cursor_pos, num_chars); + redraw_from_cursor = true; + } + rl.escape_seq = ESEQ_NONE; + break; + } + case 127: { + // backward-kill-word (M-DEL) + size_t num_chars; + num_chars = -get_next_word_cursor_offset(-1); + if (num_chars) { + vstr_cut_out_bytes(rl.line, rl.cursor_pos - num_chars, num_chars); + redraw_step_back = num_chars; + redraw_from_cursor = true; + } + rl.escape_seq = ESEQ_NONE; + break; + } + #endif case 'O': rl.escape_seq = ESEQ_ESC_O; break;
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: