home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / jove414s.zip / delete.c < prev    next >
C/C++ Source or Header  |  1991-07-06  |  7KB  |  322 lines

  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. }
  322.