📄 insdelchar.c
字号:
k = shif_im1 - shift[i]; /* # chars to delete */#ifdef DEBUG if (outf) fprintf(outf, "deleting %d chars at column %d\n", k, l);#endif /* DEBUG */ _pos(ln, l); _delchars(k); /* Update the data structures accordingly */ for (j=i; j<matchcount; j++) /* old is now shifted */ shift[j] += k; for (j=l; j<maxlen; j++) ob[j] = ob[j+k]; olen -= k; if (old) old->length = olen; low[i] = hi_im1 + 1;#ifdef DEBUG _dump_shift(old, new, ln, 1, "deletion", i);#endif } }}/* * Second half of ins/del char strategy: do all insertions and replacements. */#ifdef DEBUGstatic_idc_inschar(old, new, ln)register struct line *old, *new;#elsestatic_idc_inschar(old, ln)register struct line *old;#endif /* DEBUG */{ register int i, j, m, lhs_col; register chtype *p, *q, *r, *t; register int num_inserted, olhs_col, low_i, shif_i, i_1;#ifdef DEBUG if (outf) fprintf(outf, "doing insert chars\n");#endif /* Do the insertions for each match found */ for (i = 1, i_1 = 0; i <= matchcount; i++, i_1++) {#ifdef DEBUG if (outf) fprintf(outf, "comparing shift[i=%d] = %d to shift[i-1=%d] = %d.\n", i, shift[i], i_1, shift[i-1]);#endif /* DEBUG */ if (shift[i] >= shift[i_1]) { /* if not a deletion */ /* * Overall strategy: two parts, first overstrike * things that do not need to be inserted, then * insert the rest. * * Q w x y z A B old * Q d e f g h i A B new * * In the above example, we overstrike the "defg" over * the old "wxyz", then insert "hi". */ low_i = low[i]; shif_i = shift[i]; /* * Overstrike section. * Find the first part of the area to overstrike. * p points to the first char in the area, q to * the last char in the area. (In a pure insertion, * q will point to the last char of the prev field.) */ lhs_col = high[i_1] + 1; /* lhs of area */ if (lhs_col >= low_i) { /* 0 or negative # of chars to show */ continue; } p = nb + lhs_col; /* beg of area in new */ q = nb + low_i - 1 - shif_i; /* end .. in new */ if (p <= q) { int rightedge; _pos(ln, lhs_col);#ifdef DEBUG if (outf) fprintf(outf, "ins-overstriking %d chars at column %d\n", q - p + 1, lhs_col);#endif /* DEBUG */ _showstring(ln, lhs_col, p, q, old); /* do ovrstk */ rightedge = lhs_col + q - p + 1; if (olen < rightedge) olen = rightedge; /* update internal copy of screen */ r = ob + lhs_col; while (p <= q) /* update old buffer */ *r++ = *p++;#ifdef DEBUG _dump_shift(old, new, ln, 1, "ins-replacement", i);#endif } /* now do insertion part */ num_inserted = shif_i - shift[i_1]; if (num_inserted > 0) { lhs_col = low_i - shif_i; /* lhs_col is pos of insertion */ p = q + 1; /* p, q: area to be inserted */ q = p + num_inserted - 1; olhs_col = p - nb;#ifdef DEBUG if (outf) fprintf(outf, "inserting %d chars at column %d\n", num_inserted, olhs_col);# define putd(x) if (outf) fprintf(outf, "x=%d\n", x);#endif /* DEBUG */ /* update some of what is about to happen */ olen += num_inserted; if (olen > columns) olen = columns; if (maxlen < olen) maxlen = olen; m = olhs_col + num_inserted;#ifdef DEBUG putd(olhs_col); putd(p-nb); putd(q-nb); putd(num_inserted); putd(m); putd(olen); putd(maxlen);#endif /* DEBUG */ /* do the insertion */ _pos(ln, lhs_col); /* * This if stmt should also check * the relative cost of doing * (parm_ich x n) versus * (smir + n*ich + rmir). */ if (num_inserted > 1 && parm_ich) { /* * Insert the characters and * then draw on the blanks. */ _clearhl(); _inschars(num_inserted); /* fix up what _inschars did */ for (j = maxlen - 1, r = ob + j, t = ob + j - num_inserted; j-- >= m; ) *r-- = *t--; for (r = ob + olhs_col, j = num_inserted; j-- > 0; ) *r++ = ' '; /* * Now output the string * in non-insert mode. */ _showstring(ln, lhs_col, p, q, (struct line *) NULL); /* fix up what _showstring did */ for (r = ob + olhs_col; p <= q; ) *r++ = *p++; } else { /* * Type the characters in * "insert mode". This includes * having to send insert_character * before each character * is output. */ _insmode(1); _showstring(ln, lhs_col, p, q, (struct line *) NULL); /* fix up what _showstring did */ for (j = maxlen - 1, r = ob + j, t = ob + j - num_inserted; j-- >= m; ) *r-- = *t--; for (r = ob + olhs_col; p <= q; ) *r++ = *p++; } _insmode(0); /* finish fixing up notion of what happened */ for (j = i; j < matchcount; j++) shift[j] -= num_inserted; if (old) old->length = olen;#ifdef DEBUG _dump_shift(old, new, ln, 1, "insertion", i);#endif } } } /* Clean up any junk off the end of the line */ if (olen > high[matchcount]) { _pos(ln, high[matchcount]); _clreol(); if (old) old->length = high[matchcount]; }}#ifdef DEBUG/* * Debugging routine to show current state of affairs. old is what's * physically on the screen (reflecting any partial updates so far) * and new is what we want. ln is the line number. */static_dump_idc(old, new, ln)register struct line *old, *new;{ register int n, j; if (!outf) return; fprintf(outf, "_id_char(%x, %x, %d)\n", old, new, ln); fprintf(outf, "old: "); fprintf(outf, "%8x: ", old); if (old == NULL) { fprintf(outf, "()\n"); } else { fprintf(outf, "%4d ", old->length); for (j=0; j<old->length; j++) { n = old->body[j]; if (n & A_ATTRIBUTES) putc('\'', outf); n &= 0177; fprintf(outf, "%c", n>=' ' ? n : '.'); } fprintf(outf, "\n"); } fprintf(outf, "new: "); fprintf(outf, "%8x: ", new); if (new == NULL) { fprintf(outf, "()\n"); } else { fprintf(outf, "%4d ", new->length); for (j=0; j<new->length; j++) { n = new->body[j]; if (n & A_ATTRIBUTES) putc('\'', outf); n &= 0177; fprintf(outf, "%c", n>=' ' ? n : '.'); } fprintf(outf, "\n"); } /* dump a ruler */ fprintf(outf, " "); for (j = 0; j < maxlen; j++) fprintf(outf, (j % 10) ? (j % 5 ? " " : "+" ) : "%1d", j / 10); fprintf(outf, "\n");}/* Debugging routine to print out status of low, high and shift arrays.*/static_dump_shift(old, new, ln, dumpidc, pass, i)register struct line *old, *new;char *pass;int ln, dumpidc, i;{ register int j; if (!outf) return; if (dumpidc) { fprintf(outf, "After %s pass i=%d\n", pass, i); _dump_idc(old, new, ln); }#define olow(j) low[j] - shift[j]#define ohigh(j) high[j] - shift[j] fprintf(outf, " i low high shift olow ohigh\n"); for (j=0; j<=matchcount; j++) fprintf(outf, "%2d %d %d %d %d %d\n", j, low[j], high[j], shift[j], olow(j), ohigh(j)); fprintf(outf, "\n"); fflush(outf);}#endif/* * Dump the string running from first to last out to the terminal. * Take into account attributes, and attempt to take advantage of * large pieces of white space and text that's already there. * oldline is the old text of the line. * * Variable naming convention: *x means "extension", e.g. a rubber band * that briefly looks ahead; *c means a character version of an otherwise * chtype pointer; old means what was on the screen before this call; * left means the char 1 space to the left. */static_showstring(sline, scol, first, last, oldlp)int sline, scol;chtype *first, *last; /* pointers to beg/end of chtype string to be shown */struct line *oldlp; /* pointer to old line being overwritten */{ register int hl = 0; /* nontrivial line, highlighted or with holes */ int prevhl=SP->virt_gr, thishl; /* highlight state tty is in */ register chtype *p, *px; /* current char being considered */ register chtype *oldp, *oldpx; /* stuff under p and px */ register char *pc, *pcx; /* like p, px but in char buffer */ chtype *tailoldp; /* last valid oldp */ int oldlen; /* length of old line */ int lcol, lrow; /* position on screen */ chtype oldc; /* char at oldp */ chtype leftattr, leftnewc; /* attr,char to left of p */ int diff_cookies; /* magic cookies changed */ int diff_attrs; /* highlights changed */ chtype *oldline;#ifdef NONSTANDARD static#endif /* NONSTANDARD */ char firstc[256], *lastc; /* char copy of input first, last */#ifdef DEBUG if(outf) fprintf(outf, "_showstring((%d,%d) %d:'", sline, scol, last-first+1); if(outf) for (p=first; p<=last; p++) { thishl = *p & A_ATTRIBUTES; if (thishl) putc('\'', outf); putc(*p & A_CHARTEXT, outf); } if(outf) fprintf(outf, "').\n");#endif if (last-first > columns) { _pos(lines-1, 0);#ifndef NONSTANDARD fprintf(stderr, "Bad call to _showstring, first %x, last %x,\ diff %d\pcx\n", first, last, last-first);#endif abort(); } if (oldlp) { oldline = oldlp->body; oldp = oldline+scol; } else oldp = 0; for (p=first,lastc=firstc; p<=last; ) { if (*p & A_ATTRIBUTES) hl++; /* attributes on the line */ if (oldp && (*oldp++ & A_ATTRIBUTES)) hl++; /* attributes on old line */ if (*p==' ' && (px=p+1,*px++==' ') && *px++==' ' && *px==' ') hl++; /* a run of at least 4 blanks */ *lastc++ = *p & A_CHARTEXT; p++; /* On a separate line due to C optimizer bug */#ifdef FULLDEBUG if(outf) fprintf(outf, "p %x '%c' %o, lastc %x %o, oldp %x %o, hl %d\n", p, p[-1], p[-1], lastc, lastc[-1], oldp, oldp ? oldp[-1] : 0, hl);#endif } lastc--; lcol = scol; lrow = sline; if (oldlp) { oldline = oldlp->body; oldlen = oldlp->length; /* Check for runs of stuff that's already there. */ for (p=first,oldp=oldline+lcol; p<=last; p++,oldp++) { if (*p==*oldp && (px=p+1,oldpx=oldp+1,*px++==*oldpx++) && *px++==*oldpx++ && *px==*oldpx) hl++; /* a run of at least 4 matches */#ifdef FULLDEBUG if(outf) fprintf(outf, "p %x '%c%c%c%c', oldp %x '%c%c%c%c', hl %d\n", p, p[0], p[1], p[2], p[3], oldp, oldp[0], oldp[1], oldp[2], oldp[3], hl);#endif } } else { oldline = NULL; oldlen = 0; } if (!hl) { /* Simple, common case. Do it fast. */ _pos(lrow, lcol); _hlmode(0); _writechars(firstc, lastc, first[-1]); return; }#ifdef DEBUG if(outf) { fprintf(outf, "oldlp %x, oldline %x, oldlen %d 0x%x\n", oldlp, oldline, oldlen, oldlen); fprintf(outf, "old body('"); if (oldlp) for (p=oldline; p<oldline+oldlen; p++) { if (*p & A_ATTRIBUTES) fprintf(outf, "'"); fprintf(outf, "%c", *p & A_CHARTEXT); } fprintf(outf, "').\n"); }#endif if (scol > 0) oldc = first[-1]; else oldc = ' '; tailoldp = oldline + oldlen; for (p=first, oldp=oldline+lcol, pc=firstc; pc<=lastc; p++,oldp++,pc++) { thishl = *p & A_ATTRIBUTES;#ifdef DEBUG if(outf) fprintf(outf, "prevhl %o, thishl %o\n", prevhl, thishl);#endif if (p > first) leftnewc = p[-1]; else leftnewc = ' '; leftattr = leftnewc & A_ATTRIBUTES; diff_cookies = magic_cookie_glitch>=0 && ((oldc&A_ATTRIBUTES) != leftattr); diff_attrs = ceol_standout_glitch && (((*p)&A_ATTRIBUTES) != leftattr); if (oldp >= tailoldp) oldc = ' '; else oldc = *oldp;#ifdef xxDEBUG/* This causes core dump on Sun and other systems that trap on ref to loc 0 */ if(outf) fprintf(outf, "p %x *p %o, pc %x *pc %o, oldp %x, *oldp %o, lcol %d, lrow %d, oldc %o\n", p, p ? *p : 0, pc, pc ? *pc : 0, oldp, oldp ? *oldp : 0, lcol, lrow, oldc);#endif if (*p != oldc || SP->virt_irm == 1 || diff_cookies || diff_attrs || insert_null_glitch && oldp >= oldline+oldlen) { register int n; _pos(lrow, lcol); /* * All HP terminals except 2621 (as of 1984). * This forces it to be right no matter what * was there before. This is quite nonoptimal * but the alternative is to maintain a map of * cookie locations on the screen (you can't * get rid of a cookie short of clr_eol). * * There is a case where this is wrong: if you * draw something highlighted, then overwrite it * with something unhighlighted, then overwrite * it again with something highlighted, it will * only highlight the first character. This could * be fixed by removing the 3rd clause below, at the * cost of much worse performance in average cases * for simple highlighting. To make this work * right in every case, this clause has been * commented out. * * If you must use an HP terminal, HP has an ANSI * option for most of its terminals that does * things right. You can order that option. * This code deals with the standard HP terminals. */ if (ceol_standout_glitch && thishl != (oldc&A_ATTRIBUTES) /* && (oldc&A_ATTRIBUTES) */ ) {#ifdef FULLDEBUG if(outf) fprintf(outf, "ceol %d, thishl %d, prevhl %d\n", ceol_standout_glitch, thishl, prevhl);#endif _forcehl(); } /* Force highlighting to be right */ _hlmode(thishl); if (thishl != prevhl) { if (magic_cookie_glitch >= 0) { _sethl(); p += magic_cookie_glitch; oldp += magic_cookie_glitch; pc += magic_cookie_glitch; lcol += magic_cookie_glitch; } } /* * Gather chunks of chars together, to be more * efficient, and to allow repeats to be detected. * Not done for blanks on cookie terminals because * the last one might be a cookie. */ if (magic_cookie_glitch<0 || *pc != ' ') { for (px=p+1,oldpx=oldp+1; px<=last && *p==*px; px++,oldpx++) { if(!(repeat_char && oldpx<tailoldp && *p==*oldpx)) break; } px--; oldpx--; n = px - p; pcx = pc + n; } else { n = 0; pcx = pc; } _writechars(pc, pcx, leftnewc); lcol += n; pc += n; p += n; oldp += n; prevhl = thishl; } lcol++; } if (magic_cookie_glitch >= 0 && prevhl) { /* Have to turn off highlighting at end of line */ _hlmode(0); _sethl(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -