|
|
1.1 ! root 1: /************************************************************************* ! 2: * This program is copyright (C) 1985, 1986 by Jonathan Payne. It is * ! 3: * provided to you without charge for use only on a licensed Unix * ! 4: * system. You may copy JOVE provided that this notice is included with * ! 5: * the copy. You may not sell copies of this program or versions * ! 6: * modified for use on microcomputer systems, unless the copies are * ! 7: * included with a Unix system distribution and the source is provided. * ! 8: *************************************************************************/ ! 9: ! 10: /* Routines to perform all kinds of deletion. */ ! 11: ! 12: #include "jove.h" ! 13: ! 14: /* Assumes that either line1 or line2 is actual the current line, so it can ! 15: put its result into linebuf. */ ! 16: ! 17: patchup(line1, char1, line2, char2) ! 18: Line *line1, ! 19: *line2; ! 20: register int char1, ! 21: char2; ! 22: { ! 23: if (line1 != line2) ! 24: ChkWindows(line1, line2); ! 25: DotTo(line1, char1); ! 26: modify(); ! 27: linecopy(linebuf, curchar, lcontents(line2) + char2); ! 28: ! 29: /* The following is a redisplay optimization. */ ! 30: if (line1 != line2 && (char1 == 0 && char2 == 0)) ! 31: line1->l_dline = line2->l_dline; ! 32: ! 33: DFixMarks(line1, char1, line2, char2); ! 34: makedirty(curline); ! 35: } ! 36: ! 37: /* Deletes the region by unlinking the lines in the middle, ! 38: and patching things up. The unlinked lines are still in ! 39: order. */ ! 40: ! 41: Line * ! 42: reg_delete(line1, char1, line2, char2) ! 43: Line *line1, ! 44: *line2; ! 45: { ! 46: register Line *retline; ! 47: ! 48: if ((line1 == line2 && char1 == char2) || line2 == 0) ! 49: complain((char *) 0); ! 50: (void) fixorder(&line1, &char1, &line2, &char2); ! 51: ! 52: retline = nbufline(); /* New buffer line */ ! 53: ! 54: (void) ltobuf(line1, genbuf); ! 55: if (line1 == line2) ! 56: genbuf[char2] = '\0'; ! 57: ! 58: retline->l_prev = 0; ! 59: retline->l_dline = putline(&genbuf[char1]); ! 60: patchup(line1, char1, line2, char2); ! 61: ! 62: if (line1 == line2) ! 63: retline->l_next = 0; ! 64: else { ! 65: retline->l_next = line1->l_next; ! 66: (void) ltobuf(line2, genbuf); ! 67: genbuf[char2] = '\0'; ! 68: line2->l_dline = putline(genbuf); ! 69: /* Shorten this line */ ! 70: } ! 71: ! 72: if (line1 != line2) { ! 73: line1->l_next = line2->l_next; ! 74: if (line1->l_next) ! 75: line1->l_next->l_prev = line1; ! 76: else ! 77: curbuf->b_last = line1; ! 78: line2->l_next = 0; ! 79: } ! 80: ! 81: return retline; ! 82: } ! 83: ! 84: lremove(line1, line2) ! 85: register Line *line1, ! 86: *line2; ! 87: { ! 88: Line *next = line1->l_next; ! 89: ! 90: if (line1 == line2) ! 91: return; ! 92: line1->l_next = line2->l_next; ! 93: if (line1->l_next) ! 94: line1->l_next->l_prev = line1; ! 95: else ! 96: curbuf->b_last = line1; ! 97: lfreereg(next, line2); /* Put region at end of free line list. */ ! 98: } ! 99: ! 100: /* Delete character forward */ ! 101: ! 102: DelNChar() ! 103: { ! 104: del_char(1); ! 105: } ! 106: ! 107: /* Delete character backward */ ! 108: ! 109: DelPChar() ! 110: { ! 111: if (MinorMode(OverWrite)) { ! 112: int count = min(exp, curchar); ! 113: ! 114: DoTimes(BackChar(), count); ! 115: LastKeyStruck = ' '; /* can you say gross? */ ! 116: DoTimes(SelfInsert(), count); ! 117: DoTimes(BackChar(), count); ! 118: } else ! 119: del_char(0); ! 120: } ! 121: ! 122: /* Delete some characters. If deleting `forward' then call for_char ! 123: to the final position otherwise call back_char. Then delete the ! 124: region between the two with patchup(). */ ! 125: ! 126: del_char(forward) ! 127: { ! 128: Bufpos before, ! 129: after; ! 130: int killp = (exp_p && abs(exp) > 1); ! 131: ! 132: DOTsave(&before); ! 133: (forward) ? ForChar() : BackChar(); ! 134: if (before.p_line == curline && before.p_char == curchar) ! 135: complain((char *) 0); ! 136: if (killp) ! 137: reg_kill(before.p_line, before.p_char, 1); ! 138: else { ! 139: DOTsave(&after); ! 140: (void) fixorder(&before.p_line, &before.p_char, &after.p_line, &after.p_char); ! 141: patchup(before.p_line, before.p_char, after.p_line, after.p_char); ! 142: lremove(before.p_line, after.p_line); ! 143: } ! 144: } ! 145: ! 146: /* This kills a region between point, and line1/char1 and puts it on ! 147: the kill-ring. If the last command was one of the kill commands, ! 148: the region is appended (prepended if backwards) to the last entry. */ ! 149: ! 150: int killptr = 0; ! 151: Line *killbuf[NUMKILLS]; ! 152: ! 153: reg_kill(line2, char2, dot_moved) ! 154: Line *line2; ! 155: { ! 156: Line *nl, ! 157: *line1 = curline; ! 158: int char1 = curchar; ! 159: int backwards; ! 160: ! 161: backwards = !fixorder(&line1, &char1, &line2, &char2); ! 162: /* This is a kludge! But it possible for commands that don't ! 163: know which direction they are deleting in (e.g., delete ! 164: previous word could have been called with a negative argument ! 165: in which case, it wouldn't know that it really deleted ! 166: forward. */ ! 167: ! 168: if (!dot_moved) ! 169: backwards = !backwards; ! 170: ! 171: DotTo(line1, char1); ! 172: ! 173: nl = reg_delete(line1, char1, line2, char2); ! 174: ! 175: if (last_cmd != KILLCMD) { ! 176: killptr = ((killptr + 1) % NUMKILLS); ! 177: lfreelist(killbuf[killptr]); ! 178: killbuf[killptr] = nl; ! 179: } else { ! 180: Line *lastln = lastline(nl); ! 181: ! 182: if (backwards) ! 183: (void) DoYank(nl, 0, lastln, length(lastln), killbuf[killptr], 0, (Buffer *) 0); ! 184: else { ! 185: Line *olastln = lastline(killbuf[killptr]); ! 186: ! 187: (void) DoYank(nl, 0, lastln, length(lastln), olastln, length(olastln), (Buffer *) 0); ! 188: } ! 189: } ! 190: this_cmd = KILLCMD; ! 191: } ! 192: ! 193: DelReg() ! 194: { ! 195: register Mark *mp = CurMark(); ! 196: ! 197: reg_kill(mp->m_line, mp->m_char, 0); ! 198: } ! 199: ! 200: /* Save a region. A pretend kill. */ ! 201: ! 202: CopyRegion() ! 203: { ! 204: register Line *nl; ! 205: register Mark *mp; ! 206: register int status; ! 207: ! 208: mp = CurMark(); ! 209: if (mp->m_line == curline && mp->m_char == curchar) ! 210: complain((char *) 0); ! 211: ! 212: killptr = ((killptr + 1) % NUMKILLS); ! 213: if (killbuf[killptr]) ! 214: lfreelist(killbuf[killptr]); ! 215: nl = killbuf[killptr] = nbufline(); ! 216: SavLine(nl, NullStr); ! 217: nl->l_next = nl->l_prev = 0; ! 218: ! 219: status = inorder(mp->m_line, mp->m_char, curline, curchar); ! 220: if (status == -1) ! 221: return; ! 222: ! 223: if (status) ! 224: (void) DoYank(mp->m_line, mp->m_char, curline, curchar, ! 225: nl, 0, (Buffer *) 0); ! 226: else ! 227: (void) DoYank(curline, curchar, mp->m_line, mp->m_char, ! 228: nl, 0, (Buffer *) 0); ! 229: } ! 230: ! 231: DelWtSpace() ! 232: { ! 233: register char *ep = &linebuf[curchar], ! 234: *sp = &linebuf[curchar]; ! 235: ! 236: while (*ep == ' ' || *ep == '\t') ! 237: ep++; ! 238: while (sp > linebuf && *(sp - 1) == ' ' || *(sp - 1) == '\t') ! 239: sp--; ! 240: if (sp != ep) { ! 241: curchar = sp - linebuf; ! 242: DFixMarks(curline, curchar, curline, curchar + (ep - sp)); ! 243: strcpy(sp, ep); ! 244: makedirty(curline); ! 245: modify(); ! 246: } ! 247: } ! 248: ! 249: DelBlnkLines() ! 250: { ! 251: register Mark *dot; ! 252: int all; ! 253: ! 254: exp = 1; ! 255: if (!blnkp(&linebuf[curchar])) ! 256: return; ! 257: dot = MakeMark(curline, curchar, FLOATER); ! 258: all = !blnkp(linebuf); ! 259: while (blnkp(linebuf) && curline->l_prev) ! 260: SetLine(curline->l_prev); ! 261: all |= (firstp(curline)); ! 262: Eol(); ! 263: DelWtSpace(); ! 264: line_move(FORWARD, NO); ! 265: while (blnkp(linebuf) && !eobp()) { ! 266: DelWtSpace(); ! 267: DelNChar(); ! 268: } ! 269: if (!all && !eobp()) ! 270: OpenLine(); ! 271: ToMark(dot); ! 272: DelMark(dot); ! 273: } ! 274: ! 275: DelNWord() ! 276: { ! 277: dword(1); ! 278: } ! 279: ! 280: DelPWord() ! 281: { ! 282: dword(0); ! 283: } ! 284: ! 285: dword(forward) ! 286: { ! 287: Bufpos savedot; ! 288: ! 289: DOTsave(&savedot); ! 290: forward ? ForWord() : BackWord(); ! 291: reg_kill(savedot.p_line, savedot.p_char, 1); ! 292: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.