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

Defined functions

CopyRegion defined in line 202; used 2 times
DelBlnkLines defined in line 249; used 2 times
DelNWord defined in line 275; used 2 times
DelPWord defined in line 280; used 2 times
DelReg defined in line 193; used 3 times
DelWtSpace defined in line 231; used 16 times
del_char defined in line 126; used 2 times
dword defined in line 285; used 2 times
lremove defined in line 84; used 1 times
patchup defined in line 17; used 2 times
reg_delete defined in line 41; used 3 times
reg_kill defined in line 153; used 6 times

Defined variables

killbuf defined in line 151; used 7 times
killptr defined in line 150; used 13 times
Last modified: 1986-04-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1509
Valid CSS Valid XHTML 1.0 Strict