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