home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / jove-4.16-src.tgz / tar.out / bsd / jove / move.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  305 lines

  1. /************************************************************************
  2.  * This program is Copyright (C) 1986-1996 by Jonathan Payne.  JOVE is  *
  3.  * 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. #include "jove.h"
  9. #include "re.h"
  10. #include "chars.h"
  11. #include "jctype.h"
  12. #include "disp.h"
  13. #include "move.h"
  14. #include "screen.h"    /* for tabstop */
  15.  
  16. private int    line_pos;
  17.  
  18. void
  19. f_char(n)
  20. register int    n;
  21. {
  22.     if (n < 0) {
  23.         b_char(-n);
  24.         return;
  25.     }
  26.     while (--n >= 0) {
  27.         if (eolp()) {            /* Go to the next Line */
  28.             if (curline->l_next == NULL)
  29.                 break;
  30.             SetLine(curline->l_next);
  31.         } else
  32.             curchar += 1;
  33.     }
  34. }
  35.  
  36. void
  37. b_char(n)
  38. register int    n;
  39. {
  40.     if (n < 0) {
  41.         f_char(-n);
  42.         return;
  43.     }
  44.     while (--n >= 0) {
  45.         if (bolp()) {
  46.             if (curline->l_prev == NULL)
  47.                 break;
  48.             SetLine(curline->l_prev);
  49.             Eol();
  50.         } else
  51.             curchar -= 1;
  52.     }
  53. }
  54.  
  55. void
  56. ForChar()
  57. {
  58.     f_char(arg_value());
  59. }
  60.  
  61. void
  62. BackChar()
  63. {
  64.     b_char(arg_value());
  65. }
  66.  
  67. void
  68. NextLine()
  69. {
  70.     if ((curline == curbuf->b_last) && eolp())
  71.         complain(NullStr);
  72.     line_move(FORWARD, arg_value(), YES);
  73. }
  74.  
  75. void
  76. PrevLine()
  77. {
  78.     if ((curline == curbuf->b_first) && bolp())
  79.         complain(NullStr);
  80.     line_move(BACKWARD, arg_value(), YES);
  81. }
  82.  
  83. /* moves to a different line in DIR; LINE_CMD says whether this is
  84.    being called from NextLine() or PrevLine(), in which case it tries
  85.    to line up the column with the column of the current line */
  86.  
  87. void
  88. line_move(dir, n, line_cmd)
  89. int    dir,
  90.     n;
  91. bool    line_cmd;
  92. {
  93.     LinePtr    (*proc) ptrproto((LinePtr, int)) =
  94.         (dir == FORWARD) ? next_line : prev_line;
  95.     LinePtr    line;
  96.  
  97.     line = (*proc)(curline, n);
  98.     if (line == curline) {
  99.         if (dir == FORWARD)
  100.             Eol();
  101.         else
  102.             Bol();
  103.         return;
  104.     }
  105.  
  106.     if (line_cmd) {
  107.         this_cmd = LINECMD;
  108.         if (last_cmd != LINECMD)
  109.             line_pos = calc_pos(linebuf, curchar);
  110.     }
  111.     SetLine(line);        /* curline is in linebuf now */
  112.     if (line_cmd)
  113.         curchar = how_far(curline, line_pos);
  114. }
  115.  
  116. /* how_far returns what cur_char should be to be at or beyond col
  117.  * screen columns in to the line.
  118.  *
  119.  * Note: if col indicates a position in the middle of a Tab or other
  120.  * extended character, the result corresponds to that character
  121.  * (as if col had indicated its start).
  122.  *
  123.  * Note: the calc_pos, how_far, and DeTab must be in synch --
  124.  * each thinks it knows how characters are displayed.
  125.  */
  126.  
  127. int
  128. how_far(line, col)
  129. LinePtr    line;
  130. int    col;
  131. {
  132.     register char    *lp;
  133.     register int    pos;
  134.     register ZXchar    c;
  135.     char    *base;
  136.  
  137.     base = lp = lcontents(line);
  138.     pos = 0;
  139.  
  140.     do {
  141.         if ((c = ZXC(*lp)) == '\t' && tabstop != 0) {
  142.             pos += TABDIST(pos);
  143.         } else if (jisprint(c)) {
  144.             pos += 1;
  145.         } else {
  146.             if (c <= DEL)
  147.                 pos += 2;
  148.             else
  149.                 pos += 4;
  150.         }
  151.         lp += 1;
  152.     } while (pos <= col && c != '\0');
  153.  
  154.     return lp - base - 1;
  155. }
  156.  
  157. void
  158. Bol()
  159. {
  160.     curchar = 0;
  161. }
  162.  
  163. void
  164. Eol()
  165. {
  166.     curchar = length(curline);
  167. }
  168.  
  169. void
  170. Eof()
  171. {
  172.     PushPntp(curbuf->b_last);
  173.     ToLast();
  174. }
  175.  
  176. void
  177. Bof()
  178. {
  179.     PushPntp(curbuf->b_first);
  180.     ToFirst();
  181. }
  182.  
  183. /* Move forward (if dir > 0) or backward (if dir < 0) a sentence.  Deals
  184.    with all the kludgery involved with paragraphs, and moving backwards
  185.    is particularly yucky. */
  186.  
  187. private void
  188. to_sent(dir)
  189. int    dir;
  190. {
  191.     for (;;) {
  192.         Bufpos
  193.             old,    /* where we started */
  194.             *new;    /* where dosearch stopped */
  195.  
  196.         DOTsave(&old);
  197.  
  198.         new = dosearch(
  199.             "^[ \t]*$\\|[?.!]\\{''\\|[\"')\\]]\\|\\}\\{$\\|[ \t]\\}",
  200.             dir, YES);
  201.         if (new == NULL) {
  202.             if (dir == BACKWARD)
  203.                 ToFirst();
  204.             else
  205.                 ToLast();
  206.             break;
  207.         }
  208.         SetDot(new);
  209.         if (dir < 0) {
  210.             to_word(FORWARD);
  211.             if ((old.p_line != curline || old.p_char > curchar)
  212.             && (!inorder(new->p_line, new->p_char, old.p_line, old.p_char)
  213.               || !inorder(old.p_line, old.p_char, curline, curchar)))
  214.                 break;
  215.             SetDot(new);
  216.         } else {
  217.             if (blnkp(linebuf)) {
  218.                 Bol();
  219.                 b_char(1);
  220.                 if (old.p_line != curline || old.p_char < curchar)
  221.                     break;
  222.                 to_word(FORWARD);    /* Oh brother this is painful */
  223.             } else {
  224.                 curchar = REbom + 1;    /* Just after the [?.!] */
  225.                 if (LookingAt("''\\|[\"')\\]]", linebuf, curchar))
  226.                     curchar = REeom;
  227.                 break;
  228.             }
  229.         }
  230.     }
  231. }
  232.  
  233. void
  234. Bos()
  235. {
  236.     register int    num = arg_value();
  237.  
  238.     if (num < 0) {
  239.         negate_arg();
  240.         Eos();
  241.     } else {
  242.         while (--num >= 0) {
  243.             to_sent(BACKWARD);
  244.             if (bobp())
  245.                 break;
  246.         }
  247.     }
  248. }
  249.  
  250. void
  251. Eos()
  252. {
  253.     register int    num = arg_value();
  254.  
  255.     if (num < 0) {
  256.         negate_arg();
  257.         Bos();
  258.     } else {
  259.         while (--num >= 0) {
  260.             to_sent(FORWARD);
  261.             if (eobp())
  262.                 break;
  263.         }
  264.     }
  265. }
  266.  
  267. void
  268. f_word(num)
  269. register int    num;
  270. {
  271.     if (num < 0) {
  272.         while (++num <= 0) {
  273.             to_word(BACKWARD);
  274.             while (!bolp() && jisword(linebuf[curchar - 1]))
  275.                 curchar -= 1;
  276.             if (bobp())
  277.                 break;
  278.         }
  279.     } else {
  280.         while (--num >= 0) {
  281.             register char    c;
  282.  
  283.             to_word(FORWARD);
  284.             while ((c = linebuf[curchar]) != '\0' && jisword(c))
  285.                 curchar += 1;
  286.             if (eobp())
  287.                 break;
  288.         }
  289.     }
  290.     /* ??? why is the following necessary? -- DHR */
  291.     this_cmd = OTHER_CMD;    /* Semi kludge to stop some unfavorable behavior */
  292. }
  293.  
  294. void
  295. ForWord()
  296. {
  297.     f_word(arg_value());
  298. }
  299.  
  300. void
  301. BackWord()
  302. {
  303.     f_word(-arg_value());
  304. }
  305.