Annotation of coherent/d/usr/bin/elvis/tio.c, revision 1.1.1.1

1.1       root        1: /* tio.c */
                      2: 
                      3: /* Author:
                      4:  *     Steve Kirkendall
                      5:  *     16820 SW Tallac Way
                      6:  *     Beaverton, OR 97006
                      7:  *     [email protected], or ...uunet!tektronix!psueea!jove!kirkenda
                      8:  */
                      9: 
                     10: 
                     11: /* This file contains terminal I/O functions */
                     12: 
                     13: #include "config.h"
                     14: #if BSD || COHERENT
                     15: # include <setjmp.h>
                     16: #endif
                     17: #include <signal.h>
                     18: #include "vi.h"
                     19: 
                     20: 
                     21: /* This function reads in a line from the terminal. */
                     22: int vgets(prompt, buf, bsize)
                     23:        char    prompt; /* the prompt character, or '\0' for none */
                     24:        char    *buf;   /* buffer into which the string is read */
                     25:        int     bsize;  /* size of the buffer */
                     26: {
                     27:        int     len;    /* how much we've read so far */
                     28:        int     ch;     /* a character from the user */
                     29:        int     quoted; /* is the next char quoted? */
                     30:        int     tab;    /* column position of cursor */
                     31:        char    widths[132];    /* widths of characters */
                     32: #ifndef NO_DIGRAPH
                     33:        int     erased; /* 0, or first char of a digraph */
                     34: #endif
                     35: 
                     36:        /* show the prompt */
                     37:        move(LINES - 1, 0);
                     38:        tab = 0;
                     39:        if (prompt)
                     40:        {
                     41:                addch(prompt);
                     42:                tab = 1;
                     43:        }
                     44:        clrtoeol();
                     45:        refresh();
                     46: 
                     47:        /* read in the line */
                     48: #ifndef NO_DIGRAPH
                     49:        erased =
                     50: #endif
                     51:        quoted = len = 0;
                     52:        for (;;)
                     53:        {
                     54:                ch = getkey(quoted ? 0 : WHEN_EX);
                     55: 
                     56:                /* some special conversions */
                     57:                if (ch == ctrl('D') && len == 0)
                     58:                        ch = ctrl('[');
                     59: #ifndef NO_DIGRAPH
                     60:                if (*o_digraph && erased != 0 && ch != '\b')
                     61:                {
                     62:                        ch = digraph(erased, ch);
                     63:                        erased = 0;
                     64:                }
                     65: #endif
                     66: 
                     67:                /* inhibit detection of special chars (except ^J) after a ^V */
                     68:                if (quoted && ch != '\n')
                     69:                {
                     70:                        ch |= 256;
                     71:                }
                     72: 
                     73:                /* process the character */
                     74:                switch(ch)
                     75:                {
                     76:                  case ctrl('V'):
                     77:                        qaddch('^');
                     78:                        qaddch('\b');
                     79:                        quoted = TRUE;
                     80:                        break;
                     81: 
                     82:                  case ctrl('['):
                     83:                        return -1;
                     84: 
                     85:                  case '\n':
                     86: #if OSK
                     87:                  case '\l':
                     88: #else
                     89:                  case '\r':
                     90: #endif
                     91:                        clrtoeol();
                     92:                        goto BreakBreak;
                     93: 
                     94:                  case '\b':
                     95:                        if (len > 0)
                     96:                        {
                     97:                                len--;
                     98: #ifndef NO_DIGRAPH
                     99:                                erased = buf[len];
                    100: #endif
                    101:                                for (ch = widths[len]; ch > 0; ch--)
                    102:                                        addch('\b');
                    103:                                if (mode == MODE_EX)
                    104:                                {
                    105:                                        clrtoeol();
                    106:                                }
                    107:                                tab -= widths[len];
                    108:                        }
                    109:                        else
                    110:                        {
                    111:                                return -1;
                    112:                        }
                    113:                        break;
                    114: 
                    115:                  default:
                    116:                        /* strip off quotation bit */
                    117:                        if (ch & 256)
                    118:                        {
                    119:                                ch &= ~256;
                    120:                                quoted = FALSE;
                    121:                                qaddch(' ');
                    122:                                qaddch('\b');
                    123:                        }
                    124:                        /* add & echo the char */
                    125:                        if (len < bsize - 1)
                    126:                        {
                    127:                                if (ch == '\t')
                    128:                                {
                    129:                                        widths[len] = *o_tabstop - (tab % *o_tabstop);
                    130:                                        addstr("        " + 8 - widths[len]);
                    131:                                        tab += widths[len];
                    132:                                }
                    133:                                else if (ch > 0 && ch < ' ') /* > 0 by GB */
                    134:                                {
                    135:                                        addch('^');
                    136:                                        addch(ch + '@');
                    137:                                        widths[len] = 2;
                    138:                                        tab += 2;
                    139:                                }
                    140:                                else if (ch == '\177')
                    141:                                {
                    142:                                        addch('^');
                    143:                                        addch('?');
                    144:                                        widths[len] = 2;
                    145:                                        tab += 2;
                    146:                                }
                    147:                                else
                    148:                                {
                    149:                                        addch(ch);
                    150:                                        widths[len] = 1;
                    151:                                        tab++;
                    152:                                }
                    153:                                buf[len++] = ch;
                    154:                        }
                    155:                        else
                    156:                        {
                    157:                                beep();
                    158:                        }
                    159:                }
                    160:        }
                    161: BreakBreak:
                    162:        refresh();
                    163:        buf[len] = '\0';
                    164:        return len;
                    165: }
                    166: 
                    167: 
                    168: /* ring the terminal's bell */
                    169: void beep()
                    170: {
                    171:        if (*o_vbell)
                    172:        {
                    173:                do_VB();
                    174:                refresh();
                    175:        }
                    176:        else if (*o_errorbells)
                    177:        {
                    178:                ttywrite("\007", 1);
                    179:        }
                    180: }
                    181: 
                    182: static int     manymsgs; /* This variable keeps msgs from overwriting each other */
                    183: static char    pmsg[80]; /* previous message (waiting to be displayed) */
                    184: 
                    185: 
                    186: static int showmsg()
                    187: {
                    188:        /* if there is no message to show, then don't */
                    189:        if (!manymsgs)
                    190:                return FALSE;
                    191: 
                    192:        /* display the message */
                    193:        move(LINES - 1, 0);
                    194:        if (*pmsg)
                    195:        {
                    196:                standout();
                    197:                qaddch(' ');
                    198:                qaddstr(pmsg);
                    199:                qaddch(' ');
                    200:                standend();
                    201:        }
                    202:        clrtoeol();
                    203: 
                    204:        manymsgs = FALSE;
                    205:        return TRUE;
                    206: }
                    207: 
                    208: 
                    209: void endmsgs()
                    210: {
                    211:        if (manymsgs)
                    212:        {
                    213:                showmsg();
                    214:                addch('\n');
                    215:        }
                    216: }
                    217: 
                    218: /* Write a message in an appropriate way.  This should really be a varargs
                    219:  * function, but there is no such thing as vwprintw.  Hack!!!
                    220:  *
                    221:  * In MODE_EX or MODE_COLON, the message is written immediately, with a
                    222:  * newline at the end.
                    223:  *
                    224:  * In MODE_VI, the message is stored in a character buffer.  It is not
                    225:  * displayed until getkey() is called.  msg() will call getkey() itself,
                    226:  * if necessary, to prevent messages from being lost.
                    227:  *
                    228:  * msg("")             - clears the message line
                    229:  * msg("%s %d", ...)   - does a printf onto the message line
                    230:  */
                    231: /*VARARGS1*/
                    232: void msg(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
                    233:        char    *fmt;
                    234:        long    arg1, arg2, arg3, arg4, arg5, arg6, arg7;
                    235: {
                    236:        if (mode != MODE_VI)
                    237:        {
                    238:                sprintf(pmsg, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
                    239:                qaddstr(pmsg);
                    240:                addch('\n');
                    241:                exrefresh();
                    242:        }
                    243:        else
                    244:        {
                    245:                /* wait for keypress between consecutive msgs */
                    246:                if (manymsgs)
                    247:                {
                    248:                        getkey(WHEN_MSG);
                    249:                }
                    250: 
                    251:                /* real message */
                    252:                sprintf(pmsg, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
                    253:                manymsgs = TRUE;
                    254:        }
                    255: }
                    256: 
                    257: 
                    258: /* This function calls refresh() if the option exrefresh is set */
                    259: void exrefresh()
                    260: {
                    261:        char    *scan;
                    262: 
                    263:        /* If this ex command wrote ANYTHING set exwrote so vi's  :  command
                    264:         * can tell that it must wait for a user keystroke before redrawing.
                    265:         */
                    266:        for (scan=kbuf; scan<stdscr; scan++)
                    267:                if (*scan == '\n')
                    268:                        exwrote = TRUE;
                    269: 
                    270: #if MICROSOFT                  /* avoid compiler bug */
                    271:        scan = stdscr;
                    272: #define        stdscr  scan
                    273: #endif
                    274:        /* now we do the refresh thing */
                    275:        if (*o_exrefresh)
                    276:        {
                    277:                refresh();
                    278:        }
                    279:        else
                    280:        {
                    281:                wqrefresh(stdscr);
                    282:        }
                    283: #if MICROSOFT
                    284: #undef stdscr
                    285:        stdscr = scan;
                    286: #endif
                    287:        if (mode != MODE_VI)
                    288:        {
                    289:                manymsgs = FALSE;
                    290:        }
                    291: }
                    292: 
                    293: 
                    294: 
                    295: /* These are used for typeahead, and also for fudging the visual @ command */
                    296: static char    keybuf[100];    /* array of already-read keys */
                    297: static int     nkeys;          /* total number of keys in keybuf */
                    298: static int     next;           /* index of next key to return */
                    299: #ifndef NO_AT
                    300: static int     atnext;         /* index of next key for "@", or 0 normally */
                    301: int fromcutbuf(cbname)
                    302:        int     cbname;
                    303: {
                    304:        int     len;
                    305: 
                    306:        /* fail if we're already doing an @ macro */
                    307:        if (atnext > 0 && keybuf[atnext])
                    308:        {
                    309:                msg("Can't nest @ commands");
                    310:                return FALSE;
                    311:        }
                    312: 
                    313:        /* use the empty portion of keybuf[] to get chars from the cut buffer */
                    314:        len = cb2str(cbname, keybuf + nkeys, sizeof keybuf - nkeys);
                    315:        if (len < 0)
                    316:        {
                    317:                msg("Invalid cut buffer name.  Must be a-z");
                    318:                return FALSE;
                    319:        }
                    320:        if (len == 0)
                    321:        {
                    322:                msg("Cut buffer \"%c is empty", cbname);
                    323:                return FALSE;
                    324:        }
                    325:        else if (len >= sizeof keybuf - nkeys)
                    326:        {
                    327:                msg("Cut buffer \"%c is too large to execute", cbname);
                    328:                return FALSE;
                    329:        }
                    330: 
                    331:        /* prepare to "read" those keys on subsequent getkey() calls */
                    332:        atnext = nkeys;
                    333:        return TRUE;
                    334: }
                    335: #endif
                    336: 
                    337: /* This array describes mapped key sequences */
                    338: static struct _keymap
                    339: {
                    340:        char    *name;          /* name of the key, or NULL */
                    341:        char    rawin[LONGKEY]; /* the unmapped version of input */
                    342:        char    cooked[80];     /* the mapped version of input */
                    343:        int     len;            /* length of the unmapped version */
                    344:        int     when;           /* when is this key mapped? */
                    345: }
                    346:        mapped[MAXMAPS];
                    347: 
                    348: #if !MSDOS && !TOS
                    349: # if BSD || COHERENT
                    350: static jmp_buf env_timeout;
                    351: static int dummy()
                    352: {
                    353:        longjmp(env_timeout, 1);
                    354:        return 0;
                    355: }
                    356: # else 
                    357: static int dummy()
                    358: {
                    359: }
                    360: # endif
                    361: #endif
                    362: 
                    363: /* This function reads in a keystroke for VI mode.  It automatically handles
                    364:  * key mapping.
                    365:  */
                    366: int getkey(when)
                    367:        int             when;           /* which bits must be ON? */
                    368: {
                    369:        static char     *cooked;        /* rawin, or pointer to converted key */ 
                    370:        static int      oldwhen;        /* "when" from last time */
                    371:        static int      oldleft;
                    372:        static long     oldtop;
                    373:        static long     oldnlines;
                    374:        static char     *cshape;        /* current cursor shape */
                    375:        REG char        *kptr;          /* &keybuf[next] */
                    376:        REG struct _keymap *km; /* used to count through keymap */
                    377:        REG int         i, j, k;
                    378: 
                    379: #ifdef DEBUG
                    380:        watch();
                    381: #endif
                    382: 
                    383:        /* if this key is needed for delay between multiple error messages,
                    384:         * then reset the manymsgs flag and abort any mapped key sequence.
                    385:         */
                    386:        if (showmsg())
                    387:        {
                    388:                if (when == WHEN_MSG)
                    389:                {
                    390:                        qaddstr("[More...]");
                    391:                        refresh();
                    392:                        cooked = (char *)0;
                    393:                }
                    394:                else if (when == WHEN_VIINP || when == WHEN_VIREP)
                    395:                {
                    396:                        redraw(cursor, TRUE);
                    397:                }
                    398:        }
                    399: 
                    400: #ifndef NO_AT
                    401:        /* if we're in the middle of a visual @ macro, take atnext */
                    402:        if (atnext > 0)
                    403:        {
                    404:                if (keybuf[atnext])
                    405:                {
                    406:                        return keybuf[atnext++];
                    407:                }
                    408:                atnext = 0;
                    409:        }
                    410: #endif
                    411: 
                    412:        /* if we're doing a mapped key, get the next char */
                    413:        if (cooked && *cooked)
                    414:        {
                    415:                return *cooked++;
                    416:        }
                    417: 
                    418:        /* if keybuf is empty, fill it */
                    419:        if (next == nkeys)
                    420:        {
                    421: #ifndef NO_CURSORSHAPE
                    422:                /* make sure the cursor is the right shape */
                    423:                if (has_CQ)
                    424:                {
                    425:                        cooked = cshape;
                    426:                        switch (when)
                    427:                        {
                    428:                          case WHEN_EX:         cooked = CX;    break;
                    429:                          case WHEN_VICMD:      cooked = CV;    break;
                    430:                          case WHEN_VIINP:      cooked = CI;    break;
                    431:                          case WHEN_VIREP:      cooked = CR;    break;
                    432:                        }
                    433:                        if (cooked != cshape)
                    434:                        {
                    435:                                cshape = cooked;
                    436:                                switch (when)
                    437:                                {
                    438:                                  case WHEN_EX:         do_CX();        break;
                    439:                                  case WHEN_VICMD:      do_CV();        break;
                    440:                                  case WHEN_VIINP:      do_CI();        break;
                    441:                                  case WHEN_VIREP:      do_CR();        break;
                    442:                                }
                    443:                        }
                    444:                        cooked = (char *)0;
                    445:                }
                    446: #endif
                    447: 
                    448: #ifndef NO_SHOWMODE
                    449:                /* if "showmode" then say which mode we're in */
                    450:                if (*o_smd
                    451:                 && mode == MODE_VI
                    452:                 && (when != oldwhen || topline != oldtop || leftcol != oldleft || nlines != oldnlines))
                    453:                {
                    454:                        oldwhen = when;
                    455:                        oldtop = topline;
                    456:                        oldleft = leftcol;
                    457:                        oldnlines = nlines;
                    458: 
                    459:                        if (when & WHEN_VICMD)
                    460:                        {
                    461:                                redraw(cursor, FALSE);
                    462:                                move(LINES - 1, COLS - 10);
                    463:                                standout();
                    464:                                addstr("Command");
                    465:                                standend();
                    466:                                redraw(cursor, FALSE);
                    467:                        }
                    468:                        else if (when & WHEN_VIINP)
                    469:                        {
                    470:                                redraw(cursor, TRUE);
                    471:                                move(LINES - 1, COLS - 10);
                    472:                                standout();
                    473:                                addstr(" Input ");
                    474:                                standend();
                    475:                                redraw(cursor, TRUE);
                    476:                        }
                    477:                        else if (when & WHEN_VIREP)
                    478:                        {
                    479:                                redraw(cursor, TRUE);
                    480:                                move(LINES - 1, COLS - 10);
                    481:                                standout();
                    482:                                addstr("Replace");
                    483:                                standend();
                    484:                                redraw(cursor, TRUE);
                    485:                        }
                    486:                }
                    487:                else
                    488: #endif
                    489: 
                    490:                /* redraw if getting a VI command */
                    491:                if (when & WHEN_VICMD)
                    492:                {
                    493:                        redraw(cursor, FALSE);
                    494:                }
                    495: 
                    496:                /* read the rawin keystrokes */
                    497:                refresh();
                    498:                while ((nkeys = ttyread(keybuf, sizeof keybuf)) < 0)
                    499:                {
                    500:                        /* terminal was probably resized */
                    501:                        *o_lines = LINES;
                    502:                        *o_columns = COLS;
                    503:                        if (when & (WHEN_VICMD|WHEN_VIINP|WHEN_VIREP))
                    504:                        {
                    505:                                redraw(MARK_UNSET, FALSE);
                    506:                                redraw(cursor, (when & WHEN_VICMD) == 0);
                    507:                                refresh();
                    508:                        }
                    509:                }
                    510:                next = 0;
                    511: 
                    512:                /* if nkeys == 0 then we've reached EOF of an ex script. */
                    513:                if (nkeys == 0)
                    514:                {
                    515:                        tmpabort(TRUE);
                    516:                        move(LINES - 1, 0);
                    517:                        clrtoeol();
                    518:                        refresh();
                    519:                        endwin();
                    520:                        exit(1);
                    521:                }
                    522:        }
                    523: 
                    524:        /* see how many mapped keys this might be */
                    525:        kptr = &keybuf[next];
                    526:        for (i = j = 0, k = -1, km = mapped; i < MAXMAPS; i++, km++)
                    527:        {
                    528:                if ((km->when & when) && km->len > 0 && *km->rawin == *kptr)
                    529:                {
                    530:                        if (km->len > nkeys - next)
                    531:                        {
                    532:                                if (!strncmp(km->rawin, kptr, nkeys - next))
                    533:                                {
                    534:                                        j++;
                    535:                                }
                    536:                        }
                    537:                        else
                    538:                        {
                    539:                                if (!strncmp(km->rawin, kptr, km->len))
                    540:                                {
                    541:                                        j++;
                    542:                                        k = i;
                    543:                                }
                    544:                        }
                    545:                }
                    546:        }
                    547: 
                    548:        /* if more than one, try to read some more */
                    549:        while (j > 1)
                    550:        {
                    551: #if BSD || COHERENT
                    552:                if (setjmp(env_timeout))
                    553:                {
                    554:                        /* we timed out - assume no mapping */
                    555:                        j = 0;
                    556:                        break;
                    557:                }
                    558: #endif
                    559: #if ANY_UNIX
                    560:                signal(SIGALRM, dummy);
                    561: #endif
                    562: #if OSK
                    563:                signal(SIGQUIT, dummy);
                    564: #endif
                    565:                alarm((unsigned)*o_keytime);
                    566:                i = nkeys;
                    567:                if ((k = ttyread(keybuf + nkeys, sizeof keybuf - nkeys)) >= 0)
                    568:                {
                    569:                        nkeys += k;
                    570:                }
                    571:                alarm(0);
                    572: #if OSK
                    573: # ifndef DEBUG
                    574:                signal(SIGQUIT, SIG_IGN);
                    575: # endif
                    576: #endif
                    577: 
                    578:                /* if we couldn't read any more, pretend 0 mapped keys */
                    579:                if (i == nkeys)
                    580:                {
                    581:                        j = 0;
                    582:                }
                    583:                else /* else we got some more - try again */
                    584:                {
                    585:                        for (i = j = 0, k = -1, km = mapped; i < MAXMAPS; i++, km++)
                    586:                        {
                    587:                                if ((km->when & when) && km->len > 0 && *km->rawin == *kptr)
                    588:                                {
                    589:                                        if (km->len > nkeys - next)
                    590:                                        {
                    591:                                                if (!strncmp(km->rawin, kptr, nkeys - next))
                    592:                                                {
                    593:                                                        j++;
                    594:                                                }
                    595:                                        }
                    596:                                        else
                    597:                                        {
                    598:                                                if (!strncmp(km->rawin, kptr, km->len))
                    599:                                                {
                    600:                                                        j++;
                    601:                                                        k = i;
                    602:                                                }
                    603:                                        }
                    604:                                }
                    605:                        }
                    606:                }
                    607:        }
                    608: 
                    609:        /* if unambiguously mapped key, use it! */
                    610:        if (j == 1 && k >= 0)
                    611:        {
                    612:                next += mapped[k].len;
                    613:                cooked = mapped[k].cooked;
                    614: #ifndef NO_EXTENSIONS
                    615:                if ((when & (WHEN_VIINP|WHEN_VIREP))
                    616:                 && (mapped[k].when & WHEN_INMV))
                    617:                {
                    618:                        return 0; /* special case, means "a movement char follows" */
                    619:                }
                    620:                else
                    621: #endif
                    622:                {
                    623:                        return *cooked++;
                    624:                }
                    625:        }
                    626:        else
                    627:        /* assume key is unmapped, but still translate weird erase key to '\b' */
                    628:        if (keybuf[next] == ERASEKEY && when != 0)
                    629:        {
                    630:                next++;
                    631:                return '\b';
                    632:        }
                    633:        else if (keybuf[next] == '\0')
                    634:        {
                    635:                next++;
                    636:                return ('A' & 0x1f);
                    637:        }
                    638:        else
                    639:        {
                    640:                return keybuf[next++];
                    641:        }
                    642: }
                    643: 
                    644: 
                    645: /* This function maps or unmaps a key */
                    646: void mapkey(rawin, cooked, when, name)
                    647:        char    *rawin; /* the input key sequence, before mapping */
                    648:        char    *cooked;/* after mapping */
                    649:        short   when;   /* bitmap of when mapping should happen */
                    650:        char    *name;  /* name of the key, if any */
                    651: {
                    652:        int     i, j;
                    653: 
                    654: #ifndef NO_EXTENSIONS
                    655:        /* if the mapped version starts with the word "visual" then set WHEN_INMV */
                    656:        if (!strncmp(cooked, "visual ", 7))
                    657:        {
                    658:                when |= WHEN_INMV;
                    659:                cooked += 7;
                    660:        }
                    661:        /* if WHEN_INMV is set, then WHEN_VIINP and WHEN_VIREP must be set */
                    662:        if (when & WHEN_INMV)
                    663:        {
                    664:                when |= (WHEN_VIINP | WHEN_VIREP);
                    665:        }
                    666: #endif
                    667: 
                    668:        /* see if the key sequence was mapped before */
                    669:        j = strlen(rawin);
                    670:        for (i = 0; i < MAXMAPS; i++)
                    671:        {
                    672:                if (mapped[i].len == j
                    673:                 && !strncmp(mapped[i].rawin, rawin, j)
                    674:                 && (mapped[i].when & when))
                    675:                {
                    676:                        break;
                    677:                }
                    678:        }
                    679: 
                    680:        /* if not already mapped, then try to find a new slot to use */
                    681:        if (i == MAXMAPS)
                    682:        {
                    683:                for (i = 0; i < MAXMAPS && mapped[i].len > 0; i++)
                    684:                {
                    685:                }
                    686:        }
                    687: 
                    688:        /* no room for the new key? */
                    689:        if (i == MAXMAPS)
                    690:        {
                    691:                msg("No room left in the key map table");
                    692:                return;
                    693:        }
                    694: 
                    695:        /* map the key */
                    696:        if (cooked && *cooked)
                    697:        {
                    698:                /* Map the key */
                    699:                mapped[i].len = j;
                    700:                strncpy(mapped[i].rawin, rawin, j);
                    701:                strcpy(mapped[i].cooked, cooked);
                    702:                mapped[i].when = when;
                    703:                mapped[i].name = name;
                    704:        }
                    705:        else /* unmap the key */
                    706:        {
                    707:                mapped[i].len = 0;
                    708:        }
                    709: }
                    710: 
                    711: /* Dump keys of a given type - WHEN_VICMD dumps the ":map" keys, and
                    712:  * WHEN_VIINP|WHEN_VIREP dumps the ":map!" keys
                    713:  */
                    714: void dumpkey(when)
                    715:        int     when;   /* WHEN_XXXX of mappings to be dumped */
                    716: {
                    717:        int     i, len, mlen;
                    718:        char    *scan;
                    719:        char    *mraw;
                    720: 
                    721:        for (i = 0; i < MAXMAPS; i++)
                    722:        {
                    723:                /* skip unused entries, or entries that don't match "when" */
                    724:                if (mapped[i].len <= 0 || !(mapped[i].when & when))
                    725:                {
                    726:                        continue;
                    727:                }
                    728: 
                    729:                /* dump the key label, if any */
                    730:                len = 8;
                    731:                if (mapped[i].name)
                    732:                {
                    733:                        qaddstr(mapped[i].name);
                    734:                        len -= strlen(mapped[i].name);
                    735:                }
                    736:                do
                    737:                {
                    738:                        qaddch(' ');
                    739:                } while (len-- > 0);
                    740: 
                    741:                /* dump the raw version */
                    742:                len = 0;
                    743:                mlen = mapped[i].len;
                    744:                mraw = mapped[i].rawin;
                    745:                for (scan = mraw; scan < mraw + mlen; scan++)
                    746:                {
                    747:                        if (UCHAR(*scan) < ' ' || *scan == '\177')
                    748:                        {
                    749:                                qaddch('^');
                    750:                                qaddch(*scan ^ '@');
                    751:                                len += 2;
                    752:                        }
                    753:                        else
                    754:                        {
                    755:                                qaddch(*scan);
                    756:                                len++;
                    757:                        }
                    758:                }
                    759:                do
                    760:                {
                    761:                        qaddch(' ');
                    762:                } while (++len < 8);
                    763: 
                    764:                /* dump the mapped version */
                    765: #ifndef NO_EXTENSIONS
                    766:                if ((mapped[i].when & WHEN_INMV) && (when & (WHEN_VIINP|WHEN_VIREP)))
                    767:                {
                    768:                        qaddstr("visual ");
                    769:                }
                    770: #endif
                    771:                for (scan = mapped[i].cooked; *scan; scan++)
                    772:                {
                    773:                        if (UCHAR(*scan) < ' ' || *scan == '\177')
                    774:                        {
                    775:                                qaddch('^');
                    776:                                qaddch(*scan ^ '@');
                    777:                        }
                    778:                        else
                    779:                        {
                    780:                                qaddch(*scan);
                    781:                        }
                    782:                }
                    783: 
                    784:                addch('\n');
                    785:                exrefresh();
                    786:        }
                    787: }
                    788: 
                    789: 
                    790: 
                    791: #ifndef MKEXRC
                    792: /* This function saves the current configuration of mapped keys to a file */
                    793: void savekeys(fd)
                    794:        int     fd;     /* file descriptor to save them to */
                    795: {
                    796:        int     i;
                    797:        char    buf[80];
                    798: 
                    799:        /* now write a map command for each key other than the arrows */
                    800:        for (i = 0; i < MAXMAPS; i++)
                    801:        {
                    802:                /* ignore keys that came from termcap */
                    803:                if (mapped[i].name)
                    804:                {
                    805:                        continue;
                    806:                }
                    807: 
                    808:                /* If this isn't used, ignore it */
                    809:                if (mapped[i].len <= 0)
                    810:                {
                    811:                        continue;
                    812:                }
                    813: 
                    814:                /* write the map command */
                    815: #ifndef NO_EXTENSIONS
                    816:                if (mapped[i].when & WHEN_INMV)
                    817:                {
                    818: #if OSK
                    819:                        char    fmt[80];
                    820:                        sprintf(fmt, "map%%s %%.%ds %%s\n", mapped[i].len);
                    821:                        sprintf(buf, fmt,
                    822:                                (mapped[i].when & WHEN_VICMD) ? "" : "!",
                    823: #else
                    824:                        sprintf(buf, "map%s %.*s visual %s\n",
                    825:                                (mapped[i].when & WHEN_VICMD) ? "" : "!",
                    826:                                mapped[i].len,
                    827: #endif
                    828:                                mapped[i].rawin,
                    829:                                mapped[i].cooked);
                    830:                        twrite(fd, buf, strlen(buf));
                    831:                }
                    832:                else
                    833: #endif
                    834:                {
                    835:                        if (mapped[i].when & WHEN_VICMD)
                    836:                        {
                    837: #if OSK
                    838:                                char    fmt[80];
                    839:                                sprintf(fmt, "map %%.%ds %%s\n", mapped[i].len);
                    840:                                sprintf(buf, fmt,
                    841: #else
                    842:                                sprintf(buf, "map %.*s %s\n", mapped[i].len,
                    843: #endif
                    844:                                        mapped[i].rawin,
                    845:                                        mapped[i].cooked);
                    846:                                twrite(fd, buf, strlen(buf));
                    847:                        }
                    848:                        if (mapped[i].when & (WHEN_VIINP | WHEN_VIREP))
                    849:                        {
                    850: #if OSK
                    851:                                char    fmt[80];
                    852:                                sprintf(fmt, "map! %%.%ds %%s\n", mapped[i].len);
                    853:                                sprintf(buf, fmt,
                    854: #else
                    855:                                sprintf(buf, "map! %.*s %s\n", mapped[i].len,
                    856: #endif
                    857:                                        mapped[i].rawin,
                    858:                                        mapped[i].cooked);
                    859:                                twrite(fd, buf, strlen(buf));
                    860:                        }
                    861:                }
                    862:        }
                    863: }
                    864: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.