-/* Copyright (c) 1979 Regents of the University of California */
+/* Copyright (c) 1980 Regents of the University of California */
+static char *sccsid = "@(#)ex_vget.c 4.2 %G%";
#include "ex.h"
#include "ex_tty.h"
#include "ex_vis.h"
char ch;
register int c, d;
register char *colp;
+#define BEEHIVE
+#ifdef BEEHIVE
+ static char Peek2key;
+#endif
+ extern short slevel, ttyindes;
getATTN:
if (Peekkey) {
Peekkey = 0;
return (c);
}
+#ifdef BEEHIVE
+ if (Peek2key) {
+ c = Peek2key;
+ Peek2key = 0;
+ return (c);
+ }
+#endif
if (vglobp) {
if (*vglobp)
return (lastvgk = *vglobp++);
return(*vmacp++);
/* End of a macro or set of nested macros */
vmacp = 0;
+ if (inopen == -1) /* don't screw up undo for esc esc */
+ vundkind = VMANY;
inopen = 1; /* restore old setting now that macro done */
- vundkind = VMANY;
+ vch_mac = VC_NOTINMAC;
}
-#ifdef TRACE
- if (trace)
- fflush(trace);
-#endif
flusho();
again:
- if (read(0, &ch, 1) != 1) {
+ if (read(slevel == 0 ? 0 : ttyindes, &ch, 1) != 1) {
if (errno == EINTR)
goto getATTN;
error("Input read error");
}
c = ch & TRIM;
+#ifdef BEEHIVE
+ if (XB && slevel==0 && c == ESCAPE) {
+ if (read(0, &Peek2key, 1) != 1)
+ goto getATTN;
+ Peek2key &= TRIM;
+ switch (Peek2key) {
+ case 'C': /* SPOW mode sometimes sends \EC for space */
+ c = ' ';
+ Peek2key = 0;
+ break;
+ case 'q': /* f2 -> ^C */
+ c = CTRL(c);
+ Peek2key = 0;
+ break;
+ case 'p': /* f1 -> esc */
+ Peek2key = 0;
+ break;
+ }
+ }
+#endif
#ifdef UCVISUAL
/*
c = getkey();
switch (c) {
+ case CTRL(v):
+ case CTRL(q):
+ c = getkey();
+ return (c);
+
case ATTN:
case QUIT:
ungetkey(c);
}
OP = Pline; Pline = normline;
ignore(vgetline(0, genbuf + 1, &waste));
+ if (Outchar == termchar)
+ putchar('\n');
vscrap();
Pline = OP;
if (Peekkey != ATTN && Peekkey != QUIT && Peekkey != CTRL(h)) {
setLAST()
{
- if (vglobp)
+ if (vglobp || vmacp)
return;
lastreg = vreg;
lasthad = Xhadcnt;
if (trace)
fprintf(trace,"map(%c): ",c);
#endif
+ /*
+ * If c==0, the char came from getesc typing escape. Pass it through
+ * unchanged. 0 messes up the following code anyway.
+ */
+ if (c==0)
+ return(0);
+
b[0] = c;
b[1] = 0;
for (d=0; maps[d].mapto; d++) {
#ifdef MDEBUG
if (trace)
- fprintf(trace,"d=%d, ",d);
+ fprintf(trace,"\ntry '%s', ",maps[d].cap);
#endif
if (p = maps[d].cap) {
for (q=b; *p; p++, q++) {
#endif
if (*q==0) {
/*
+ * Is there another char waiting?
+ *
* This test is oversimplified, but
* should work mostly. It handles the
* case where we get an ESCAPE that
*/
if ((c=='#' ? peekkey() : fastpeekkey()) == 0) {
#ifdef MDEBUG
- if (trace)
- fprintf(trace,"fpk=0: return %c",c);
+ if (trace)
+ fprintf(trace,"fpk=0: return '%c'",c);
#endif
- macpush(&b[1]);
+ /*
+ * Nothing waiting. Push back
+ * what we peeked at & return
+ * failure (c).
+ *
+ * We want to be able to undo
+ * commands, but it's nonsense
+ * to undo part of an insertion
+ * so if in input mode don't.
+ */
+ macpush(&b[1],maps == arrows);
return(c);
}
*q = getkey();
if (*p != *q)
goto contin;
}
- macpush(maps[d].mapto);
+ macpush(maps[d].mapto,maps == arrows);
c = getkey();
#ifdef MDEBUG
- if (trace)
- fprintf(trace,"Success: return %c",c);
+ if (trace)
+ fprintf(trace,"Success: push(%s), return %c",maps[d].mapto, c);
#endif
return(c); /* first char of map string */
contin:;
}
#ifdef MDEBUG
if (trace)
- fprintf(trace,"Fail: return %c",c); /* DEBUG */
+ fprintf(trace,"Fail: push(%s), return %c", &b[1], c);
#endif
- macpush(&b[1]);
+ macpush(&b[1],0);
return(c);
}
* worry about where vmacp was previously pointing. We also have to
* check for overflow (which is typically from a recursive macro)
* Finally we have to set a flag so the whole thing can be undone.
+ * canundo is 1 iff we want to be able to undo the macro. This
+ * is false for, for example, pushing back lookahead from fastpeekkey(),
+ * since otherwise two fast escapes can clobber our undo.
*/
-macpush(st)
+macpush(st, canundo)
char *st;
+int canundo;
{
char tmpbuf[BUFSIZ];
if (st==0 || *st==0)
return;
+#ifdef notdef
+ if (!value(UNDOMACRO))
+ canundo = 0;
+#endif
#ifdef TRACE
if (trace)
- fprintf(trace, "macpush(%s)",st);
+ fprintf(trace, "macpush(%s), canundo=%d\n",st,canundo);
#endif
- if (strlen(vmacp) + strlen(st) > BUFSIZ)
+ if ((vmacp ? strlen(vmacp) : 0) + strlen(st) > BUFSIZ)
error("Macro too long@ - maybe recursive?");
- if (vmacp)
+ if (vmacp) {
strcpy(tmpbuf, vmacp);
+ if (!FIXUNDO)
+ canundo = 0; /* can't undo inside a macro anyway */
+ }
strcpy(vmacbuf, st);
if (vmacp)
strcat(vmacbuf, tmpbuf);
vmacp = vmacbuf;
/* arrange to be able to undo the whole macro */
- inopen = -1; /* no need to save since it had to be 1 or -1 before */
- otchng = tchng;
- saveall();
- vundkind = VMANY;
-#ifdef TRACE
- if (trace)
- fprintf(trace, "saveall for macro: undkind=%d, unddel=%d, undap1=%d, undap2=%d, dol=%d, unddol=%d, truedol=%d\n", undkind, lineno(unddel), lineno(undap1), lineno(undap2), lineno(dol), lineno(unddol), lineno(truedol));
+ if (canundo) {
+#ifdef notdef
+ otchng = tchng;
+ vsave();
+ saveall();
+ inopen = -1; /* no need to save since it had to be 1 or -1 before */
+ vundkind = VMANY;
#endif
+ vch_mac = VC_NOCHANGE;
+ }
}
+#ifdef TRACE
+visdump(s)
+char *s;
+{
+ register int i;
+
+ if (!trace) return;
+
+ fprintf(trace, "\n%s: basWTOP=%d, basWLINES=%d, WTOP=%d, WBOT=%d, WLINES=%d, WCOLS=%d, WECHO=%d\n",
+ s, basWTOP, basWLINES, WTOP, WBOT, WLINES, WCOLS, WECHO);
+ fprintf(trace, " vcnt=%d, vcline=%d, cursor=%d, wcursor=%d, wdot=%d\n",
+ vcnt, vcline, cursor-linebuf, wcursor-linebuf, wdot-zero);
+ for (i=0; i<TUBELINES; i++)
+ if (vtube[i] && *vtube[i])
+ fprintf(trace, "%d: '%s'\n", i, vtube[i]);
+ tvliny();
+}
+
+vudump(s)
+char *s;
+{
+ register line *p;
+
+ if (!trace) return;
+
+ fprintf(trace, "\n%s: undkind=%d, vundkind=%d, unddel=%d, undap1=%d, undap2=%d,\n",
+ s, undkind, vundkind, lineno(unddel), lineno(undap1), lineno(undap2));
+ fprintf(trace, " undadot=%d, dot=%d, dol=%d, unddol=%d, truedol=%d\n",
+ lineno(undadot), lineno(dot), lineno(dol), lineno(unddol), lineno(truedol));
+ fprintf(trace, " [");
+ for (p=zero+1; p<=truedol; p++)
+ fprintf(trace, "%o ", *p);
+ fprintf(trace, "]\n");
+}
+#endif
+
/*
* Get a count from the keyed input stream.
* A zero count is indistinguishable from no count.
int trapalarm();
register int c;
- signal(SIGALRM, trapalarm);
- alarm(1);
+ /*
+ * If the user has set notimeout, we wait forever for a key.
+ * If we are in a macro we do too, but since it's already
+ * buffered internally it will return immediately.
+ * In other cases we force this to die in 1 second.
+ * This is pretty reliable (VMUNIX rounds it to .5 - 1.5 secs,
+ * but UNIX truncates it to 0 - 1 secs) but due to system delays
+ * there are times when arrow keys or very fast typing get counted
+ * as separate. notimeout is provided for people who dislike such
+ * nondeterminism.
+ */
+ if (value(TIMEOUT) && inopen >= 0) {
+ signal(SIGALRM, trapalarm);
+ alarm(1);
+ }
CATCH
c = peekkey();
#ifdef MDEBUG