Handle xterm's alternate screen when entering or leaving ex mode, e.g.
":!ls", so that the screen is not changed before the "Press any key" message. Taken from v1.79.
This commit is contained in:
parent
a6921e9cfe
commit
4a3a422fde
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cl_funcs.c,v 1.2 1998/01/09 08:06:20 perry Exp $ */
|
||||
/* $NetBSD: cl_funcs.c,v 1.3 2000/05/31 19:49:23 jdc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994
|
||||
@ -85,10 +85,60 @@ cl_attr(sp, attribute, on)
|
||||
{
|
||||
CL_PRIVATE *clp;
|
||||
|
||||
clp = CLP(sp);
|
||||
|
||||
switch (attribute) {
|
||||
case SA_ALTERNATE:
|
||||
/*
|
||||
* !!!
|
||||
* There's a major layering violation here. The problem is that the
|
||||
* X11 xterm screen has what's known as an "alternate" screen. Some
|
||||
* xterm termcap/terminfo entries include sequences to switch to/from
|
||||
* that alternate screen as part of the ti/te (smcup/rmcup) strings.
|
||||
* Vi runs in the alternate screen, so that you are returned to the
|
||||
* same screen contents on exit from vi that you had when you entered
|
||||
* vi. Further, when you run :shell, or :!date or similar ex commands,
|
||||
* you also see the original screen contents. This wasn't deliberate
|
||||
* on vi's part, it's just that it historically sent terminal init/end
|
||||
* sequences at those times, and the addition of the alternate screen
|
||||
* sequences to the strings changed the behavior of vi. The problem
|
||||
* caused by this is that we don't want to switch back to the alternate
|
||||
* screen while getting a new command from the user, when the user is
|
||||
* continuing to enter ex commands, e.g.:
|
||||
*
|
||||
* :!date <<< switch to original screen
|
||||
* [Hit return to continue] <<< prompt user to continue
|
||||
* :command <<< get command from user
|
||||
*
|
||||
* Note that the :command input is a true vi input mode, e.g., input
|
||||
* maps and abbreviations are being done. So, we need to be able to
|
||||
* switch back into the vi screen mode, without flashing the screen.
|
||||
*
|
||||
* To make matters worse, the curses initscr() and endwin() calls will
|
||||
* do this automatically -- so, this attribute isn't as controlled by
|
||||
* the higher level screen as closely as one might like.
|
||||
*/
|
||||
if (on) {
|
||||
if (clp->ti_te != TI_SENT) {
|
||||
clp->ti_te = TI_SENT;
|
||||
if (clp->smcup == NULL)
|
||||
(void)cl_getcap(sp, "smcup", &clp->smcup);
|
||||
if (clp->smcup != NULL)
|
||||
(void)tputs(clp->smcup, 1, cl_putchar);
|
||||
}
|
||||
} else
|
||||
if (clp->ti_te != TE_SENT) {
|
||||
clp->ti_te = TE_SENT;
|
||||
if (clp->rmcup == NULL)
|
||||
(void)cl_getcap(sp, "rmcup", &clp->rmcup);
|
||||
if (clp->rmcup != NULL)
|
||||
(void)tputs(clp->rmcup, 1, cl_putchar);
|
||||
(void)fflush(stdout);
|
||||
}
|
||||
(void)fflush(stdout);
|
||||
break;
|
||||
case SA_INVERSE:
|
||||
if (F_ISSET(sp, SC_EX | SC_SCR_EXWROTE)) {
|
||||
clp = CLP(sp);
|
||||
if (clp->smso == NULL)
|
||||
return (1);
|
||||
if (on)
|
||||
@ -529,12 +579,7 @@ cl_suspend(sp, allowedp)
|
||||
(void)keypad(stdscr, FALSE);
|
||||
|
||||
#ifdef HAVE_BSD_CURSES
|
||||
/* Send the terminal end sequence. */
|
||||
if (clp->rmcup == NULL)
|
||||
(void)cl_getcap(sp, "rmcup", &clp->rmcup);
|
||||
if (clp->rmcup != NULL)
|
||||
(void)tputs(clp->rmcup, 1, cl_putchar);
|
||||
(void)fflush(stdout);
|
||||
(void)cl_attr(sp, SA_ALTERNATE, 0);
|
||||
#else
|
||||
(void)endwin();
|
||||
#endif
|
||||
@ -557,12 +602,7 @@ cl_suspend(sp, allowedp)
|
||||
if (F_ISSET(gp, G_STDIN_TTY))
|
||||
(void)tcsetattr(STDIN_FILENO, TCSASOFT | TCSADRAIN, &t);
|
||||
|
||||
/* Send the terminal initialization sequence. */
|
||||
if (clp->smcup == NULL)
|
||||
(void)cl_getcap(sp, "smcup", &clp->smcup);
|
||||
if (clp->smcup != NULL)
|
||||
(void)tputs(clp->smcup, 1, cl_putchar);
|
||||
(void)fflush(stdout);
|
||||
(void)cl_attr(sp, SA_ALTERNATE, 1);
|
||||
#endif
|
||||
/* Put the cursor keys into application mode. */
|
||||
(void)keypad(stdscr, TRUE);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cl_screen.c,v 1.3 1998/01/10 23:04:11 perry Exp $ */
|
||||
/* $NetBSD: cl_screen.c,v 1.4 2000/05/31 19:49:23 jdc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994
|
||||
@ -374,16 +374,6 @@ fast: /* Set the terminal modes. */
|
||||
err: (void)cl_vi_end(sp->gp);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* If not already done, send the terminal initialization sequence. */
|
||||
if (clp->ti_te == TE_SENT) {
|
||||
clp->ti_te = TI_SENT;
|
||||
if (clp->smcup == NULL)
|
||||
(void)cl_getcap(sp, "smcup", &clp->smcup);
|
||||
if (clp->smcup != NULL)
|
||||
(void)tputs(clp->smcup, 1, cl_putchar);
|
||||
(void)fflush(stdout);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -498,15 +488,6 @@ fast: if (tcsetattr(STDIN_FILENO, TCSADRAIN | TCSASOFT, &clp->ex_enter)) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* If not already done, send the terminal end sequence. */
|
||||
if (clp->ti_te == TI_SENT) {
|
||||
clp->ti_te = TE_SENT;
|
||||
if (clp->rmcup == NULL)
|
||||
(void)cl_getcap(sp, "rmcup", &clp->rmcup);
|
||||
if (clp->rmcup != NULL)
|
||||
(void)tputs(clp->rmcup, 1, cl_putchar);
|
||||
(void)fflush(stdout);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: gs.h,v 1.2 1998/01/09 08:06:39 perry Exp $ */
|
||||
/* $NetBSD: gs.h,v 1.3 2000/05/31 19:49:25 jdc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994
|
||||
@ -44,7 +44,7 @@ struct _fref {
|
||||
typedef enum { EX_TERM_CE, EX_TERM_SCROLL } exadj_t;
|
||||
|
||||
/* Screen attribute argument to scr_attr(). */
|
||||
typedef enum { SA_INVERSE } scr_attr_t;
|
||||
typedef enum { SA_ALTERNATE, SA_INVERSE } scr_attr_t;
|
||||
|
||||
/* Key type argument to scr_keyval(). */
|
||||
typedef enum { KEY_VEOF, KEY_VERASE, KEY_VKILL, KEY_VWERASE } scr_keyval_t;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ex_read.c,v 1.7 1998/01/09 08:07:59 perry Exp $ */
|
||||
/* $NetBSD: ex_read.c,v 1.8 2000/05/31 19:49:25 jdc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
@ -162,6 +162,12 @@ ex_read(sp, cmdp)
|
||||
ex_emsg(sp, cmdp->cmd->name, EXM_NOCANON_F);
|
||||
return (1);
|
||||
}
|
||||
/*
|
||||
* !!!
|
||||
* Historically, the read command doesn't switch to
|
||||
* the alternate X11 xterm screen, if doing a filter
|
||||
* read -- don't set SA_ALTERNATE.
|
||||
*/
|
||||
F_SET(sp, SC_SCR_EX | SC_SCR_EXWROTE);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ex_shell.c,v 1.7 1998/01/09 08:08:02 perry Exp $ */
|
||||
/* $NetBSD: ex_shell.c,v 1.8 2000/05/31 19:49:25 jdc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
@ -84,9 +84,12 @@ ex_exec_proc(sp, cmdp, cmd, msg, need_newline)
|
||||
const char *msg;
|
||||
int need_newline;
|
||||
{
|
||||
GS *gp;
|
||||
const char *name;
|
||||
pid_t pid;
|
||||
|
||||
gp = sp->gp;
|
||||
|
||||
/* We'll need a shell. */
|
||||
if (opts_empty(sp, O_SHELL, 0))
|
||||
return (1);
|
||||
@ -97,6 +100,7 @@ ex_exec_proc(sp, cmdp, cmd, msg, need_newline)
|
||||
ex_emsg(sp, cmdp->cmd->name, EXM_NOCANON);
|
||||
return (1);
|
||||
}
|
||||
(void)gp->scr_attr(sp, SA_ALTERNATE, 0);
|
||||
F_SET(sp, SC_SCR_EX | SC_SCR_EXWROTE);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ex_util.c,v 1.7 1998/01/09 08:08:10 perry Exp $ */
|
||||
/* $NetBSD: ex_util.c,v 1.8 2000/05/31 19:49:26 jdc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994
|
||||
@ -154,8 +154,13 @@ int
|
||||
ex_init(sp)
|
||||
SCR *sp;
|
||||
{
|
||||
if (sp->gp->scr_screen(sp, SC_EX))
|
||||
GS *gp;
|
||||
|
||||
gp = sp->gp;
|
||||
|
||||
if (gp->scr_screen(sp, SC_EX))
|
||||
return (1);
|
||||
(void)gp->scr_attr(sp, SA_ALTERNATE, 0);
|
||||
|
||||
sp->rows = O_VAL(sp, O_LINES);
|
||||
sp->cols = O_VAL(sp, O_COLUMNS);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: v_ex.c,v 1.8 1999/01/08 06:16:55 abs Exp $ */
|
||||
/* $NetBSD: v_ex.c,v 1.9 2000/05/31 19:49:26 jdc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
@ -66,12 +66,17 @@ v_exmode(sp, vp)
|
||||
SCR *sp;
|
||||
VICMD *vp;
|
||||
{
|
||||
GS *gp;
|
||||
|
||||
gp = sp->gp;
|
||||
|
||||
/* Try and switch screens -- the screen may not permit it. */
|
||||
if (sp->gp->scr_screen(sp, SC_EX)) {
|
||||
msgq(sp, M_ERR,
|
||||
"207|The Q command requires the ex terminal interface");
|
||||
return (1);
|
||||
}
|
||||
(void)gp->scr_attr(sp, SA_ALTERNATE, 0);
|
||||
|
||||
/* Save the current cursor position. */
|
||||
sp->frp->lno = sp->lno;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vi.c,v 1.8 1998/01/09 08:08:48 perry Exp $ */
|
||||
/* $NetBSD: vi.c,v 1.9 2000/05/31 19:49:26 jdc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
@ -89,6 +89,7 @@ vi(spp)
|
||||
/* Initialize the vi screen. */
|
||||
if (v_init(sp))
|
||||
return (1);
|
||||
(void)gp->scr_attr(sp, SA_ALTERNATE, 1);
|
||||
|
||||
for (vip = VIP(sp), rval = 0;;) {
|
||||
/* Resolve messages. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vs_msg.c,v 1.2 1998/01/09 08:08:51 perry Exp $ */
|
||||
/* $NetBSD: vs_msg.c,v 1.3 2000/05/31 19:49:27 jdc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994
|
||||
@ -620,6 +620,9 @@ vs_ex_resolve(sp, continuep)
|
||||
if (F_ISSET(vip, VIP_N_EX_REDRAW))
|
||||
F_SET(sp, SC_SCR_REFORMAT);
|
||||
|
||||
/* Ex may have switched out of the alternate screen, return. */
|
||||
(void)gp->scr_attr(sp, SA_ALTERNATE, 1);
|
||||
|
||||
/*
|
||||
* Whew. We're finally back home, after what feels like years.
|
||||
* Kiss the ground.
|
||||
|
Loading…
Reference in New Issue
Block a user