Skip to content

Commit 7d588b0

Browse files
pramasouldpgeorge
authored andcommitted
lib/mp-readline: Add emacs-style control characters for cursor movement.
Disabled by default. Adds 108 bytes to Thumb2 arch when enabled.
1 parent cd14188 commit 7d588b0

5 files changed

Lines changed: 60 additions & 1 deletion

File tree

lib/mp-readline/readline.c

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,44 @@ int readline_process_char(int c) {
111111
} else if (c == CHAR_CTRL_A) {
112112
// CTRL-A with non-empty line is go-to-start-of-line
113113
goto home_key;
114+
#if MICROPY_REPL_EMACS_KEYS
115+
} else if (c == CHAR_CTRL_B) {
116+
// CTRL-B with non-empty line is go-back-one-char
117+
goto left_arrow_key;
118+
#endif
114119
} else if (c == CHAR_CTRL_C) {
115120
// CTRL-C with non-empty line is cancel
116121
return c;
122+
#if MICROPY_REPL_EMACS_KEYS
123+
} else if (c == CHAR_CTRL_D) {
124+
// CTRL-D with non-empty line is delete-at-cursor
125+
goto delete_key;
126+
#endif
117127
} else if (c == CHAR_CTRL_E) {
118128
// CTRL-E is go-to-end-of-line
119129
goto end_key;
130+
#if MICROPY_REPL_EMACS_KEYS
131+
} else if (c == CHAR_CTRL_F) {
132+
// CTRL-F with non-empty line is go-forward-one-char
133+
goto right_arrow_key;
134+
} else if (c == CHAR_CTRL_K) {
135+
// CTRL-K is kill from cursor to end-of-line, inclusive
136+
vstr_cut_tail_bytes(rl.line, last_line_len - rl.cursor_pos);
137+
// set redraw parameters
138+
redraw_from_cursor = true;
139+
} else if (c == CHAR_CTRL_N) {
140+
// CTRL-N is go to next line in history
141+
goto down_arrow_key;
142+
} else if (c == CHAR_CTRL_P) {
143+
// CTRL-P is go to previous line in history
144+
goto up_arrow_key;
145+
} else if (c == CHAR_CTRL_U) {
146+
// CTRL-U is kill from beginning-of-line up to cursor
147+
vstr_cut_out_bytes(rl.line, rl.orig_line_len, rl.cursor_pos - rl.orig_line_len);
148+
// set redraw parameters
149+
redraw_step_back = rl.cursor_pos - rl.orig_line_len;
150+
redraw_from_cursor = true;
151+
#endif
120152
} else if (c == '\r') {
121153
// newline
122154
mp_hal_stdout_tx_str("\r\n");
@@ -181,6 +213,9 @@ int readline_process_char(int c) {
181213
} else {
182214
rl.escape_seq = ESEQ_NONE;
183215
if (c == 'A') {
216+
#if MICROPY_REPL_EMACS_KEYS
217+
up_arrow_key:
218+
#endif
184219
// up arrow
185220
if (rl.hist_cur + 1 < (int)READLINE_HIST_SIZE && MP_STATE_PORT(readline_hist)[rl.hist_cur + 1] != NULL) {
186221
// increase hist num
@@ -194,6 +229,9 @@ int readline_process_char(int c) {
194229
redraw_step_forward = rl.line->len - rl.orig_line_len;
195230
}
196231
} else if (c == 'B') {
232+
#if MICROPY_REPL_EMACS_KEYS
233+
down_arrow_key:
234+
#endif
197235
// down arrow
198236
if (rl.hist_cur >= 0) {
199237
// decrease hist num
@@ -209,11 +247,17 @@ int readline_process_char(int c) {
209247
redraw_step_forward = rl.line->len - rl.orig_line_len;
210248
}
211249
} else if (c == 'C') {
250+
#if MICROPY_REPL_EMACS_KEYS
251+
right_arrow_key:
252+
#endif
212253
// right arrow
213254
if (rl.cursor_pos < rl.line->len) {
214255
redraw_step_forward = 1;
215256
}
216257
} else if (c == 'D') {
258+
#if MICROPY_REPL_EMACS_KEYS
259+
left_arrow_key:
260+
#endif
217261
// left arrow
218262
if (rl.cursor_pos > rl.orig_line_len) {
219263
redraw_step_back = 1;
@@ -238,7 +282,10 @@ int readline_process_char(int c) {
238282
redraw_step_forward = rl.line->len - rl.cursor_pos;
239283
} else if (rl.escape_seq_buf[0] == '3') {
240284
// delete
241-
if (rl.cursor_pos >= rl.orig_line_len && rl.cursor_pos < rl.line->len) {
285+
#if MICROPY_REPL_EMACS_KEYS
286+
delete_key:
287+
#endif
288+
if (rl.cursor_pos < rl.line->len) {
242289
vstr_cut_out_bytes(rl.line, rl.cursor_pos, 1);
243290
redraw_from_cursor = true;
244291
}

lib/mp-readline/readline.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
#define CHAR_CTRL_C (3)
3030
#define CHAR_CTRL_D (4)
3131
#define CHAR_CTRL_E (5)
32+
#define CHAR_CTRL_F (6)
33+
#define CHAR_CTRL_K (11)
34+
#define CHAR_CTRL_N (14)
35+
#define CHAR_CTRL_P (16)
36+
#define CHAR_CTRL_U (21)
3237

3338
void readline_init0(void);
3439
int readline(vstr_t *line, const char *prompt);

py/mpconfig.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,11 @@
303303
#define MICROPY_HELPER_REPL (0)
304304
#endif
305305

306+
// Whether to include emacs-style readline behavior in REPL
307+
#ifndef MICROPY_REPL_EMACS_KEYS
308+
#define MICROPY_REPL_EMACS_KEYS (1)
309+
#endif
310+
306311
// Whether port requires event-driven REPL functions
307312
#ifndef MICROPY_REPL_EVENT_DRIVEN
308313
#define MICROPY_REPL_EVENT_DRIVEN (0)

stmhal/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#define MICROPY_ENABLE_FINALISER (1)
4040
#define MICROPY_STACK_CHECK (1)
4141
#define MICROPY_HELPER_REPL (1)
42+
#define MICROPY_REPL_EMACS_KEYS (1)
4243
#define MICROPY_ENABLE_SOURCE_LINE (1)
4344
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
4445
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)

unix/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#define MICROPY_DEBUG_PRINTERS (1)
5353
#define MICROPY_USE_READLINE_HISTORY (1)
5454
#define MICROPY_HELPER_REPL (1)
55+
#define MICROPY_REPL_EMACS_KEYS (1)
5556
#define MICROPY_HELPER_LEXER_UNIX (1)
5657
#define MICROPY_ENABLE_SOURCE_LINE (1)
5758
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE)

0 commit comments

Comments
 (0)