home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / program / d / elvis / Source / c / input < prev    next >
Encoding:
Text File  |  1989-12-31  |  5.7 KB  |  299 lines

  1. /* input.c */
  2.  
  3. /* Author:
  4.  *    Steve Kirkendall
  5.  *    16820 SW Tallac Way
  6.  *    Beaverton, OR 97006
  7.  *    kirkenda@jove.cs.pdx.edu, or ...uunet!tektronix!psueea!jove!kirkenda
  8.  */
  9.  
  10.  
  11. /* This file contains the input() function, which implements vi's INPUT mode */
  12.  
  13. #include "vi.h"
  14.  
  15.  
  16. /* This function allows the user to replace an existing (possibly zero-length)
  17.  * chunk of text with typed-in text.  It returns the MARK of the last character
  18.  * that the user typed in.
  19.  */
  20. MARK input(from, to, when)
  21.     MARK    from;    /* where to start inserting text */
  22.     MARK    to;    /* extent of text to delete */
  23.     int    when;    /* either WHEN_VIINP or WHEN_VIREP */
  24. {
  25.     char    key[2];    /* key char followed by '\0' char */
  26.     char    *build;    /* used in building a newline+indent string */
  27.     char    *scan;    /* used while looking at the indent chars of a line */
  28.     MARK    m;
  29.  
  30. #ifdef DEBUG
  31.     /* if "from" and "to" are reversed, complain */
  32.     if (from > to)
  33.     {
  34.         msg("ERROR: input(%ld:%d, %ld:%d)",
  35.             markline(from), markidx(from),
  36.             markline(to), markidx(to));
  37.         return MARK_UNSET;
  38.     }
  39. #endif
  40.  
  41.     key[1] = 0;
  42.  
  43.     /* if we're replacing text with new text, save the old stuff */
  44.     /* (Alas, there is no easy way to save text for replace mode) */
  45.     if (from != to)
  46.     {
  47.         cut(from, to);
  48.     }
  49.  
  50.     ChangeText
  51.     {
  52.         /* if doing a dot command, then reuse the previous text */
  53.         if (doingdot)
  54.         {
  55.             /* delete the text thats there now */
  56.             if (from != to)
  57.             {
  58.                 delete(from, to);
  59.             }
  60.  
  61.             cutname('.');
  62.             cursor = paste(from, FALSE, TRUE) + 1L;
  63.         }
  64.         else
  65.         {
  66.             /* if doing a change within the line... */
  67.             if (from != to && markline(from) == markline(to))
  68.             {
  69.                 /* mark the end of the text with a "$" */
  70.                 change(to - 1, to, "$");
  71.             }
  72.             else
  73.             {
  74.                 /* delete the old text right off */
  75.                 if (from != to)
  76.                 {
  77.                     delete(from, to);
  78.                 }
  79.                 to = from;
  80.             }
  81.  
  82.             /* handle autoindent of the first line, maybe */
  83.             cursor = from;
  84.             if (*o_autoindent && markline(cursor) > 1L && markidx(cursor) == 0)
  85.             {
  86.                 /* Only autoindent blank lines. */
  87.                 pfetch(markline(cursor));
  88.                 if (plen == 0)
  89.                 {
  90.                     /* Okay, we really want to autoindent */
  91.                     pfetch(markline(cursor) - 1L);
  92.                     for (scan = ptext, build = tmpblk.c;
  93.                          *scan == ' ' || *scan == '\t';
  94.                          )
  95.                     {
  96.                         *build++ = *scan++;
  97.                     }
  98.                     if (build > tmpblk.c)
  99.                     {
  100.                         *build = '\0';
  101.                         add(cursor, tmpblk.c);
  102.                         cursor += (build - tmpblk.c);
  103.                     }
  104.                 }
  105.             }
  106.  
  107.             /* repeatedly add characters from the user */
  108.             for (;;)
  109.             {
  110.                 /* Get a character */
  111.                 redraw(cursor, TRUE);
  112.                 key[0] = getkey(when);
  113.  
  114.                 /* if whitespace & wrapmargin is set & we're
  115.                 /* past the warpmargin, then change the
  116.                 /* whitespace character into a newline
  117.                  */
  118.                 if ((*key == ' ' || *key == '\t')
  119.                  && *o_wrapmargin != 0)
  120.                 {
  121.                     pfetch(markline(cursor));
  122.                     if (idx2col(cursor, ptext, TRUE) > (*o_wrapmargin & 0xff))
  123.                     {
  124.                         *key = '\n';
  125.                     }
  126.                 }
  127.  
  128.                 /* process it */
  129.                 switch (*key)
  130.                 {
  131.                   case ctrl('['):
  132.                     goto BreakBreak;
  133.  
  134.                   case ctrl('U'):
  135.                     if (markline(cursor) == markline(from))
  136.                     {
  137.                         cursor == from;
  138.                     }
  139.                     else
  140.                     {
  141.                         cursor &= ~(BLKSIZE - 1);
  142.                     }
  143.                     break;
  144.  
  145.                   case '\b':
  146.                   case ctrl('D'):
  147.                     if (cursor <= from)
  148.                     {
  149.                         beep();
  150.                     }
  151.                     else if (markidx(cursor) == 0)
  152.                     {
  153.                         cursor -= BLKSIZE;
  154.                         pfetch(markline(cursor));
  155.                         cursor += plen;
  156.                     }
  157.                     else
  158.                     {
  159.                         cursor--;
  160.                     }
  161.                     break;
  162.  
  163.                   case ctrl('W'):
  164.                     m = movebword(cursor, 1L);
  165.                     if (markline(m) == markline(cursor) && m >= from)
  166.                     {
  167.                         cursor = m;
  168.                         if (from > cursor)
  169.                         {
  170.                             from = cursor;
  171.                         }
  172.                     }
  173.                     else
  174.                     {
  175.                         beep();
  176.                     }
  177.                     break;
  178.  
  179.                   case '\n':
  180.                   case '\r':
  181.                     build = tmpblk.c;
  182.                     *build++ = '\n';
  183.                     if (*o_autoindent)
  184.                     {
  185.                         pfetch(markline(cursor));
  186.                         for (scan = ptext; *scan == ' ' || *scan == '\t'; )
  187.                         {
  188.                             *build++ = *scan++;
  189.                         }
  190.                     }
  191.                     *build = 0;
  192.                     if (cursor >= to && when != WHEN_VIREP)
  193.                     {
  194.                         add(cursor, tmpblk.c);
  195.                     }
  196.                     else
  197.                     {
  198.                         change(cursor, to, tmpblk.c);
  199.                     }
  200.                     redraw(cursor, TRUE);
  201.                     to = cursor = (cursor & ~(BLKSIZE - 1))
  202.                             + BLKSIZE
  203.                             + (build - tmpblk.c) - 1;
  204.                     break;
  205.  
  206.                   case ctrl('A'):
  207.                     if (cursor < to)
  208.                     {
  209.                         delete(cursor, to);
  210.                     }
  211.                     cutname('.');
  212.                     to = cursor = paste(cursor, FALSE, TRUE) + 1L;
  213.                     break;
  214.  
  215.                   case ctrl('V'):
  216.                     if (cursor >= to && when != WHEN_VIREP)
  217.                     {
  218.                         add(cursor, "^");
  219.                     }
  220.                     else
  221.                     {
  222.                         change(cursor, to, "^");
  223.                     }
  224.                     redraw(cursor, TRUE);
  225.                     *key = getkey(0);
  226.                     if (*key == '\n')
  227.                     {
  228.                         /* '\n' too hard to handle */
  229.                         *key = '\r';
  230.                     }
  231.                     change(cursor, cursor + 1, key);
  232.                     cursor++;
  233.                     if (cursor > to)
  234.                     {
  235.                         to = cursor;
  236.                     }
  237.                     break;
  238.  
  239.                   case ctrl('L'):
  240.                   case ctrl('R'):
  241.                     redraw(MARK_UNSET, FALSE);
  242.                     break;
  243.  
  244.                   case ctrl('T'):
  245.                     *key = '\t';
  246.                     /* fall through to default case... */
  247.  
  248.                   default:
  249.                     if (cursor >= to && when != WHEN_VIREP)
  250.                     {
  251.                         add(cursor, key);
  252.                         cursor++;
  253.                         to = cursor;
  254.                     }
  255.                     else
  256.                     {
  257.                         pfetch(markline(cursor));
  258.                         if (markidx(cursor) == plen)
  259.                         {
  260.                             add(cursor, key);
  261.                         }
  262.                         else
  263.                         {
  264.                             change(cursor, cursor + 1, key);
  265.                         }
  266.                         cursor++;
  267.                     }
  268.                 } /* end switch(*key) */
  269.             } /* end for(;;) */
  270. BreakBreak:;
  271.  
  272.             /* delete any excess characters */
  273.             if (cursor < to)
  274.             {
  275.                 delete(cursor, to);
  276.             }
  277.  
  278.         } /* end if doingdot else */
  279.  
  280.     } /* end ChangeText */
  281.  
  282.     /* put the new text into a cut buffer for possible reuse */
  283.     if (!doingdot)
  284.     {
  285.         blksync();
  286.         cutname('.');
  287.         cut(from, cursor);
  288.     }
  289.  
  290.     /* move to last char that we inputted, unless it was newline */
  291.     if (markidx(cursor) != 0)
  292.     {
  293.         cursor--;
  294.     }
  295.  
  296.     rptlines = 0L;
  297.     return cursor;
  298. }
  299.