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: }

Defined functions

CopyRegion defined in line 214; used 4 times
DelBlnkLines defined in line 263; used 4 times
DelPChar defined in line 110; used 4 times
dword defined in line 301; used 4 times
lremove defined in line 83; used 3 times
patchup defined in line 15; used 4 times
reg_delete defined in line 40; used 4 times
reg_kill defined in line 163; used 8 times

Defined variables

killbuf defined in line 161; used 7 times
killptr defined in line 160; used 13 times
Last modified: 1988-04-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2794
Valid CSS Valid XHTML 1.0 Strict