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:
parent
1b586f3a73
commit
46a1102852
@ -105,7 +105,7 @@ int readline_process_char(int c) {
|
||||
bool redraw_from_cursor = false;
|
||||
int redraw_step_forward = 0;
|
||||
if (rl.escape_seq == ESEQ_NONE) {
|
||||
if (CHAR_CTRL_A <= c && c <= CHAR_CTRL_D && vstr_len(rl.line) == rl.orig_line_len) {
|
||||
if (CHAR_CTRL_A <= c && c <= CHAR_CTRL_E && vstr_len(rl.line) == rl.orig_line_len) {
|
||||
// control character with empty line
|
||||
return c;
|
||||
} else if (c == CHAR_CTRL_A) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
61
unix/main.c
61
unix/main.c
@ -162,10 +162,12 @@ STATIC int do_repl(void) {
|
||||
vstr_t line;
|
||||
vstr_init(&line, 16);
|
||||
for (;;) {
|
||||
mp_hal_stdio_mode_raw();
|
||||
|
||||
input_restart:
|
||||
vstr_reset(&line);
|
||||
mp_hal_stdio_mode_raw();
|
||||
int ret = readline(&line, ">>> ");
|
||||
mp_parse_input_kind_t parse_input_kind = MP_PARSE_SINGLE_INPUT;
|
||||
|
||||
if (ret == CHAR_CTRL_D) {
|
||||
// EOF
|
||||
@ -173,31 +175,56 @@ STATIC int do_repl(void) {
|
||||
mp_hal_stdio_mode_orig();
|
||||
vstr_clear(&line);
|
||||
return 0;
|
||||
} else if (ret == CHAR_CTRL_E) {
|
||||
// paste mode
|
||||
mp_hal_stdout_tx_str("\npaste mode; CTRL-C to cancel, CTRL-D to finish\n=== ");
|
||||
vstr_reset(&line);
|
||||
for (;;) {
|
||||
char c = mp_hal_stdin_rx_chr();
|
||||
if (c == CHAR_CTRL_C) {
|
||||
// cancel everything
|
||||
mp_hal_stdout_tx_str("\n");
|
||||
goto input_restart;
|
||||
} else if (c == CHAR_CTRL_D) {
|
||||
// end of input
|
||||
mp_hal_stdout_tx_str("\n");
|
||||
break;
|
||||
} else {
|
||||
// add char to buffer and echo
|
||||
vstr_add_byte(&line, c);
|
||||
if (c == '\r') {
|
||||
mp_hal_stdout_tx_str("\n=== ");
|
||||
} else {
|
||||
mp_hal_stdout_tx_strn(&c, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
parse_input_kind = MP_PARSE_FILE_INPUT;
|
||||
} else if (line.len == 0) {
|
||||
if (ret != 0) {
|
||||
printf("\n");
|
||||
}
|
||||
mp_hal_stdio_mode_orig();
|
||||
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
|
||||
printf("\n");
|
||||
mp_hal_stdio_mode_orig();
|
||||
goto input_restart;
|
||||
} else if (ret == CHAR_CTRL_D) {
|
||||
// stop entering compound statement
|
||||
break;
|
||||
goto input_restart;
|
||||
} 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
|
||||
printf("\n");
|
||||
goto input_restart;
|
||||
} else if (ret == CHAR_CTRL_D) {
|
||||
// stop entering compound statement
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mp_hal_stdio_mode_orig();
|
||||
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, false);
|
||||
ret = execute_from_lexer(lex, MP_PARSE_SINGLE_INPUT, true);
|
||||
ret = execute_from_lexer(lex, parse_input_kind, true);
|
||||
if (ret & FORCED_EXIT) {
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user