# 2.11BSD#431 - /usr/src/bin/tcsh/tc.bind.c

##### Functions

    dobind            X
    dobindkey         X
    parseescape       X
    u_p_string        X

       1: /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/tc.bind.c,v 3.0 1991/07/04 21:49:28 christos Exp $ */
       2: /*
       3:  * tc.bind.c: Key binding functions
       4:  */
       5: /*-
       6:  * Copyright (c) 1980, 1991 The Regents of the University of California.
       7:  * All rights reserved.
       8:  *
       9:  * Redistribution and use in source and binary forms, with or without
      10:  * modification, are permitted provided that the following conditions
      11:  * are met:
      12:  * 1. Redistributions of source code must retain the above copyright
      13:  *    notice, this list of conditions and the following disclaimer.
      14:  * 2. Redistributions in binary form must reproduce the above copyright
      15:  *    notice, this list of conditions and the following disclaimer in the
      16:  *    documentation and/or other materials provided with the distribution.
      17:  * 3. All advertising materials mentioning features or use of this software
      18:  *    must display the following acknowledgement:
      19:  *	This product includes software developed by the University of
      20:  *	California, Berkeley and its contributors.
      21:  * 4. Neither the name of the University nor the names of its contributors
      22:  *    may be used to endorse or promote products derived from this software
      23:  *    without specific prior written permission.
      24:  *
      25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      35:  * SUCH DAMAGE.
      36:  */
      37: #include "config.h"
      38: #if !defined(lint) && !defined(pdp11)
      39: static char *rcsid()
      40:     { return "$Id: tc.bind.c,v 3.0 1991/07/04 21:49:28 christos Exp $"; }
      41: #endif
      42:
      43: #include "sh.h"
      44: #include "ed.h"
      45: #include "ed.defns.h"
      46:
      47: static  int    str7cmp      __P((char *, char *));
      48: static  int    tocontrol    __P((int));
      49: static  char  *u_p_key  __P((int));
      50: static  KEYCMD getkeycmd    __P((Char **));
      51: static  int    parsekey     __P((Char **));
      52: static  void   prntky       __P((KEYCMD *, Char *));
      53: static  KEYCMD parsecmd     __P((Char *));
      54: static  Char  *parsestring  __P((Char *, Char *));
      55: static  void   print_all_keys   __P((void));
      56: static  void   prntkys  __P((KEYCMD *, int, int));
      57: static  void   bindkey_usage    __P((void));
      58: static  void   list_functions   __P((void));
      59: static  void   pkeys        __P((int, int));
      60:
      61: extern int MapsAreInited;
      62:
      63: /* like strcmp, but compairisons are striped to 7 bits
      64:    (due to shell stupidness) */
      65: static int
      66: str7cmp(a, b)
      67:     register char *a, *b;
      68: {
      69:     while ((*a & TRIM) == (*b++ & TRIM))
      70:     if (!*a++)
      71:         return (0);
      72:     b--;
      73:     return ((*a & TRIM) - (*b & TRIM));
      74: }
      75: static int
      76: tocontrol(c)
      77:     int    c;
      78: {
      79:     c &= CHAR;
      80:     if (Islower(c))
      81:     c = Toupper(c);
      82:     else if (c == ' ')
      83:     c = '@';
      84:     if (c == '?')
      85:     c = 0177;
      86:     else
      87:     c &= 037;
      88:     return (c);
      89: }
      90:
      91: static char *
      92: u_p_key(c)          /* 'c' -> "c", '^C' -> "^" + "C" */
      93:     register int c;
      94: {
      95:     register char *cp;
      96:     static char tmp[10];
      97:
      98:     cp = tmp;
      99:
     100:     if (c & 0400) {
     101:     *cp++ = 'A';
     102:     *cp++ = '-';
     103:     c &= 0377;
     104:     }
     105:     if ((c & META) && !(Isprint(c) || Iscntrl(c) && Isprint(c | 0100))) {
     106:     *cp++ = 'M';
     107:     *cp++ = '-';
     108:     c &= ASCII;
     109:     }
     110:     if (Isprint(c)) {
     111:     *cp++ = c;
     112:     *cp = '\0';
     113:     return (tmp);
     114:     }
     115:     else if (c == ' ') {
     116:     (void) strcpy(cp, "Spc");
     117:     return (tmp);
     118:     }
     119:     else if (c == '\n') {
     120:     (void) strcpy(cp, "Lfd");
     121:     return (tmp);
     122:     }
     123:     else if (c == '\r') {
     124:     (void) strcpy(cp, "Ret");
     125:     return (tmp);
     126:     }
     127:     else if (c == '\t') {
     128:     (void) strcpy(cp, "Tab");
     129:     return (tmp);
     130:     }
     131:     else if (c == '\033') {
     132:     (void) strcpy(cp, "Esc");
     133:     return (tmp);
     134:     }
     135:     else if (c == '\177') {
     136:     (void) strcpy(cp, "Del");
     137:     return (tmp);
     138:     }
     139:     else {
     140:     *cp++ = '^';
     141:     if (c == '\177') {
     142:         *cp++ = '?';
     143:     }
     144:     else {
     145:         *cp++ = c | 0100;
     146:     }
     147:     *cp = '\0';
     148:     return (tmp);
     149:     }
     150: }
     151:
     152: static  KEYCMD
     153: getkeycmd(sp)
     154:     Char  **sp;
     155: {
     156:     register Char *s = *sp;
     157:     register char c;
     158:     register KEYCMD keycmd = F_UNASSIGNED;
     159:     KEYCMD *map;
     160:     int     meta = 0;
     161:     Char   *ret_sp = s;
     162:
     163:     map = CcKeyMap;
     164:
     165:     while (*s) {
     166:     if (*s == '^' && s[1]) {
     167:         s++;
     168:         c = tocontrol(*s++);
     169:     }
     170:     else
     171:         c = *s++;
     172:
     173:     if (*s == '\0')
     174:         break;
     175:
     176:     switch (map[c | meta]) {
     177:     case F_METANEXT:
     178:         meta = META;
     179:         keycmd = F_METANEXT;
     180:         ret_sp = s;
     181:         break;
     182:
     183:     case F_XKEY:
     184:         keycmd = F_XKEY;
     185:         ret_sp = s;
     186:         /* FALLTHROUGH */
     187:
     188:     default:
     189:         *sp = ret_sp;
     190:         return (keycmd);
     191:
     192:     }
     193:     }
     194:     *sp = ret_sp;
     195:     return (keycmd);
     196: }
     197:
     198: static int
     199: parsekey(sp)
     200:     Char  **sp;         /* Return position of first u_p_d character
     201: 				 * for return value -2 (xkeynext) */
     202: {
     203:     register int c, meta = 0, control = 0, ctrlx = 0;
     204:     Char   *s = *sp;
     205:     KEYCMD  keycmd;
     206:
     207:     if (s == NULL) {
     208:     xprintf("bad key specification -- null string\n");
     209:     return -1;
     210:     }
     211:     if (*s == 0) {
     212:     xprintf("bad key specification -- empty string\n");
     213:     return -1;
     214:     }
     215:
     216:     (void) strip(s);        /* trim to 7 bits. */
     217:
     218:     if (s[1] == 0)      /* single char */
     219:     return (s[0] & 0377);
     220:
     221:     if ((s[0] == 'F' || s[0] == 'f') && s[1] == '-') {
     222:     if (s[2] == 0) {
     223:         xprintf("Bad function-key specification.  Null key not allowed\n");
     224:         return (-1);
     225:     }
     226:     *sp = s + 2;
     227:     return (-2);
     228:     }
     229:
     230:     if (s[0] == '0' && s[1] == 'x') {   /* if 0xn, then assume number */
     231:     c = 0;
     232:     for (s += 2; *s; s++) { /* convert to hex; skip the first 0 */
     233:         c *= 16;
     234:         if (!Isxdigit(*s)) {
     235:         xprintf("bad key specification -- malformed hex number\n");
     236:         return -1;  /* error */
     237:         }
     238:         if (Isdigit(*s))
     239:         c += *s - '0';
     240:         else if (*s >= 'a' && *s <= 'f')
     241:         c += *s - 'a' + 0xA;
     242:         else if (*s >= 'F' && *s <= 'F')
     243:         c += *s - 'A' + 0xA;
     244:     }
     245:     }
     246:     else if (s[0] == '0' && Isdigit(s[1])) {    /* if 0n, then assume number */
     247:     c = 0;
     248:     for (s++; *s; s++) {    /* convert to octal; skip the first 0 */
     249:         if (!Isdigit(*s) || *s == '8' || *s == '9') {
     250:         xprintf("bad key specification -- malformed octal number\n");
     251:         return -1;  /* error */
     252:         }
     253:         c = (c * 8) + *s - '0';
     254:     }
     255:     }
     256:     else if (Isdigit(s[0]) && Isdigit(s[1])) {  /* decimal number */
     257:     c = 0;
     258:     for (; *s; s++) {   /* convert to octal; skip the first 0 */
     259:         if (!Isdigit(*s)) {
     260:         xprintf("bad key specification -- malformed decimal number\n");
     261:         return -1;  /* error */
     262:         }
     263:         c = (c * 10) + *s - '0';
     264:     }
     265:     }
     266:     else {
     267:     keycmd = getkeycmd(&s);
     268:
     269:     if ((s[0] == 'X' || s[0] == 'x') && s[1] == '-') {  /* X- */
     270:         ctrlx++;
     271:         s += 2;
     272:         keycmd = getkeycmd(&s);
     273:     }
     274:     if ((*s == 'm' || *s == 'M') && s[1] == '-') {  /* meta */
     275:         meta++;
     276:         s += 2;
     277:         keycmd = getkeycmd(&s);
     278:     }
     279:     else if (keycmd == F_METANEXT && *s) {  /* meta */
     280:         meta++;
     281:         keycmd = getkeycmd(&s);
     282:     }
     283:     if (*s == '^' && s[1]) {
     284:         control++;
     285:         s++;
     286:         keycmd = getkeycmd(&s);
     287:     }
     288:     else if ((*s == 'c' || *s == 'C') && s[1] == '-') { /* control */
     289:         control++;
     290:         s += 2;
     291:         keycmd = getkeycmd(&s);
     292:     }
     293:
     294:     if (keycmd == F_XKEY) {
     295:         if (*s == 0) {
     296:         xprintf("Bad function-key specification.\n");
     297:         xprintf("Null key not allowed\n");
     298:         return (-1);
     299:         }
     300:         *sp = s;
     301:         return (-2);
     302:     }
     303:
     304:     if (s[1] != 0) {    /* if symbolic name */
     305:         char   *ts;
     306:
     307:         ts = short2str(s);
     308:         if (!str7cmp(ts, "space") || !str7cmp(ts, "Spc"))
     309:         c = ' ';
     310:         else if (!str7cmp(ts, "return") || !str7cmp(ts, "Ret"))
     311:         c = '\r';
     312:         else if (!str7cmp(ts, "newline") || !str7cmp(ts, "Lfd"))
     313:         c = '\n';
     314:         else if (!str7cmp(ts, "linefeed"))
     315:         c = '\n';
     316:         else if (!str7cmp(ts, "tab"))
     317:         c = '\t';
     318:         else if (!str7cmp(ts, "escape") || !str7cmp(ts, "Esc"))
     319:         c = '\033';
     320:         else if (!str7cmp(ts, "backspace"))
     321:         c = '\b';
     322:         else if (!str7cmp(ts, "delete"))
     323:         c = '\177';
     324:         else {
     325:         xprintf("bad key specification -- unknown name \"%s\"\n", s);
     326:         return -1;  /* error */
     327:         }
     328:     }
     329:     else
     330:         c = *s;     /* just a single char */
     331:
     332:     if (control)
     333:         c = tocontrol(c);
     334:     if (meta)
     335:         c |= META;
     336:     if (ctrlx)
     337:         c |= 0400;
     338:     }
     339:     return (c & 0777);
     340: }
     341:
     342:
     343: void
     344: dobindkey(v)
     345:     Char  **v;
     346: {
     347:     KEYCMD *map;
     348:     int     string, no, remove;
     349:     Char   *par;
     350:     Char    p;
     351:     Char    inbuf[200];
     352:     Char    outbuf[200];
     353:     Char   *in;
     354:     Char   *out;
     355:     KEYCMD  cmd;
     356:
     357:     if (!MapsAreInited)
     358:     ed_IMaps();
     359:
     360:     map = CcKeyMap;
     361:     string = 0;
     362:     remove = 0;
     363:     for (no = 1, par = v[no];
     364:      par != NULL && (*par++ & CHAR) == '-'; no++, par = v[no]) {
     365:     if ((p = (*par & CHAR)) == '-') {
     366:         break;
     367:     }
     368:     else if (p == 'a') {
     369:         map = CcAltMap;
     370:     }
     371:     else if (p == 's') {
     372:         string = 1;
     373:     }
     374:     else if (p == 'r') {
     375:         remove = 1;
     376:     }
     377:     else if (p == 'v') {
     378:         ed_IVIMaps();
     379:         return;
     380:     }
     381:     else if (p == 'e') {
     382:         ed_IEmacsMaps();
     383:         return;
     384:     }
     385:     else if (p == 'd') {
     386: #ifdef VIDEFAULT
     387:         ed_IVIMaps();
     388: #else
     389:         ed_IEmacsMaps();
     390: #endif
     391:         return;
     392:     }
     393:     else if (p == 'l') {
     394:         list_functions();
     395:         return;
     396:     }
     397:     else {
     398:         bindkey_usage();
     399:         return;
     400:     }
     401:     }
     402:
     403:     if (!v[no]) {
     404:     print_all_keys();
     405:     return;
     406:     }
     407:
     408:     if ((in = parsestring(v[no++], inbuf)) == NULL)
     409:     return;
     410:     if (remove) {
     411:     if (in[1]) {
     412:         (void) DeleteXkey(in);
     413:     }
     414:     else if (map[(unsigned char) *in] == F_XKEY) {
     415:         (void) DeleteXkey(in);
     416:         map[(unsigned char) *in] = F_UNASSIGNED;
     417:     }
     418:     else {
     419:         map[(unsigned char) *in] = F_UNASSIGNED;
     420:     }
     421:     return;
     422:     }
     423:     if (!v[no]) {
     424:     prntky(map, in);
     425:     return;
     426:     }
     427:     if (v[no + 1]) {
     428:     bindkey_usage();
     429:     return;
     430:     }
     431:     if (string) {
     432:     if ((out = parsestring(v[no], outbuf)) == NULL)
     433:         return;
     434:     AddXkey(in, out);
     435:     map[(unsigned char) *in] = F_XKEY;
     436:     }
     437:     else {
     438:     if ((cmd = parsecmd(v[no])) == 0)
     439:         return;
     440:     if (in[1]) {
     441:         AddXKeyCmd(in, (Char) cmd);
     442:         map[(unsigned char) *in] = F_XKEY;
     443:     }
     444:     else {
     445:         (void) ClearXkey(map, in);
     446:         map[(unsigned char) *in] = cmd;
     447:     }
     448:     }
     449: }
     450:
     451: static void
     452: prntky(map, in)
     453:     KEYCMD *map;
     454:     Char   *in;
     455: {
     456:     unsigned char outbuf[100];
     457:     register struct KeyFuncs *fp;
     458:
     459:     if (in[0] == 0 || in[1] == 0) {
     460:     (void) u_p_string(in, outbuf);
     461:     for (fp = FuncNames; fp->name; fp++) {
     462:         if (fp->func == map[(unsigned char) *in]) {
     463:         xprintf("%s\t->\t%s\n", outbuf, fp->name);
     464:         }
     465:     }
     466:     }
     467:     else {
     468:     (void) PrintXkey(in);
     469:     }
     470: }
     471:
     472: static  KEYCMD
     473: parsecmd(str)
     474:     Char   *str;
     475: {
     476:     register struct KeyFuncs *fp;
     477:
     478:     for (fp = FuncNames; fp->name; fp++) {
     479:     if (str7cmp(short2str(str), fp->name) == 0) {
     480:         return fp->func;
     481:     }
     482:     }
     483:     xprintf("Bad command name: %s\n", short2str(str));
     484:     return 0;
     485: }
     486:
     487: int
     488: parseescape(ptr)
     489:     Char  **ptr;
     490: {
     491:     Char   *p, c;
     492:
     493:     p = *ptr;
     494:
     495:     if ((p[1] & CHAR) == 0) {
     496:     xprintf("Something must follow: %c\\n", *p);
     497:     return 0;
     498:     }
     499:     if ((*p & CHAR) == '\\') {
     500:     p++;
     501:     switch (*p & CHAR) {
     502:     case 'a':
     503:         c = '\007';     /* Bell */
     504:         break;
     505:     case 'b':
     506:         c = '\010';     /* Backspace */
     507:         break;
     508:     case 't':
     509:         c = '\011';     /* Horizontal Tab */
     510:         break;
     511:     case 'n':
     512:         c = '\012';     /* New Line */
     513:         break;
     514:     case 'v':
     515:         c = '\013';     /* Vertical Tab */
     516:         break;
     517:     case 'f':
     518:         c = '\014';     /* Form Feed */
     519:         break;
     520:     case 'r':
     521:         c = '\015';     /* Carriage Return */
     522:         break;
     523:     case 'e':
     524:         c = '\033';     /* Escape */
     525:         break;
     526:     case '0':
     527:     case '1':
     528:     case '2':
     529:     case '3':
     530:     case '4':
     531:     case '5':
     532:     case '6':
     533:     case '7':
     534:         {
     535:         register int cnt, val, ch;
     536:
     537:         for (cnt = 0, val = 0; cnt < 3; cnt++) {
     538:             ch = *p++ & CHAR;
     539:             if (ch < '0' || ch > '7') {
     540:             p--;
     541:             break;
     542:             }
     543:             val = (val << 3) | (ch - '0');
     544:         }
     545:         if ((val & 0xffffff00) != 0) {
     546:             xprintf("Octal constant does not fit in a char.\n");
     547:             return 0;
     548:         }
     549:         c = val;
     550:         --p;
     551:         }
     552:         break;
     553:     default:
     554:         c = *p;
     555:         break;
     556:     }
     557:     }
     558:     else if ((*p & CHAR) == '^') {
     559:     p++;
     560:     c = (*p == '?') ? '\177' : ((*p & CHAR) & 0237);
     561:     }
     562:     else
     563:     c = *p;
     564:     *ptr = p;
     565:     return (c);
     566: }
     567:
     568: static Char *
     569: parsestring(str, buf)
     570:     Char   *str;
     571:     Char   *buf;
     572: {
     573:     Char   *b;
     574:     Char   *p;
     575:
     576:     b = buf;
     577:     if (*str == 0) {
     578:     xprintf("Null string specification\n");
     579:     return 0;
     580:     }
     581:
     582:     for (p = str; *p != 0; p++) {
     583:     if ((*p & CHAR) == '\\' || (*p & CHAR) == '^') {
     584:         if ((*b++ = parseescape(&p)) == 0)
     585:         return 0;
     586:     }
     587:     else {
     588:         *b++ = *p & CHAR;
     589:     }
     590:     }
     591:     *b = 0;
     592:     return buf;
     593: }
     594:
     595: unsigned char *
     596: u_p_string(str, buf)
     597:     Char   *str;
     598:     unsigned char *buf;
     599: {
     600:     unsigned char *b;
     601:     Char   *p;
     602:
     603:     b = buf;
     604:     *b++ = '"';
     605:     if (*str == 0) {
     606:     *b++ = '^';
     607:     *b++ = '@';
     608:     *b++ = '"';
     609:     *b++ = 0;
     610:     return buf;
     611:     }
     612:
     613:     for (p = str; *p != 0; p++) {
     614:     if (Iscntrl(*p)) {
     615:         *b++ = '^';
     616:         if (*p == '\177')
     617:         *b++ = '?';
     618:         else
     619:         *b++ = *p | 0100;
     620:     }
     621:     else if (*p == '^' || *p == '\\') {
     622:         *b++ = '\\';
     623:         *b++ = *p;
     624:     }
     625:     else if (*p == ' ' || (Isprint(*p) && !Isspace(*p))) {
     626:         *b++ = *p;
     627:     }
     628:     else {
     629:         *b++ = '\\';
     630:         *b++ = ((*p >> 6) & 7) + '0';
     631:         *b++ = ((*p >> 3) & 7) + '0';
     632:         *b++ = (*p & 7) + '0';
     633:     }
     634:     }
     635:     *b++ = '"';
     636:     *b++ = 0;
     637:     return buf;         /* should check for overflow */
     638: }
     639:
     640: static void
     641: print_all_keys()
     642: {
     643:     int     prev, i;
     644:
     645:     xprintf("Standard key bindings\n");
     646:     prev = 0;
     647:     for (i = 0; i < 256; i++) {
     648:     if (CcKeyMap[prev] == CcKeyMap[i])
     649:         continue;
     650:     prntkys(CcKeyMap, prev, i - 1);
     651:     prev = i;
     652:     }
     653:     prntkys(CcKeyMap, prev, i - 1);
     654:
     655:     xprintf("Alternative key bindings\n");
     656:     prev = 0;
     657:     for (i = 0; i < 256; i++) {
     658:     if (CcAltMap[prev] == CcAltMap[i])
     659:         continue;
     660:     prntkys(CcAltMap, prev, i - 1);
     661:     prev = i;
     662:     }
     663:     prntkys(CcAltMap, prev, i - 1);
     664:     xprintf("Multi-character bindings\n");
     665:     (void) PrintXkey(STRNULL);  /* print all Xkey bindings */
     666: }
     667:
     668: static void
     669: prntkys(map, first, last)
     670:     KEYCMD *map;
     671:     int     first, last;
     672: {
     673:     register struct KeyFuncs *fp;
     674:     Char    firstbuf[2], lastbuf[2];
     675:     unsigned char unparsbuf[10], extrabuf[10];
     676:
     677:     firstbuf[0] = first;
     678:     firstbuf[1] = 0;
     679:     lastbuf[0] = last;
     680:     lastbuf[1] = 0;
     681:     if (map[first] == F_UNASSIGNED) {
     682:     if (first == last)
     683:         xprintf("%-15s->  is undefined\n",
     684:             u_p_string(firstbuf, unparsbuf));
     685:     return;
     686:     }
     687:
     688:     for (fp = FuncNames; fp->name; fp++) {
     689:     if (fp->func == map[first]) {
     690:         if (first == last) {
     691:         xprintf("%-15s->  %s\n",
     692:             u_p_string(firstbuf, unparsbuf), fp->name);
     693:         }
     694:         else {
     695:         xprintf("%-4s to %-7s->  %s\n",
     696:             u_p_string(firstbuf, unparsbuf),
     697:             u_p_string(lastbuf, extrabuf), fp->name);
     698:         }
     699:         return;
     700:     }
     701:     }
     702:     if (map == CcKeyMap) {
     703:     xprintf("BUG!!! %s isn't bound to anything.\n",
     704:         u_p_string(firstbuf, unparsbuf));
     705:     xprintf("CcKeyMap[%d] == %d\n", first, CcKeyMap[first]);
     706:     }
     707:     else {
     708:     xprintf("BUG!!! %s isn't bound to anything.\n",
     709:         u_p_string(firstbuf, unparsbuf));
     710:     xprintf("CcAltMap[%d] == %d\n", first, CcAltMap[first]);
     711:     }
     712: }
     713:
     714: static void
     715: bindkey_usage()
     716: {
     717:     xprintf(
     718:     "Usage: bindkey [options] [--] [in-string [out-string | command]]\n");
     719:     xprintf("    -a   bind key in alternative key binding\n");
     720:     xprintf("    -s   bind an out-string instad of a command\n");
     721:     xprintf("    -v   initialized maps to default vi bindings\n");
     722:     xprintf("    -e   initialized maps to default emacs bindings\n");
     723:     xprintf("    -d   initialized maps to default bindings\n");
     724: #ifdef  LONGFUNCS
     725:     xprintf("    -l   list available functions with descriptions\n");
     726: #else
     727:     xprintf("    -l   list available functions\n");
     728: #endif	/* LONGFUNCS */
     729:     xprintf("    -r   remove the binding of in-string\n");
     730:     xprintf(
     731:        "\nIn no out-string or command is given, the binding for in-string\n");
     732:     xprintf("is printed or all bindings if in-strings is not given.\n");
     733: }
     734:
     735: static void
     736: list_functions()
     737: {
     738:     register struct KeyFuncs *fp;
     739:
     740:     for (fp = FuncNames; fp->name; fp++) {
     741: #ifdef  LONGFUNCS
     742:     xprintf("%s\n          %s\n", fp->name, fp->description);
     743: #else
     744:     xprintf("%s\n", fp->name);
     745: #endif
     746:     }
     747: }
     748:
     749: void
     750: dobind(v)
     751:     register Char **v;
     752: {
     753:     register int c;
     754:     register struct KeyFuncs *fp;
     755:     register int i, prev;
     756:     Char   *p, *l;
     757:     Char    buf[1000];
     758:
     759:     /*
     760:      * Assume at this point that i'm given 2 or 3 args - 'bind', the f-name,
     761:      * and the key; or 'bind' key to print the func for that key.
     762:      */
     763:
     764:     if (!MapsAreInited)
     765:     ed_IMaps();
     766:
     767:     if (v[1] && v[2] && v[3]) {
     768:     xprintf(
     769:        "usage: bind [KEY | COMMAND KEY | \"emacs\" | \"vi\" | \"-a\"]\n");
     770:     return;
     771:     }
     772:
     773:     if (v[1] && v[2]) {     /* if bind FUNCTION KEY */
     774:     for (fp = FuncNames; fp->name; fp++) {
     775:         if (str7cmp(short2str(v[1]), fp->name) == 0) {
     776:         Char   *s = v[2];
     777:
     778:         if ((c = parsekey(&s)) == -1)
     779:             return;
     780:         if (c == -2) {  /* extented key */
     781:             for (i = 0; i < 256; i++) {
     782:             if (i != 033 && (CcKeyMap[i] == F_XKEY ||
     783:                      CcAltMap[i] == F_XKEY)) {
     784:                 p = buf;
     785:                 if (i > 0177) {
     786:                 *p++ = 033;
     787:                 *p++ = i & ASCII;
     788:                 }
     789:                 else {
     790:                 *p++ = i;
     791:                 }
     792:                 for (l = s; *l != 0; l++) {
     793:                 *p++ = *l;
     794:                 }
     795:                 *p = 0;
     796:                 AddXKeyCmd(buf, fp->func);
     797:             }
     798:             }
     799:             return;
     800:         }
     801:         if (c & 0400) {
     802:             if (VImode) {
     803:             CcAltMap[c & 0377] = fp->func;
     804:             /* bind the vi cmd mode key */
     805:             if (c & META) {
     806:                 buf[0] = 033;
     807:                 buf[1] = c & ASCII;
     808:                 buf[2] = 0;
     809:                 AddXKeyCmd(buf, fp->func);
     810:             }
     811:             }
     812:             else {
     813:             buf[0] = 030;   /* ^X */
     814:             buf[1] = c & 0377;
     815:             buf[2] = 0;
     816:             AddXKeyCmd(buf, fp->func);
     817:             CcKeyMap[030] = F_XKEY;
     818:             }
     819:         }
     820:         else {
     821:             CcKeyMap[c] = fp->func; /* bind the key */
     822:             if (c & META) {
     823:             buf[0] = 033;
     824:             buf[1] = c & ASCII;
     825:             buf[2] = 0;
     826:             AddXKeyCmd(buf, fp->func);
     827:             }
     828:         }
     829:         return;
     830:         }
     831:     }
     832:     stderror(ERR_NAME | ERR_STRING, "Invalid function");
     833:     }
     834:     else if (v[1]) {
     835:     char   *cv = short2str(v[1]);
     836:
     837:     if (str7cmp(cv, "list") == 0) {
     838:         for (fp = FuncNames; fp->name; fp++) {
     839:         xprintf("%s\n", fp->name);
     840:         }
     841:         return;
     842:     }
     843:     if ((str7cmp(cv, "emacs") == 0) ||
     844: #ifndef VIDEFAULT
     845:         (str7cmp(cv, "defaults") == 0) ||
     846:         (str7cmp(cv, "default") == 0) ||
     847: #endif
     848:         (str7cmp(cv, "mg") == 0) ||
     849:         (str7cmp(cv, "gnumacs") == 0)) {
     850:         /* reset keys to default */
     851:         ed_IEmacsMaps();
     852: #ifdef VIDEFAULT
     853:     }
     854:     else if ((str7cmp(cv, "vi") == 0)
     855:          || (str7cmp(cv, "default") == 0)
     856:          || (str7cmp(cv, "defaults") == 0)) {
     857: #else
     858:     }
     859:     else if (str7cmp(cv, "vi") == 0) {
     860: #endif
     861:         ed_IVIMaps();
     862:     }
     863:     else {          /* want to know what this key does */
     864:         Char   *s = v[1];
     865:
     866:         if ((c = parsekey(&s)) == -1)
     867:         return;
     868:         if (c == -2) {  /* extended key */
     869:         (void) PrintXkey(s);
     870:         return;
     871:         }
     872:         pkeys(c, c);    /* must be regular key */
     873:     }
     874:     }
     875:     else {          /* list all the bindings */
     876:     prev = 0;
     877:     for (i = 0; i < 256; i++) {
     878:         if (CcKeyMap[prev] == CcKeyMap[i])
     879:         continue;
     880:         pkeys(prev, i - 1);
     881:         prev = i;
     882:     }
     883:     pkeys(prev, i - 1);
     884:     prev = 0;
     885:     for (i = 256; i < 512; i++) {
     886:         if (CcAltMap[prev & 0377] == CcAltMap[i & 0377])
     887:         continue;
     888:         pkeys(prev, i - 1);
     889:         prev = i;
     890:     }
     891:     pkeys(prev, i - 1);
     892:     (void) PrintXkey(STRNULL);  /* print all Xkey bindings */
     893:     }
     894:     return;
     895: }
     896:
     897: static void
     898: pkeys(first, last)
     899:     register int first, last;
     900: {
     901:     register struct KeyFuncs *fp;
     902:     register KEYCMD *map;
     903:     char    buf[8];
     904:
     905:     if (last & 0400) {
     906:     map = CcAltMap;
     907:     first &= 0377;
     908:     last &= 0377;
     909:     }
     910:     else {
     911:     map = CcKeyMap;
     912:     }
     913:     if (map[first] == F_UNASSIGNED) {
     914:     if (first == last)
     915: #ifdef _SEQUENT_
     916:         xprintf(" %s\t\tis undefined\n",
     917:             u_p_key(map == CcAltMap ? first | 0400 : first));
     918: #else               /* _SEQUENT_ */
     919:         xprintf(" %s\t\tis undefined\n", u_p_key(first));
     920: #endif				/* _SEQUENT_ */
     921:     return;
     922:     }
     923:
     924:     for (fp = FuncNames; fp->name; fp++) {
     925:     if (fp->func == map[first]) {
     926:         if (first == last) {
     927:         xprintf(" %s\t\t%s\n",
     928:             u_p_key((first & 0377) | (map == CcAltMap ? 0400 : 0)),
     929:             fp->name);
     930:         }
     931:         else {
     932:         (void) strcpy(buf, u_p_key((first & 0377) |
     933:                           (map == CcAltMap ? 0400 : 0)));
     934:         xprintf(" %s..%s\t\t%s\n", buf,
     935:              u_p_key((last & 0377) | (map == CcAltMap ? 0400 : 0)),
     936:             fp->name);
     937:         }
     938:         return;
     939:     }
     940:     }
     941:     if (map == CcKeyMap) {
     942:     xprintf("BUG!!! %s isn't bound to anything.\n", u_p_key(first));
     943:     xprintf("CcKeyMap[%d] == %d\n", first, CcKeyMap[first]);
     944:     }
     945:     else {
     946:     xprintf("BUG!!! %s isn't bound to anything.\n",
     947:         u_p_key(first & 0400));
     948:     xprintf("CcAltMap[%d] == %d\n", first, CcAltMap[first]);
     949:     }
     950: }

#### Defined functions

bindkey_usage defined in line 714; used 2 times

- in line 398, 428

dobind defined in line 749; never used
dobindkey defined in line 343; never used
getkeycmd defined in line 152; used 7 times

- in line 50, 267-291(6)

list_functions defined in line 735; used 1 times

- in line 394

parsecmd defined in line 472; used 2 times

- in line 53, 438

parseescape defined in line 487; used 2 times

- in line 584
- in /usr/src/bin/tcsh/tc.prompt.c line 383

parsekey defined in line 198; used 2 times

- in line 778, 866

parsestring defined in line 568; used 2 times

- in line 408, 432

pkeys defined in line 897; used 5 times

- in line 872, 880-891(4)

print_all_keys defined in line 640; used 1 times

- in line 404

prntky defined in line 451; used 1 times

- in line 424

prntkys defined in line 668; used 4 times

- in line 650-653(2), 660-663(2)

rcsid defined in line 39; never used
str7cmp defined in line 65; used 24 times

- in line 308-322(12), 479, 775, 837, 843-859(9)

tocontrol defined in line 75; used 2 times

- in line 168, 333

u_p_key defined in line 91; used 7 times

- in line 917-919(2), 928-935(3), 942-947(2)

u_p_string defined in line 595; used 7 times

- in line 460, 684, 692-697(3), 704-709(2)

Last modified: 1991-08-21 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1756 |