|
|
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: #include "disp.h" ! 12: ! 13: /* Assumes that either line1 or line2 is actual the current line, so it can ! 14: put its result into linebuf. */ ! 15: ! 16: private void ! 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: int char1, ! 46: char2; ! 47: { ! 48: register Line *retline; ! 49: ! 50: if ((line1 == line2 && char1 == char2) || line2 == 0) ! 51: complain((char *) 0); ! 52: (void) fixorder(&line1, &char1, &line2, &char2); ! 53: ! 54: retline = nbufline(); /* New buffer line */ ! 55: ! 56: (void) ltobuf(line1, genbuf); ! 57: if (line1 == line2) ! 58: genbuf[char2] = '\0'; ! 59: ! 60: retline->l_prev = 0; ! 61: retline->l_dline = putline(&genbuf[char1]); ! 62: patchup(line1, char1, line2, char2); ! 63: ! 64: if (line1 == line2) ! 65: retline->l_next = 0; ! 66: else { ! 67: retline->l_next = line1->l_next; ! 68: (void) ltobuf(line2, genbuf); ! 69: genbuf[char2] = '\0'; ! 70: line2->l_dline = putline(genbuf); ! 71: /* Shorten this line */ ! 72: } ! 73: ! 74: if (line1 != line2) { ! 75: line1->l_next = line2->l_next; ! 76: if (line1->l_next) ! 77: line1->l_next->l_prev = line1; ! 78: else ! 79: curbuf->b_last = line1; ! 80: line2->l_next = 0; ! 81: } ! 82: ! 83: return retline; ! 84: } ! 85: ! 86: void ! 87: lremove(line1, line2) ! 88: register Line *line1, ! 89: *line2; ! 90: { ! 91: Line *next = line1->l_next; ! 92: ! 93: if (line1 == line2) ! 94: return; ! 95: line1->l_next = line2->l_next; ! 96: if (line1->l_next) ! 97: line1->l_next->l_prev = line1; ! 98: else ! 99: curbuf->b_last = line1; ! 100: lfreereg(next, line2); /* Put region at end of free line list. */ ! 101: } ! 102: ! 103: /* delete character forward */ ! 104: ! 105: void ! 106: DelNChar() ! 107: { ! 108: del_char(FORWARD, arg_value(), YES); ! 109: } ! 110: ! 111: /* Delete character backward */ ! 112: ! 113: void ! 114: DelPChar() ! 115: { ! 116: if (MinorMode(OverWrite)) { ! 117: int count = min(arg_value(), curchar); ! 118: ! 119: b_char(count); ! 120: ! 121: /* overwrite with spaces */ ! 122: set_arg_value(count); ! 123: LastKeyStruck = ' '; ! 124: SelfInsert(); ! 125: ! 126: b_char(count); ! 127: } else ! 128: del_char(BACKWARD, arg_value(), YES); ! 129: } ! 130: ! 131: /* Delete some characters. If deleting forward then call for_char ! 132: to the final position otherwise call back_char. Then delete the ! 133: region between the two with patchup(). */ ! 134: ! 135: void ! 136: del_char(dir, num, OK_kill) ! 137: int dir, ! 138: num, ! 139: OK_kill; ! 140: { ! 141: Bufpos before, ! 142: after; ! 143: int killp = (OK_kill && (abs(num) > 1)); ! 144: ! 145: DOTsave(&before); ! 146: if (dir == FORWARD) ! 147: f_char(num); ! 148: else ! 149: b_char(num); ! 150: if (before.p_line == curline && before.p_char == curchar) ! 151: complain((char *) 0); ! 152: if (killp) ! 153: reg_kill(before.p_line, before.p_char, 1); ! 154: else { ! 155: DOTsave(&after); ! 156: (void) fixorder(&before.p_line, &before.p_char, &after.p_line, &after.p_char); ! 157: patchup(before.p_line, before.p_char, after.p_line, after.p_char); ! 158: lremove(before.p_line, after.p_line); ! 159: } ! 160: } ! 161: ! 162: /* This kills a region between point, and line1/char1 and puts it on ! 163: the kill-ring. If the last command was one of the kill commands, ! 164: the region is appended (prepended if backwards) to the last entry. */ ! 165: ! 166: int killptr = 0; ! 167: Line *killbuf[NUMKILLS]; ! 168: ! 169: void ! 170: reg_kill(line2, char2, dot_moved) ! 171: Line *line2; ! 172: int char2, ! 173: dot_moved; ! 174: { ! 175: Line *nl, ! 176: *line1 = curline; ! 177: int char1 = curchar; ! 178: int backwards; ! 179: ! 180: backwards = !fixorder(&line1, &char1, &line2, &char2); ! 181: /* This is a kludge! But it possible for commands that don't ! 182: know which direction they are deleting in (e.g., delete ! 183: previous word could have been called with a negative argument ! 184: in which case, it wouldn't know that it really deleted ! 185: forward. */ ! 186: ! 187: if (!dot_moved) ! 188: backwards = !backwards; ! 189: ! 190: DotTo(line1, char1); ! 191: ! 192: nl = reg_delete(line1, char1, line2, char2); ! 193: ! 194: if (last_cmd != KILLCMD) { ! 195: killptr = ((killptr + 1) % NUMKILLS); ! 196: lfreelist(killbuf[killptr]); ! 197: killbuf[killptr] = nl; ! 198: } else { ! 199: Line *lastln = lastline(nl); ! 200: ! 201: if (backwards) ! 202: (void) DoYank(nl, 0, lastln, length(lastln), killbuf[killptr], 0, (Buffer *) 0); ! 203: else { ! 204: Line *olastln = lastline(killbuf[killptr]); ! 205: ! 206: (void) DoYank(nl, 0, lastln, length(lastln), olastln, length(olastln), (Buffer *) 0); ! 207: } ! 208: } ! 209: this_cmd = KILLCMD; ! 210: } ! 211: ! 212: void ! 213: DelReg() ! 214: { ! 215: register Mark *mp = CurMark(); ! 216: ! 217: reg_kill(mp->m_line, mp->m_char, 0); ! 218: } ! 219: ! 220: /* Save a region. A pretend kill. */ ! 221: ! 222: void ! 223: CopyRegion() ! 224: { ! 225: register Line *nl; ! 226: register Mark *mp; ! 227: register int status; ! 228: ! 229: mp = CurMark(); ! 230: if (mp->m_line == curline && mp->m_char == curchar) ! 231: complain((char *) 0); ! 232: ! 233: killptr = ((killptr + 1) % NUMKILLS); ! 234: if (killbuf[killptr]) ! 235: lfreelist(killbuf[killptr]); ! 236: nl = killbuf[killptr] = nbufline(); ! 237: SavLine(nl, NullStr); ! 238: nl->l_next = nl->l_prev = 0; ! 239: ! 240: status = inorder(mp->m_line, mp->m_char, curline, curchar); ! 241: if (status == -1) ! 242: return; ! 243: ! 244: if (status) ! 245: (void) DoYank(mp->m_line, mp->m_char, curline, curchar, ! 246: nl, 0, (Buffer *) 0); ! 247: else ! 248: (void) DoYank(curline, curchar, mp->m_line, mp->m_char, ! 249: nl, 0, (Buffer *) 0); ! 250: } ! 251: ! 252: void ! 253: DelWtSpace() ! 254: { ! 255: register char *ep = &linebuf[curchar], ! 256: *sp = &linebuf[curchar]; ! 257: ! 258: while (*ep == ' ' || *ep == '\t') ! 259: ep += 1; ! 260: while (sp > linebuf && (sp[-1] == ' ' || sp[-1] == '\t')) ! 261: sp -= 1; ! 262: if (sp != ep) { ! 263: curchar = sp - linebuf; ! 264: DFixMarks(curline, curchar, curline, curchar + (ep - sp)); ! 265: strcpy(sp, ep); ! 266: makedirty(curline); ! 267: modify(); ! 268: } ! 269: } ! 270: ! 271: void ! 272: DelBlnkLines() ! 273: { ! 274: register Mark *dot; ! 275: int all; ! 276: ! 277: if (!blnkp(&linebuf[curchar])) ! 278: return; ! 279: dot = MakeMark(curline, curchar, M_FLOATER); ! 280: all = !blnkp(linebuf); ! 281: while (blnkp(linebuf) && curline->l_prev) ! 282: SetLine(curline->l_prev); ! 283: all |= (firstp(curline)); ! 284: Eol(); ! 285: DelWtSpace(); ! 286: line_move(FORWARD, 1, NO); ! 287: while (blnkp(linebuf) && !eobp()) { ! 288: DelWtSpace(); ! 289: del_char(FORWARD, 1, NO); ! 290: } ! 291: if (!all && !eobp()) ! 292: open_lines(1); ! 293: ToMark(dot); ! 294: DelMark(dot); ! 295: } ! 296: ! 297: private void ! 298: dword(forward) ! 299: int forward; ! 300: { ! 301: Bufpos savedot; ! 302: ! 303: DOTsave(&savedot); ! 304: if (forward) ! 305: ForWord(); ! 306: else ! 307: BackWord(); ! 308: reg_kill(savedot.p_line, savedot.p_char, 1); ! 309: } ! 310: ! 311: void ! 312: DelNWord() ! 313: { ! 314: dword(1); ! 315: } ! 316: ! 317: void ! 318: DelPWord() ! 319: { ! 320: dword(0); ! 321: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.