home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / ex / ex_vget.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  6KB  |  382 lines

  1. /* Copyright (c) 1979 Regents of the University of California */
  2. #include "ex.h"
  3. #include "ex_tty.h"
  4. #include "ex_vis.h"
  5.  
  6. /*
  7.  * Input routines for open/visual.
  8.  * We handle upper case only terminals in visual and reading from the
  9.  * echo area here as well as notification on large changes
  10.  * which appears in the echo area.
  11.  */
  12.  
  13. /*
  14.  * Return the key.
  15.  */
  16. ungetkey(c)
  17.     char c;
  18. {
  19.  
  20.     if (Peekkey != ATTN)
  21.         Peekkey = c;
  22. }
  23.  
  24. /*
  25.  * Return a keystroke, but never a ^@.
  26.  */
  27. getkey()
  28. {
  29.     register char c;
  30.  
  31.     do
  32.         c = getbr();
  33.     while (c == 0);
  34.     return (c);
  35. }
  36.  
  37. /*
  38.  * Tell whether next keystroke would be a ^@.
  39.  */
  40. peekbr()
  41. {
  42.  
  43.     Peekkey = getbr();
  44.     return (Peekkey == 0);
  45. }
  46.  
  47. short    precbksl;
  48.  
  49. /*
  50.  * Get a keystroke, including a ^@.
  51.  * If an key was returned with ungetkey, that
  52.  * comes back first.  Next comes unread input (e.g.
  53.  * from repeating commands with .), and finally new
  54.  * keystrokes.
  55.  *
  56.  * The hard work here is in mapping of \ escaped
  57.  * characters on upper case only terminals.
  58.  */
  59. getbr()
  60. {
  61.     char ch;
  62.     register int c, d;
  63.     register char *colp;
  64.  
  65. getATTN:
  66.     if (Peekkey) {
  67.         c = Peekkey;
  68.         Peekkey = 0;
  69.         return (c);
  70.     }
  71.     if (vglobp) {
  72.         if (*vglobp)
  73.             return (*vglobp++);
  74.         return (ESCAPE);
  75.     }
  76. #ifdef TRACE
  77.     if (trace)
  78.         fflush(trace);
  79. #endif
  80.     flusho();
  81. again:
  82.     if (read(0, &ch, 1) != 1) {
  83.         if (errno == EINTR)
  84.             goto getATTN;
  85.         error("Input read error");
  86.     }
  87.     c = ch & TRIM;
  88.  
  89. #ifdef UCVISUAL
  90.     /*
  91.      * The algorithm here is that of the UNIX kernel.
  92.      * See the description in the programmers manual.
  93.      */
  94.     if (UPPERCASE) {
  95.         if (isupper(c))
  96.             c = tolower(c);
  97.         if (c == '\\') {
  98.             if (precbksl < 2)
  99.                 precbksl++;
  100.             if (precbksl == 1)
  101.                 goto again;
  102.         } else if (precbksl) {
  103.             d = 0;
  104.             if (islower(c))
  105.                 d = toupper(c);
  106.             else {
  107.                 colp = "({)}!|^~'~";
  108.                 while (d = *colp++)
  109.                     if (d == c) {
  110.                         d = *colp++;
  111.                         break;
  112.                     } else
  113.                         colp++;
  114.             }
  115.             if (precbksl == 2) {
  116.                 if (!d) {
  117.                     Peekkey = c;
  118.                     precbksl = 0;
  119.                     c = '\\';
  120.                 }
  121.             } else if (d)
  122.                 c = d;
  123.             else {
  124.                 Peekkey = c;
  125.                 precbksl = 0;
  126.                 c = '\\';
  127.             }
  128.         }
  129.         if (c != '\\')
  130.             precbksl = 0;
  131.     }
  132. #endif
  133. #ifdef TRACE
  134.     if (trace) {
  135.         if (!techoin) {
  136.             tfixnl();
  137.             techoin = 1;
  138.             fprintf(trace, "*** Input: ");
  139.         }
  140.         tracec(c);
  141.     }
  142. #endif
  143.     return (c);
  144. }
  145.  
  146. /*
  147.  * Get a key, but if a delete, quit or attention
  148.  * is typed return 0 so we will abort a partial command.
  149.  */
  150. getesc()
  151. {
  152.     register int c;
  153.  
  154.     c = getkey();
  155.     switch (c) {
  156.  
  157.     case ATTN:
  158.     case QUIT:
  159.         ungetkey(c);
  160.         return (0);
  161.  
  162.     case ESCAPE:
  163.         return (0);
  164.     }
  165.     return (c);
  166. }
  167.  
  168. /*
  169.  * Peek at the next keystroke.
  170.  */
  171. peekkey()
  172. {
  173.  
  174.     Peekkey = getkey();
  175.     return (Peekkey);
  176. }
  177.  
  178. /*
  179.  * Read a line from the echo area, with single character prompt c.
  180.  * A return value of 1 means the user blewit or blewit away.
  181.  */
  182. readecho(c)
  183.     char c;
  184. {
  185.     char *sc = cursor;
  186.     int (*OP)();
  187.     bool waste;
  188.  
  189.     if (WBOT == WECHO)
  190.         vclean();
  191.     else
  192.         vclrech(0);
  193.     splitw++;
  194.     vgoto(WECHO, 0);
  195.     putchar(c);
  196.     vclreol();
  197.     vgoto(WECHO, 1);
  198.     cursor = linebuf; linebuf[0] = 0; genbuf[0] = c;
  199.     if (peekbr()) {
  200.         if (!INS[0] || (INS[0] & (QUOTE|TRIM)) == OVERBUF)
  201.             goto blewit;
  202.         vglobp = INS;
  203.     }
  204.     OP = Pline; Pline = normline;
  205.     ignore(vgetline(0, genbuf + 1, &waste));
  206.     vscrap();
  207.     Pline = OP;
  208.     if (Peekkey != ATTN && Peekkey != QUIT) {
  209.         cursor = sc;
  210.         vclreol();
  211.         return (0);
  212.     }
  213. blewit:
  214.     splitw = 0;
  215.     vclean();
  216.     vshow(dot, NOLINE);
  217.     vnline(sc);
  218.     return (1);
  219. }
  220.  
  221. /*
  222.  * A complete command has been defined for
  223.  * the purposes of repeat, so copy it from
  224.  * the working to the previous command buffer.
  225.  */
  226. setLAST()
  227. {
  228.  
  229.     if (vglobp)
  230.         return;
  231.     lastreg = vreg;
  232.     lasthad = Xhadcnt;
  233.     lastcnt = Xcnt;
  234.     *lastcp = 0;
  235.     CP(lastcmd, workcmd);
  236. }
  237.  
  238. /*
  239.  * Gather up some more text from an insert.
  240.  * If the insertion buffer oveflows, then destroy
  241.  * the repeatability of the insert.
  242.  */
  243. addtext(cp)
  244.     char *cp;
  245. {
  246.  
  247.     if (vglobp)
  248.         return;
  249.     addto(INS, cp);
  250.     if ((INS[0] & (QUOTE|TRIM)) == OVERBUF)
  251.         lastcmd[0] = 0;
  252. }
  253.  
  254. setDEL()
  255. {
  256.  
  257.     setBUF(DEL);
  258. }
  259.  
  260. /*
  261.  * Put text from cursor upto wcursor in BUF.
  262.  */
  263. setBUF(BUF)
  264.     register char *BUF;
  265. {
  266.     register int c;
  267.     register char *wp = wcursor;
  268.  
  269.     c = *wp;
  270.     *wp = 0;
  271.     BUF[0] = 0;
  272.     addto(BUF, cursor);
  273.     *wp = c;
  274. }
  275.  
  276. addto(buf, str)
  277.     register char *buf, *str;
  278. {
  279.  
  280.     if ((buf[0] & (QUOTE|TRIM)) == OVERBUF)
  281.         return;
  282.     if (strlen(buf) + strlen(str) + 1 >= VBSIZE) {
  283.         buf[0] = OVERBUF;
  284.         return;
  285.     }
  286.     ignore(strcat(buf, str));
  287. }
  288.  
  289. /*
  290.  * Note a change affecting a lot of lines, or non-visible
  291.  * lines.  If the parameter must is set, then we only want
  292.  * to do this for open modes now; return and save for later
  293.  * notification in visual.
  294.  */
  295. noteit(must)
  296.     bool must;
  297. {
  298.     register int sdl = destline, sdc = destcol;
  299.  
  300.     if (notecnt < 2 || !must && state == VISUAL)
  301.         return (0);
  302.     splitw++;
  303.     if (WBOT == WECHO)
  304.         vmoveitup(1);
  305.     vigoto(WECHO, 0);
  306.     printf("%d %sline", notecnt, notesgn);
  307.     if (notecnt > 1)
  308.         putchar('s');
  309.     if (*notenam) {
  310.         printf(" %s", notenam);
  311.         if (*(strend(notenam) - 1) != 'e')
  312.             putchar('e');
  313.         putchar('d');
  314.     }
  315.     vclreol();
  316.     notecnt = 0;
  317.     if (state != VISUAL)
  318.         vcnt = vcline = 0;
  319.     splitw = 0;
  320.     if (state == ONEOPEN || state == CRTOPEN)
  321.         vup1();
  322.     destline = sdl; destcol = sdc;
  323.     return (1);
  324. }
  325.  
  326. /*
  327.  * Rrrrringgggggg.
  328.  * If possible, use flash (VB).
  329.  */
  330. beep()
  331. {
  332.  
  333.     if (VB)
  334.         vputp(VB, 0);
  335.     else
  336.         vputc(CTRL(g));
  337. }
  338.  
  339. /*
  340.  * Map the command input character c,
  341.  * for keypads and labelled keys which do cursor
  342.  * motions.  I.e. on an adm3a we might map ^K to ^P.
  343.  * DM1520 for example has a lot of mappable characters.
  344.  */
  345. map(c)
  346.     register int c;
  347. {
  348.     register int d;
  349.     register char *cp = MA;
  350.  
  351.     if (cp == 0)
  352.         return (c);
  353.     while (d = *cp++) {
  354.         if (c == d)
  355.             return (*cp);
  356.         if (*cp++ == 0)
  357.             return (c);
  358.     }
  359.     return (c);
  360. }
  361.  
  362. /*
  363.  * Get a count from the keyed input stream.
  364.  * A zero count is indistinguishable from no count.
  365.  */
  366. vgetcnt()
  367. {
  368.     register int c, cnt;
  369.  
  370.     cnt = 0;
  371.     for (;;) {
  372.         c = getkey();
  373.         if (!isdigit(c))
  374.             break;
  375.         cnt *= 10, cnt += c - '0';
  376.     }
  377.     ungetkey(c);
  378.     Xhadcnt = 1;
  379.     Xcnt = cnt;
  380.     return(cnt);
  381. }
  382.