static void rmultlinerep(int savecnt, int endsrccol) { int tmpcnt = 2; /* 1st replacement counts as 1 repeat */ /* Save linebuf into temp file before moving off the line. */ vsave(); /* * At this point the temp file contains the line followed by '\n', * which is preceded by indentation if autoindent is set. * '\n' must be repeated [savecnt - 1] more times in the temp file. * dot is the current line containing the '\n'. Decrement dot so that * vdoappend() will append each '\n' before the current '\n'. * This will allow only the last line to contain any autoindent * characters. */ --dot; --vcline; /* * Append after dot. */ while (tmpcnt <= savecnt) { linebuf[0] = '\0'; /* append linebuf below current line in temp file */ vdoappend(linebuf); vcline++; ++tmpcnt; } /* set the current line to the line after the last '\n' */ ++dot; ++vcline; /* point cursor after (linebuf + endsrccol) */ vcursaft(linebuf + endsrccol); }
/* * Change operator. * * In a single line we mark the end of the changed area with '$'. * On multiple whole lines, we clear the lines first. * Across lines with both wcursor and wdot given, we delete * and sync then append (but one operation for undo). */ void vchange(int c) { register char *cp; register int i, ind, cnt; line *addr; if (wdot) { /* * Change/delete of lines or across line boundaries. */ if ((cnt = xdw()) < 0) return; getDOT(); if (wcursor && cnt == 1) { /* * Not really. */ wdot = 0; if (c == EOF) { vdelete(c); return; } goto smallchange; } if (cursor && wcursor) { /* * Across line boundaries, but not * necessarily whole lines. * Construct what will be left. */ *cursor = 0; strcpy(genbuf, linebuf); getline(*wdot); if (strlen(genbuf) + strlen(wcursor) > LBSIZE - 2) { getDOT(); beep(); return; } strcat(genbuf, wcursor); if (c == EOF && *vpastwh(genbuf) == 0) { /* * Although this is a delete * spanning line boundaries, what * would be left is all white space, * so take it all away. */ wcursor = 0; getDOT(); op = 0; notpart(lastreg); notpart('1'); vdelete(c); return; } ind = -1; } else if (c == EOF && wcursor == 0) { vdelete(c); return; } else #ifdef LISPCODE /* * We are just substituting text for whole lines, * so determine the first autoindent. */ if (value(LISP) && value(AUTOINDENT)) ind = lindent(dot); else #endif ind = whitecnt(linebuf); i = vcline >= 0 ? LINE(vcline) : WTOP; /* * Delete the lines from the buffer, * and remember how the partial stuff came about in * case we are told to put. */ addr = dot; vremote(cnt, delete, 0); setpk(); notenam = "delete"; if (c != EOF) notenam = "change"; /* * If DEL[0] were nonzero, put would put it back * rather than the deleted lines. */ DEL[0] = 0; if (cnt > 1) killU(); /* * Now hack the screen image coordination. */ vreplace(vcline, cnt, 0); wdot = NOLINE; noteit(0); vcline--; if (addr <= dol) dot--; /* * If this is a across line delete/change, * cursor stays where it is; just splice together the pieces * of the new line. Otherwise generate a autoindent * after a S command. */ if (ind >= 0) { *genindent(ind) = 0; vdoappend(genbuf); } else { vmcurs = cursor; strcLIN(genbuf); vdoappend(linebuf); } /* * Indicate a change on hardcopies by * erasing the current line. */ if (c != EOF && state != VISUAL && state != HARDOPEN) { int oldhold = hold; hold |= HOLDAT, vclrlin(i, dot), hold = oldhold; } /* * Open the line (logically) on the screen, and * update the screen tail. Unless we are really a delete * go off and gather up inserted characters. */ vcline++; if (vcline < 0) vcline = 0; vopen(dot, i); vsyncCL(); noteit(1); if (c != EOF) { if (ind >= 0) { cursor = linebuf; linebuf[0] = 0; vfixcurs(); } else { ind = 0; vcursat(cursor); } vappend('x', 1, ind); return; } if (*cursor == 0 && cursor > linebuf) cursor += skipleft(linebuf, cursor); vrepaint(cursor); return; } smallchange: /* * The rest of this is just low level hacking on changes * of small numbers of characters. */ if (wcursor < linebuf) wcursor = linebuf; if (cursor == wcursor) { beep(); return; } i = vdcMID(); cp = cursor; if (state != HARDOPEN) vfixcurs(); /* * Put out the \\'s indicating changed text in hardcopy, * or mark the end of the change with $ if not hardcopy. */ if (state == HARDOPEN) bleep(i, cp); else { int c, d, n; vcursbef(wcursor); d = skipleft(linebuf, wcursor); nextc(c, &wcursor[d], n); if (colsc(c) > 1) putchar(' '); putchar('$'); i = cindent(); } /* * Remember the deleted text for possible put, * and then prepare and execute the input portion of the change. */ cursor = cp; setDEL(); CP(cursor, wcursor); if (state != HARDOPEN) { vcursaft(cursor - 1); doomed = i - cindent(); } else { /* sethard(); wcursor = cursor; cursor = linebuf; vgoto(outline, value(NUMBER) << 3); vmove(); */ doomed = 0; } prepapp(); vappend('c', 1, 0); }