home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume7 / rvi / part4 / rv_word.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  3.6 KB  |  210 lines

  1. #include "rv.h"
  2. #include <ctype.h>
  3.  
  4. extern boolean change_flag;    /* The current command is a change cmd */
  5.  
  6. static INT matchtype;
  7.  
  8. static boolean
  9. isword(c, bigflag)
  10. /*
  11.  * Return TRUE if c is part of a word
  12.  */
  13. INT c;
  14. boolean bigflag;
  15. {
  16.     INT oldmatchtype;
  17.  
  18.     if (bigflag)
  19.         return (!isspace(c));
  20.     oldmatchtype = matchtype;
  21.     if (isalpha(c) || isdigit(c) || c == '_') {
  22.         matchtype = 1;
  23.         return (oldmatchtype != 2);
  24.     }
  25.     if (!isspace(c)) {
  26.         matchtype = 2;
  27.         return (oldmatchtype != 1);
  28.     }
  29.     matchtype = 0;
  30.     return FALSE;
  31. }
  32.     
  33.  
  34.  
  35. boolean
  36. word_search(c, cmd_count, cmdflag)
  37. /*
  38.  * Scan forward and backward for words
  39.  */
  40. INT c;
  41. INT cmd_count;
  42. boolean cmdflag;    /* TRUE if this is a cursor movement command */
  43. {
  44.     register INT i, len, method;
  45.     register char *s;
  46.     register struct sc_screen *sc;
  47.     INT    direction = 1;
  48.     boolean big_word = FALSE, end_word = FALSE, newline_flag = FALSE;
  49.  
  50.     sc = &screen;
  51.  
  52.     switch (c) {
  53. case 'w':
  54.     /*
  55.      * Scan forward for a word
  56.      */
  57.     direction = 1;
  58.     big_word = FALSE;
  59.     break;
  60.  
  61. case 'W':
  62.     /*
  63.      * Scan forward for a big word
  64.      */
  65.     direction = 1;
  66.     big_word = TRUE;
  67.     break;
  68.  
  69. case 'b':
  70.     /*
  71.      * Scan backward for a word
  72.      */
  73.     direction = -1;
  74.     big_word = FALSE;
  75.     break;
  76.  
  77. case 'B':
  78.     /*
  79.      * Scan backward for a big word
  80.      */
  81.     direction = -1;
  82.     big_word = TRUE;
  83.     break;
  84.  
  85. case 'e':
  86.     /*
  87.      * Scan forward for the end of a word
  88.      */
  89.     direction = 1;
  90.     big_word = FALSE;
  91.     end_word = TRUE;
  92.     break;
  93.  
  94. case 'E':
  95.     /*
  96.      * Scan forward for the end of a big word
  97.      */
  98.     direction = 1;
  99.     big_word = TRUE;
  100.     end_word = TRUE;
  101.     break;
  102.  
  103. default:
  104.     return FALSE;
  105.  
  106.     } /* End switch */
  107.  
  108.  
  109.     s = sc->sc_curline->li_text;
  110.     len = sc->sc_curline->li_width;
  111.     sc->sc_validcol = TRUE;
  112.     i = sc->sc_column;
  113.     for (; cmd_count > 0; --cmd_count) {
  114.         /*
  115.          * Build a search algorithm
  116.          */
  117.         matchtype = 0;
  118.         if (len <= 0)
  119.             goto beyondline;
  120.         if (newline_flag) {
  121.             method = isword(s[i], big_word) ? 1 : 0;
  122.             newline_flag = FALSE;
  123.         } else {
  124.             INT temptype;
  125.  
  126.             method = isword(s[i], big_word) ? 2 : 0;
  127.             temptype = matchtype;
  128.             if (direction > 0 && i < len-1 ||
  129.                     direction < 0 && i > 0)
  130.                 method |= isword(s[i+direction], big_word) ?
  131.                     1 : 0;
  132.             matchtype = temptype;
  133.         }
  134.         if (direction < 0 || end_word)
  135.             method |= 4;
  136.         if (method < 4 && change_flag)
  137.             method = 4;  /* Emulating a vi kludge.. */
  138.         else
  139.             switch (method) {
  140.     case 0:
  141.     case 1:            method = 2;
  142.                 break;
  143.     case 2:
  144.     case 3:            method = 3;
  145.                 break;
  146.     case 7:            method = 4;
  147.                 break;
  148.     case 4:
  149.     case 5:            method = 6;
  150.                 break;
  151.     case 6:            method = 7;
  152.                 break;
  153.             }
  154.         /*
  155.          * Execute the search algorithm 
  156.          */
  157.         if (method & 1)
  158.             while (isword(s[i], big_word)) {
  159.                 i += direction;
  160.                 if (i < 0 || i >= len)
  161.                     goto beyondline;
  162.             }
  163.         if (method & 2)
  164.             while (!isword(s[i], big_word)) {
  165.                 i += direction;
  166.                 if (i < 0 || i >= len)
  167.                     goto beyondline;
  168.             }
  169.         if (method & 4)
  170.             for (;;) {
  171.                 i += direction;
  172.                 if (i < 0 || i >= len ||
  173.                         !isword(s[i], big_word)) {
  174.                     i -= direction;
  175.                     break;
  176.                 }
  177.             }
  178.         continue;
  179. beyondline:
  180.         if (cmdflag) {
  181.             move_abs_cursor(sc->sc_lineno+direction, 0);
  182.             s = sc->sc_curline->li_text;
  183.             len = sc->sc_curline->li_width;
  184.             sc->sc_firstline = sc->sc_lineno;
  185.             sc->sc_lastline = sc->sc_lineno;
  186.             if (errflag)
  187.                 break;
  188.             if (len == 0 || direction > 0)
  189.                 i = 0;
  190.             else
  191.                 i = len-1;
  192.             sc->sc_column = sc->sc_firstcol = sc->sc_lastcol = i;
  193.             sc->sc_validcol = TRUE;
  194.             ++cmd_count;
  195.             newline_flag = TRUE;
  196.         } else
  197.             break;
  198.     }
  199.     if (direction >= 0) {
  200.         sc->sc_lastcol = i;
  201.         if (!cmdflag && method < 4 && !change_flag)
  202.             sc->sc_lastcol--;
  203.     } else {
  204.         if (!cmdflag)
  205.             sc->sc_lastcol--;
  206.         sc->sc_firstcol = i;
  207.     }
  208.     return (sc->sc_firstcol <= sc->sc_lastcol);
  209. }
  210.