From 46a11028521425e7d6c85458c849bb96ff82152e Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 9 Oct 2015 22:41:10 +0100 Subject: repl: Add paste mode to friendly REPL, entered via CTRL-E. Use CTRL-E to enter paste mode. Prompt starts with "===" and accepts all characters verbatim, echoing them back. Only control characters are CTRL-C which cancels the input and returns to normal REPL, and CTRL-D which ends the input and executes it. The input is executed as though it were a file. The input is not added to the prompt history. --- stmhal/pyexec.c | 53 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) (limited to 'stmhal') diff --git a/stmhal/pyexec.c b/stmhal/pyexec.c index c692933dc..a809940a8 100644 --- a/stmhal/pyexec.c +++ b/stmhal/pyexec.c @@ -389,6 +389,7 @@ friendly_repl_reset: vstr_reset(&line); int ret = readline(&line, ">>> "); + mp_parse_input_kind_t parse_input_kind = MP_PARSE_SINGLE_INPUT; if (ret == CHAR_CTRL_A) { // change to raw REPL @@ -409,20 +410,46 @@ friendly_repl_reset: mp_hal_stdout_tx_str("\r\n"); vstr_clear(&line); return PYEXEC_FORCED_EXIT; + } else if (ret == CHAR_CTRL_E) { + // paste mode + mp_hal_stdout_tx_str("\r\npaste mode; CTRL-C to cancel, CTRL-D to finish\r\n=== "); + vstr_reset(&line); + for (;;) { + char c = mp_hal_stdin_rx_chr(); + if (c == CHAR_CTRL_C) { + // cancel everything + mp_hal_stdout_tx_str("\r\n"); + goto input_restart; + } else if (c == CHAR_CTRL_D) { + // end of input + mp_hal_stdout_tx_str("\r\n"); + break; + } else { + // add char to buffer and echo + vstr_add_byte(&line, c); + if (c == '\r') { + mp_hal_stdout_tx_str("\r\n=== "); + } else { + mp_hal_stdout_tx_strn(&c, 1); + } + } + } + parse_input_kind = MP_PARSE_FILE_INPUT; } else if (vstr_len(&line) == 0) { continue; - } - - while (mp_repl_continue_with_input(vstr_null_terminated_str(&line))) { - vstr_add_byte(&line, '\n'); - ret = readline(&line, "... "); - if (ret == CHAR_CTRL_C) { - // cancel everything - mp_hal_stdout_tx_str("\r\n"); - goto input_restart; - } else if (ret == CHAR_CTRL_D) { - // stop entering compound statement - break; + } else { + // got a line with non-zero length, see if it needs continuing + while (mp_repl_continue_with_input(vstr_null_terminated_str(&line))) { + vstr_add_byte(&line, '\n'); + ret = readline(&line, "... "); + if (ret == CHAR_CTRL_C) { + // cancel everything + mp_hal_stdout_tx_str("\r\n"); + goto input_restart; + } else if (ret == CHAR_CTRL_D) { + // stop entering compound statement + break; + } } } @@ -430,7 +457,7 @@ friendly_repl_reset: if (lex == NULL) { printf("MemoryError\n"); } else { - ret = parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL); + ret = parse_compile_execute(lex, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL); if (ret & PYEXEC_FORCED_EXIT) { return ret; } -- cgit v1.2.3