char *oglobp;
char d;
line *addr;
- int ind;
+ int ind, nlput;
+ int shouldpo = 0;
int onumber, olist, (*OPline)(), (*OPutchar)();
+ vch_mac = VC_NOTINMAC;
+
/*
* If we started as a vi command (on the command line)
* then go process initial commands (recover, next or tag).
fprintf(trace,"pcb=%c,",peekkey());
#endif
op = getkey();
+ maphopcnt = 0;
do {
/*
* Keep mapping the char as long as it changes.
ungetkey(c);
goto looptop;
}
+ if (!value(REMAP))
+ break;
+ if (++maphopcnt > 256)
+ error("Infinite macro loop");
} while (c != op);
/*
/*
* ^L Clear screen e.g. after transmission error.
*/
- case CTRL(l):
- vclear();
- vdirty(0, vcnt);
- /* fall into... */
/*
* ^R Retype screen, getting rid of @ lines.
* If in open, equivalent to ^L.
+ * On terminals where the right arrow key sends
+ * ^L we make ^R act like ^L, since there is no
+ * way to get ^L. These terminals (adm31, tvi)
+ * are intelligent so ^R is useless. Soroc
+ * will probably foul this up, but nobody has
+ * one of them.
*/
+ case CTRL(l):
case CTRL(r):
+ if (c == CTRL(l) || (KR && *KR==CTRL(l))) {
+ vclear();
+ vdirty(0, vcnt);
+ }
if (state != VISUAL) {
/*
* Get a clean line, throw away the
* in vmacbuf, point vglobp there and punt.
*/
case '@':
- c = getkey();
+ c = getesc();
+ if (c == 0)
+ continue;
if (c == '@')
c = lastmac;
if (isupper(c))
char tmpbuf[BUFSIZ];
regbuf(c,tmpbuf,sizeof(vmacbuf));
- macpush(tmpbuf);
+ macpush(tmpbuf, 1);
ONERR
lastmac = 0;
splitw = 0;
/*
* ^F Window forwards, with 2 lines of continuity.
- * Count gives new screen size.
+ * Count repeats.
*/
case CTRL(f):
vsave();
- if (hadcnt)
- vsetsiz(cnt);
if (vcnt > 2) {
- dot += (vcnt - vcline) - 2;
+ dot += (vcnt - vcline) - 2 + (cnt-1)*basWLINES;
vcnt = vcline = 0;
}
vzop(0, 0, '+');
*/
case CTRL(b):
vsave();
- if (hadcnt)
- vsetsiz(cnt);
if (one + vcline != dot && vcnt > 2) {
- dot -= vcline - 2;
+ dot -= vcline - 2 + (cnt-1)*basWLINES;
vcnt = vcline = 0;
}
vzop(0, 0, '^');
if (cnt > (i = dol - dot + 1))
cnt = i;
vsave();
+ vmacchng(1);
setLAST();
cursor = strend(linebuf);
vremote(cnt, join, 0);
case 'O':
case 'o':
voOpen(c, cnt);
+ vmacchng(1);
continue;
/*
case '~':
{
char mbuf[4];
+ setLAST();
mbuf[0] = 'r';
mbuf[1] = *cursor;
mbuf[2] = cursor[1]==0 ? 0 : ' ';
mbuf[3] = 0;
if (isalpha(mbuf[1]))
mbuf[1] ^= ' '; /* toggle the case */
- macpush(mbuf);
+ macpush(mbuf, 1);
}
continue;
* is doomed, unless R when all is, and save the
* current line in a the undo temporary buffer.
*/
+ vmacchng(1);
setLAST();
vcursat(cursor);
prepapp();
vnoapp();
doomed = c == 'R' ? 10000 : 0;
- vundkind = VCHNG;
+ if(FIXUNDO)
+ vundkind = VCHNG;
+ vmoving = 0;
CP(vutmp, linebuf);
/*
onintr();
/* fall into... */
+#ifdef notdef
/*
* q Quit back to command mode, unless called as
* vi on command line in which case dont do it
vrepaint(cursor);
continue;
}
+#endif
/* fall into... */
/*
*/
case 'Q':
vsave();
+ /*
+ * If we are in the middle of a macro, throw away
+ * the rest and fix up undo.
+ * This code copied from getbr().
+ */
+ if (vmacp) {
+ vmacp = 0;
+ if (inopen == -1) /* don't screw up undo for esc esc */
+ vundkind = VMANY;
+ inopen = 1; /* restore old setting now that macro done */
+ }
return;
+
+ /*
+ * ZZ Like :x
+ */
+ case 'Z':
+ forbid(getkey() != 'Z');
+ oglobp = globp;
+ globp = "x";
+ vclrech(0);
+ goto gogo;
+
/*
* P Put back text before cursor or before current
* line. If text was whole lines goes back
case 'P':
case 'p':
vmoving = 0;
- forbid (inopen < 0);
+#ifdef notdef
+ forbid (!vreg && value(UNDOMACRO) && inopen < 0);
+#endif
/*
* If previous delete was partial line, use an
* append or insert to put it back so as to
* sure there is something to put back.
*/
forbid (!vreg && unddol == dol);
+ /*
+ * If we just did a macro the whole buffer is in
+ * the undo save area. We don't want to put THAT.
+ */
+ forbid (vundkind == VMANY && undkind==UNDALL);
vsave();
+ vmacchng(1);
setLAST();
i = 0;
if (vreg && partreg(vreg) || !vreg && pkill[0]) {
* We thus put a catch in here. If we didn't and
* there was an error we would end up in command mode.
*/
+ addr = dol; /* old dol */
CATCH
vremote(1, vreg ? putreg : put, vreg);
ONERR
}
ENDCATCH
splitw = 0;
+ nlput = dol - addr + 1;
if (!i) {
/*
* Increment undap1, undap2 to make up
* for their incorrect initialization in the
* routine vremote before calling put/putreg.
*/
- undap1++, undap2++;
+ if (FIXUNDO)
+ undap1++, undap2++;
vcline++;
- }
+ nlput--;
- /*
- * After a put want current line first line,
- * and dot was made the last line put in code run
- * so far. This is why we increment vcline above,
- * and decrease (usually) dot here.
- */
- dot = undap1;
- vreplace(vcline, i, undap2 - undap1);
+ /*
+ * After a put want current line first line,
+ * and dot was made the last line put in code
+ * run so far. This is why we increment vcline
+ * above and decrease dot here.
+ */
+ dot -= nlput - 1;
+ }
+#ifdef TRACE
+ if (trace)
+ fprintf(trace, "vreplace(%d, %d, %d), undap1=%d, undap2=%d, dot=%d\n", vcline, i, nlput, lineno(undap1), lineno(undap2), lineno(dot));
+#endif
+ vreplace(vcline, i, nlput);
if (state != VISUAL) {
/*
* Special case in open mode.
vsave();
goto doinit;
+#ifdef TIOCLGET
+ /*
+ * ^Z: suspend editor session and temporarily return
+ * to shell. Only works on Berkeley tty driver.
+ */
+ case CTRL(z):
+ forbid(dosusp == 0 || !ldisc);
+ vsave();
+ oglobp = globp;
+ globp = "stop";
+ goto gogo;
+#endif
+
/*
* : Read a command from the echo area and
* execute it in command mode.
esave[0] = 0;
goto fixup;
}
+ getDOT();
/*
* Use the visual undo buffer to store the global
* string for command mode, since it is idle right now.
* command mode). This is clumsy.
*/
d = peekc; ungetchar(0);
+ if (shouldpo) {
+ /*
+ * So after a "Hit return..." ":", we do
+ * another "Hit return..." the next time
+ */
+ pofix();
+ shouldpo = 0;
+ }
CATCH
/*
* Save old values of options so we can
* a write command there, but its not
* worth worrying about.
*/
- if (tchng && tchng != i)
+ if (FIXUNDO && tchng && tchng != i)
vundkind = VMANY, cursor = 0;
/*
*/
if (vcnt < 0 && Peekkey == ':') {
getDOT();
+ shouldpo = 1;
continue;
}
+ shouldpo = 0;
/*
* In the case where the file being edited is
vcnt = -vcnt;
if (state == VISUAL)
vclear();
- else if (state == CRTOPEN)
+ else if (state == CRTOPEN) {
vcnt = 0;
+ }
}
/*
* u undo the last changing command.
*/
case 'u':
- vundo();
+ vundo(1);
continue;
/*
addr1 = dot;
addr2 = dot + cnt - 1;
- if (inopen > 0)
- undap1 = undap2 = dot;
inglobal = 0;
+ if (FIXUNDO)
+ undap1 = undap2 = dot;
(*f)(arg);
inglobal = oing;
- if (inopen > 0)
+ if (FIXUNDO)
vundkind = VMANY;
vmcurs = 0;
}
char temp[LBSIZE];
CP(temp, linebuf);
- if (vundkind == VCHNG || vundkind == VCAPU) {
+ if (FIXUNDO && vundkind == VCHNG || vundkind == VCAPU) {
/*
* If the undo state is saved in the temporary buffer
* vutmp, then we sync this into the temp file so that