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.
This commit is contained in:
Damien George
2015-10-09 22:41:10 +01:00
parent 1b586f3a73
commit 46a1102852
3 changed files with 85 additions and 31 deletions

View File

@@ -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;
}