summaryrefslogtreecommitdiff
path: root/unix
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2015-10-09 22:41:10 +0100
committerDamien George <damien.p.george@gmail.com>2015-10-11 23:30:22 +0100
commit46a11028521425e7d6c85458c849bb96ff82152e (patch)
treec13f48bea9f947bc4c3e1cda04adc7d5437e8edf /unix
parent1b586f3a734c27c78080fb2173bbde17168cb9e4 (diff)
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.
Diffstat (limited to 'unix')
-rw-r--r--unix/main.c61
1 files changed, 44 insertions, 17 deletions
diff --git a/unix/main.c b/unix/main.c
index 7a2f7e4ff..a3f4cfe6c 100644
--- a/unix/main.c
+++ b/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;
}