home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / jove / part06 / move.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-02-02  |  4.3 KB  |  266 lines

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