From 742015e59f17c2d4f8b80504f76556654bab810b Mon Sep 17 00:00:00 2001 From: jh Date: Fri, 28 May 2010 09:30:13 +0000 Subject: Fixes from NetBSD for nvi visual mode: - Fix handling of ^@ when reading an ex command. Don't try to replay the previous input. - Fix handling of ^C in insert mode and when reading an ex command. Repeating an interrupted input could cause a crash and interrupting ex command input could cause a file corruption. - Fix a bug which causes crashes in file name completion when a file name is longer than the screen width. - When an error occurs in v_txt(), leave the input mode. PR: bin/21089, bin/136393 Obtained from: NetBSD --- contrib/nvi/vi/v_ex.c | 4 ++++ contrib/nvi/vi/v_txt.c | 47 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 37 insertions(+), 14 deletions(-) (limited to 'contrib/nvi') diff --git a/contrib/nvi/vi/v_ex.c b/contrib/nvi/vi/v_ex.c index bcb0ea6..d4d431a 100644 --- a/contrib/nvi/vi/v_ex.c +++ b/contrib/nvi/vi/v_ex.c @@ -428,6 +428,10 @@ v_ex(sp, vp) if (tp->term == TERM_BS) break; + /* If the user changed their mind, return. */ + if (tp->term != TERM_OK) + break; + /* Log the command. */ if (O_STR(sp, O_CEDIT) != NULL && v_ecl_log(sp, tp)) return (1); diff --git a/contrib/nvi/vi/v_txt.c b/contrib/nvi/vi/v_txt.c index c47a485..4a3e80a 100644 --- a/contrib/nvi/vi/v_txt.c +++ b/contrib/nvi/vi/v_txt.c @@ -510,15 +510,6 @@ next: if (v_event_get(sp, evp, 0, ec_flags)) case E_EOF: F_SET(sp, SC_EXIT_FORCE); return (1); - case E_INTERRUPT: - /* - * !!! - * Historically, exited the user from text input - * mode or cancelled a colon command, and returned to command - * mode. It also beeped the terminal, but that seems a bit - * excessive. - */ - goto k_escape; case E_REPAINT: if (vs_repaint(sp, &ev)) return (1); @@ -526,10 +517,37 @@ next: if (v_event_get(sp, evp, 0, ec_flags)) case E_WRESIZE: /* interrupts the input mode. */ v_emsg(sp, NULL, VIM_WRESIZE); - goto k_escape; + /* FALLTHROUGH */ default: - v_event_err(sp, evp); - goto k_escape; + if (evp->e_event != E_INTERRUPT && evp->e_event != E_WRESIZE) + v_event_err(sp, evp); + /* + * !!! + * Historically, exited the user from text input + * mode or cancelled a colon command, and returned to command + * mode. It also beeped the terminal, but that seems a bit + * excessive. + */ + /* + * If we are recording, morph into key so that + * we can repeat the command safely: there is no way to + * invalidate the repetition of an instance of a command, + * which would be the alternative possibility. + * If we are not recording (most likely on the command line), + * simply discard the input and return to command mode + * so that an INTERRUPT doesn't become for example a file + * completion request. -aymeric + */ + if (LF_ISSET(TXT_RECORD)) { + evp->e_event = E_CHARACTER; + evp->e_c = 033; + evp->e_flags = 0; + evp->e_value = K_ESCAPE; + break; + } else { + tp->term = TERM_ESC; + goto k_escape; + } } /* @@ -539,7 +557,7 @@ next: if (v_event_get(sp, evp, 0, ec_flags)) * This was not documented as far as I know, and is a great test of vi * clones. */ - if (rcol == 0 && !LF_ISSET(TXT_REPLAY) && evp->e_c == '\0') { + if (LF_ISSET(TXT_RECORD) && rcol == 0 && evp->e_c == '\0') { if (vip->rep == NULL) goto done; @@ -1456,6 +1474,7 @@ done: /* Leave input mode. */ err: alloc_err: + F_CLR(sp, SC_TINPUT); txt_err(sp, &sp->tiq); return (1); } @@ -2216,8 +2235,8 @@ txt_fc_col(sp, argc, argv) /* If the largest file name is too large, just print them. */ if (colwidth > sp->cols) { - p = msg_print(sp, av[0]->bp + prefix, &nf); for (ac = argc, av = argv; ac > 0; --ac, ++av) { + p = msg_print(sp, av[0]->bp + prefix, &nf); (void)ex_printf(sp, "%s\n", p); if (F_ISSET(gp, G_INTERRUPTED)) break; -- cgit v1.1