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