Annotation of coherent/d/usr/bin/elvis/tio.c, revision 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.