Annotation of 43BSDReno/contrib/emacs-18.55/src/keymap.c, revision 1.1

1.1     ! root        1: /* Manipulation of keymaps
        !             2:    Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GNU Emacs.
        !             5: 
        !             6: GNU Emacs is distributed in the hope that it will be useful,
        !             7: but WITHOUT ANY WARRANTY.  No author or distributor
        !             8: accepts responsibility to anyone for the consequences of using it
        !             9: or for whether it serves any particular purpose or works at all,
        !            10: unless he says so in writing.  Refer to the GNU Emacs General Public
        !            11: License for full details.
        !            12: 
        !            13: Everyone is granted permission to copy, modify and redistribute
        !            14: GNU Emacs, but only under the conditions described in the
        !            15: GNU Emacs General Public License.   A copy of this license is
        !            16: supposed to have been given to you along with GNU Emacs so you
        !            17: can know your rights and responsibilities.  It should be in a
        !            18: file named COPYING.  Among other things, the copyright notice
        !            19: and this notice must be preserved on all copies.  */
        !            20: 
        !            21: 
        !            22: #include "config.h"
        !            23: #include <stdio.h>
        !            24: #undef NULL
        !            25: #include "lisp.h"
        !            26: #include "commands.h"
        !            27: #include "buffer.h"
        !            28: 
        !            29: #define min(a, b) ((a) < (b) ? (a) : (b))
        !            30: 
        !            31: /* Actually allocate storage for these variables */
        !            32: 
        !            33: #ifdef HAVE_X_WINDOWS
        !            34: Lisp_Object MouseMap;          /* Keymap for mouse commands */
        !            35: #endif /* HAVE_X_WINDOWS */
        !            36: 
        !            37: struct Lisp_Vector *CurrentGlobalMap;  /* Current global keymap */
        !            38: 
        !            39: struct Lisp_Vector *GlobalMap; /* default global key bindings */
        !            40: 
        !            41: struct Lisp_Vector *ESCmap;            /* The keymap used for globally
        !            42:                                           bound ESC-prefixed default
        !            43:                                           commands */
        !            44: 
        !            45: struct Lisp_Vector *CtlXmap;           /* The keymap used for globally
        !            46:                                           bound C-x-prefixed default
        !            47:                                           commands */
        !            48: 
        !            49: /* was MinibufLocalMap */
        !            50: Lisp_Object Vminibuffer_local_map;
        !            51:                                /* The keymap used by the minibuf for local
        !            52:                                   bindings when spaces are allowed in the
        !            53:                                   minibuf */
        !            54: 
        !            55: /* was MinibufLocalNSMap */
        !            56: Lisp_Object Vminibuffer_local_ns_map;                  
        !            57:                                /* The keymap used by the minibuf for local
        !            58:                                   bindings when spaces are not encouraged
        !            59:                                   in the minibuf */
        !            60: 
        !            61: /* keymap used for minibuffers when doing completion */
        !            62: /* was MinibufLocalCompletionMap */
        !            63: Lisp_Object Vminibuffer_local_completion_map;
        !            64: 
        !            65: /* keymap used for minibuffers when doing completion and require a match */
        !            66: /* was MinibufLocalMustMatchMap */
        !            67: Lisp_Object Vminibuffer_local_must_match_map;
        !            68: 
        !            69: Lisp_Object Qkeymapp, Qkeymap;
        !            70: 
        !            71: /* A char over 0200 in a key sequence
        !            72:    is equivalent to prefixing with this character.  */
        !            73: 
        !            74: extern int meta_prefix_char;
        !            75: 
        !            76: DEFUN ("make-keymap", Fmake_keymap, Smake_keymap, 0, 0, 0,
        !            77:   "Construct and return a new keymap, a vector of length 128.\n\
        !            78: All entries in it are nil, meaning \"command undefined\".")
        !            79:   ()
        !            80: {
        !            81:   register Lisp_Object val;
        !            82:   XFASTINT (val) = 0200;
        !            83:   return Fmake_vector (val, Qnil);
        !            84: }
        !            85: 
        !            86: DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, Smake_sparse_keymap, 0, 0, 0,
        !            87:   "Construct and return a new sparse-keymap list.\n\
        !            88: Its car is 'keymap and its cdr is an alist of (CHAR . DEFINITION).\n\
        !            89: Initially the alist is nil.")
        !            90:   ()
        !            91: {
        !            92:   return Fcons (Qkeymap, Qnil);
        !            93: }
        !            94: 
        !            95: /* This is used for installing the standard key bindings at initialization time.
        !            96:  For example,  defkey (CtlXmap, Ctl('X'), "exchange-point-and-mark");  */
        !            97: 
        !            98: void
        !            99: defkey (keymap, key, defname)
        !           100:      struct Lisp_Vector *keymap;
        !           101:      int key;
        !           102:      char *defname;
        !           103: {
        !           104:   keymap->contents[key] = intern (defname);
        !           105: }
        !           106: 
        !           107: void
        !           108: ndefkey (keymap, key, defname)
        !           109:      Lisp_Object keymap;
        !           110:      int key;
        !           111:      char *defname;
        !           112: {
        !           113:   store_in_keymap (keymap, key, intern (defname));
        !           114: }
        !           115: 
        !           116: /* Define character fromchar in map frommap as an alias for character tochar in map tomap.
        !           117:  Subsequent redefinitions of the latter WILL affect the former. */
        !           118: 
        !           119: #ifdef NOTDEF
        !           120: void
        !           121: synkey (frommap, fromchar, tomap, tochar)
        !           122:      struct Lisp_Vector *frommap, *tomap;
        !           123:      int fromchar, tochar;
        !           124: {
        !           125:   Lisp_Object v, c;
        !           126:   XSET (v, Lisp_Vector, tomap);
        !           127:   XFASTINT (c) = tochar;
        !           128:   frommap->contents[fromchar] = Fcons (v, c);
        !           129: }
        !           130: #endif /* NOTDEF */
        !           131: 
        !           132: DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0,
        !           133:   "Return t if ARG is a keymap.\n\
        !           134: A keymap is a vector of length 128, or a list (keymap . ALIST),\n\
        !           135: where alist elements look like (CHAR . DEFN).")
        !           136:   (object)
        !           137:      Lisp_Object object;
        !           138: {
        !           139:   register Lisp_Object tem;
        !           140:   tem = object;
        !           141:   while (XTYPE (tem) == Lisp_Symbol)
        !           142:     {
        !           143:       tem = XSYMBOL (tem)->function;
        !           144:       if (EQ (tem, Qunbound))
        !           145:        return Qnil;
        !           146:       QUIT;
        !           147:     }
        !           148: 
        !           149:   if ((XTYPE (tem) == Lisp_Vector && XVECTOR (tem)->size == 0200)
        !           150:       || (CONSP (tem) && EQ (XCONS (tem)->car, Qkeymap)))
        !           151:     return Qt;
        !           152:   return Qnil;
        !           153: }
        !           154: 
        !           155: Lisp_Object
        !           156: get_keymap_1 (object, error)
        !           157:      Lisp_Object object;
        !           158:      int error;
        !           159: {
        !           160:   register Lisp_Object tem;
        !           161: 
        !           162:   while (1)
        !           163:     {
        !           164:       tem = object;
        !           165:       while (XTYPE (tem) == Lisp_Symbol && !EQ (tem, Qunbound))
        !           166:        {
        !           167:          tem = XSYMBOL (tem)->function;
        !           168:          QUIT;
        !           169:        }
        !           170:       if ((XTYPE (tem) == Lisp_Vector && XVECTOR (tem)->size == 0200)
        !           171:          || (CONSP (tem) && EQ (XCONS (tem)->car, Qkeymap)))
        !           172:        return tem;
        !           173:       if (error)
        !           174:        object = wrong_type_argument (Qkeymapp, object);
        !           175:       else return Qnil;
        !           176:     }
        !           177: }
        !           178: 
        !           179: Lisp_Object
        !           180: get_keymap (object)
        !           181:      Lisp_Object object;
        !           182: {
        !           183:   return get_keymap_1 (object, 1);
        !           184: }
        !           185: 
        !           186: Lisp_Object
        !           187: get_keyelt (object)
        !           188:      register Lisp_Object object;
        !           189: {
        !           190:   register Lisp_Object map, tem;
        !           191: 
        !           192:   while (map = get_keymap_1 (Fcar_safe (object), 0),
        !           193:         tem = Fkeymapp (map),
        !           194:         !NULL (tem))
        !           195:       /*(XTYPE (object) == Lisp_Cons && !EQ (XCONS (object)->car, Qkeymap))*/
        !           196:     {
        !           197:       object = Fcdr (object);
        !           198:       if (CONSP (map))
        !           199:        object = Fcdr (Fassq (object, Fcdr (map)));
        !           200:       else
        !           201:        object = Faref (map, object);
        !           202:     }
        !           203:   return object;
        !           204: }
        !           205: 
        !           206: Lisp_Object
        !           207: access_keymap (map, idx)
        !           208:      Lisp_Object map;
        !           209:      register int idx;
        !           210: {
        !           211:   register Lisp_Object val;
        !           212:   if (idx < 0 || idx >= 0200)
        !           213:     error ("Command key out of range 0-127");
        !           214: 
        !           215:   /* Get definition for character `idx' proper.  */
        !           216:   if (CONSP (map))
        !           217:     val = Fcdr (Fassq (make_number (idx), Fcdr (map)));
        !           218:   else
        !           219:     val = XVECTOR (map)->contents[idx];
        !           220: 
        !           221:   return val;
        !           222: }
        !           223: 
        !           224: Lisp_Object
        !           225: store_in_keymap (keymap, idx, def)
        !           226:      Lisp_Object keymap;
        !           227:      register int idx;
        !           228:      register Lisp_Object def;
        !           229: {
        !           230:   register Lisp_Object tem;
        !           231: 
        !           232:   if (idx < 0 || idx >= 0200)
        !           233:     error ("Command key out of range 0-127");
        !           234: 
        !           235:   if (CONSP (keymap))
        !           236:     {
        !           237:       tem = Fassq (make_number (idx), Fcdr (keymap));
        !           238:       if (!NULL (tem))
        !           239:        Fsetcdr (tem, def);
        !           240:       else
        !           241:        Fsetcdr (keymap, Fcons (Fcons (make_number (idx), def),
        !           242:                                Fcdr (keymap)));
        !           243:     }
        !           244:   else
        !           245:     XVECTOR (keymap)->contents[idx] = def;
        !           246: 
        !           247:   return def;
        !           248: }
        !           249: 
        !           250: DEFUN ("copy-keymap", Fcopy_keymap, Scopy_keymap, 1, 1, 0,
        !           251:   "Return a copy of the keymap KEYMAP.\n\
        !           252: The copy starts out with the same definitions of KEYMAP,\n\
        !           253: but changing either the copy or KEYMAP does not affect the other.\n\
        !           254: Any key definitions that are subkeymaps are recursively copied.")
        !           255:   (keymap)
        !           256:      Lisp_Object keymap;
        !           257: {
        !           258:   register Lisp_Object copy, tem;
        !           259: 
        !           260:   keymap = get_keymap (keymap);
        !           261:   if (XTYPE (keymap) == Lisp_Vector)
        !           262:     {
        !           263:       register int i;
        !           264:       copy = Fcopy_sequence (keymap);
        !           265:       for (i = 0; i < XVECTOR (copy)->size; i++)
        !           266:        if (tem = Fkeymapp (XVECTOR (copy)->contents[i]), !NULL (tem))
        !           267:          XVECTOR (copy)->contents[i] = Fcopy_keymap (XVECTOR (copy)->contents[i]);
        !           268:     }
        !           269:   else
        !           270:     {
        !           271:       register Lisp_Object tail;
        !           272:       copy = Fcopy_alist (keymap); 
        !           273:       for (tail = copy; CONSP (tail); tail = XCONS (tail)->cdr)
        !           274:        {
        !           275:          register Lisp_Object elt;
        !           276:          elt = XCONS (tail)->car;
        !           277:          if (CONSP (elt) && (tem = Fkeymapp (XCONS (elt)->cdr), !NULL (tem)))
        !           278:            XCONS (elt)->cdr = Fcopy_keymap (XCONS (elt)->cdr);
        !           279:        }
        !           280:     }
        !           281:   return copy;
        !           282: }
        !           283: 
        !           284: DEFUN ("define-key", Fdefine_key, Sdefine_key, 3, 3, 0,
        !           285:   "Args KEYMAP, KEYS, DEF.  Define key sequence KEYS, in KEYMAP, as DEF.\n\
        !           286: KEYMAP is a keymap.  KEYS is a string meaning a sequence of keystrokes.\n\
        !           287: DEF is anything that can be a key's definition:\n\
        !           288:  nil (means key is undefined in this keymap),\n\
        !           289:  a command (a Lisp function suitable for interactive calling)\n\
        !           290:  a string (treated as a keyboard macro),\n\
        !           291:  a keymap (to define a prefix key),\n\
        !           292:  a list (KEYMAP . CHAR), meaning use definition of CHAR in map KEYMAP,\n\
        !           293:  or a symbol.  The symbol's function definition is used as the key's\n\
        !           294: definition, and may be any of the above (including another symbol).")
        !           295:   (keymap, keys, def)
        !           296:      register Lisp_Object keymap;
        !           297:      Lisp_Object keys;
        !           298:      Lisp_Object def;
        !           299: {
        !           300:   register unsigned char *p;
        !           301:   register int level;
        !           302:   register int c;
        !           303:   register Lisp_Object tem;
        !           304:   register Lisp_Object cmd;
        !           305:   int metized = 0;
        !           306: 
        !           307:   keymap = get_keymap (keymap);
        !           308: 
        !           309:   CHECK_STRING (keys, 1);
        !           310:   p = XSTRING (keys)->data;
        !           311:   level = XSTRING (keys)->size;
        !           312:   if (level == 0) return (Qnil);
        !           313: 
        !           314:   while (1)
        !           315:     {
        !           316:       c = *p;
        !           317:       if (c >= 0200 && !metized)
        !           318:        {
        !           319:          c = meta_prefix_char;
        !           320:          metized = 1;
        !           321:        }
        !           322:       else
        !           323:        {
        !           324:          c &= 0177;
        !           325:          metized = 0;
        !           326:          level--;
        !           327:          p++;
        !           328:        }
        !           329: 
        !           330:       if (!level)
        !           331:        return store_in_keymap (keymap, c, def);
        !           332: 
        !           333:       cmd = get_keyelt (access_keymap (keymap, c));
        !           334:       if (NULL (cmd))
        !           335:        {
        !           336:          cmd = Fmake_sparse_keymap ();
        !           337:          store_in_keymap (keymap, c, cmd);
        !           338:        }
        !           339:       tem = Fkeymapp (cmd);
        !           340:       if (NULL (tem))
        !           341:        error ("Key sequence %s uses invalid prefix characters",
        !           342:               XSTRING (keys)->data);
        !           343: 
        !           344:       keymap = get_keymap (cmd);
        !           345:     }
        !           346: }
        !           347: 
        !           348: /* Value is number if `keys' is too long; NIL if valid but has no definition. */
        !           349: 
        !           350: DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 2, 0,
        !           351:   "In keymap KEYMAP, look up key sequence KEYS.  Return the definition.\n\
        !           352: nil means undefined.  See doc of define-key for kinds of definitions.\n\
        !           353: Number as value means KEYS is \"too long\";\n\
        !           354: that is, characters in it except for the last one\n\
        !           355: fail to be a valid sequence of prefix characters in KEYMAP.\n\
        !           356: The number is how many characters at the front of KEYS\n\
        !           357: it takes to reach a non-prefix command.")
        !           358:   (keymap, keys)
        !           359:      register Lisp_Object keymap;
        !           360:      Lisp_Object keys;
        !           361: {
        !           362:   register unsigned char *p;
        !           363:   register int level;
        !           364:   register Lisp_Object tem;
        !           365:   register Lisp_Object cmd;
        !           366:   register int c;
        !           367:   int metized = 0;
        !           368: 
        !           369:   keymap = get_keymap (keymap);
        !           370: 
        !           371:   CHECK_STRING (keys, 1);
        !           372:   p = XSTRING (keys)->data;
        !           373:   level = XSTRING (keys)->size;
        !           374:   if (level == 0) return (Qnil);
        !           375: 
        !           376:   while (1)
        !           377:     {
        !           378:       c = *p;
        !           379:       if (c >= 0200 && !metized)
        !           380:        {
        !           381:          c = meta_prefix_char;
        !           382:          metized = 1;
        !           383:        }
        !           384:       else
        !           385:        {
        !           386:          c &= 0177;
        !           387:          metized = 0;
        !           388:          level--;
        !           389:          p++;
        !           390:        }
        !           391: 
        !           392:       cmd = get_keyelt (access_keymap (keymap, c));
        !           393:       if (!level)
        !           394:        return cmd;
        !           395: 
        !           396:       tem = Fkeymapp (cmd);
        !           397:       if (NULL (tem))
        !           398:        return make_number (XSTRING (keys)->size - level);
        !           399: 
        !           400:       keymap = get_keymap (cmd);
        !           401:       QUIT;
        !           402:     }
        !           403: }
        !           404: 
        !           405: DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 1, 0,
        !           406:   "Return the definition for command KEYS in current keymaps.\n\
        !           407: KEYS is a string, a sequence of keystrokes.\n\
        !           408: The definition is probably a symbol with a function definition.")
        !           409:   (keys)
        !           410:      Lisp_Object keys;
        !           411: {
        !           412:   register Lisp_Object map, value, value1;
        !           413:   map = bf_cur->keymap;
        !           414:   if (!NULL (map))
        !           415:     {
        !           416:       value = Flookup_key (map, keys);
        !           417:       if (NULL (value))
        !           418:        {
        !           419:          XSET (map, Lisp_Vector, CurrentGlobalMap);
        !           420:          value1 = Flookup_key (map, keys);
        !           421:          if (XTYPE (value1) == Lisp_Int)
        !           422:            return Qnil;
        !           423:          return value1;
        !           424:        }
        !           425:       else if (XTYPE (value) != Lisp_Int)
        !           426:        return value;
        !           427:     }
        !           428:   XSET (map, Lisp_Vector, CurrentGlobalMap);
        !           429:   return Flookup_key (map, keys);
        !           430: }
        !           431: 
        !           432: DEFUN ("local-key-binding", Flocal_key_binding, Slocal_key_binding, 1, 1, 0,
        !           433:   "Return the definition for command KEYS in current local keymap only.\n\
        !           434: KEYS is a string, a sequence of keystrokes.\n\
        !           435: The definition is probably a symbol with a function definition.")
        !           436:   (keys)
        !           437:      Lisp_Object keys;
        !           438: {
        !           439:   register Lisp_Object map;
        !           440:   map = bf_cur->keymap;
        !           441:   if (NULL (map))
        !           442:     return Qnil;
        !           443:   return Flookup_key (map, keys);
        !           444: }
        !           445: 
        !           446: DEFUN ("global-key-binding", Fglobal_key_binding, Sglobal_key_binding, 1, 1, 0,
        !           447:   "Return the definition for command KEYS in current global keymap only.\n\
        !           448: KEYS is a string, a sequence of keystrokes.\n\
        !           449: The definition is probably a symbol with a function definition.")
        !           450:   (keys)
        !           451:      Lisp_Object keys;
        !           452: {
        !           453:   register Lisp_Object map;
        !           454:   XSET (map, Lisp_Vector, CurrentGlobalMap);
        !           455:   return Flookup_key (map, keys);
        !           456: }
        !           457: 
        !           458: DEFUN ("global-set-key", Fglobal_set_key, Sglobal_set_key, 2, 2,
        !           459:   "kSet key globally: \nCSet key %s to command: ",
        !           460:   "Give KEY a definition of COMMAND.\n\
        !           461: COMMAND is a symbol naming an interactively-callable function.\n\
        !           462: KEY is a string representing a sequence of keystrokes.\n\
        !           463: Note that if KEY has a local definition in the current buffer\n\
        !           464: that local definition will continue to shadow any global definition.")
        !           465:   (keys, function)
        !           466:      Lisp_Object keys, function;
        !           467: {
        !           468:   register Lisp_Object map;
        !           469:   XSET (map, Lisp_Vector, CurrentGlobalMap);
        !           470:   CHECK_STRING (keys, 1);
        !           471:   Fdefine_key (map, keys, function);
        !           472:   return Qnil;
        !           473: }
        !           474: 
        !           475: DEFUN ("local-set-key", Flocal_set_key, Slocal_set_key, 2, 2,
        !           476:   "kSet key locally: \nCSet key %s locally to command: ",
        !           477:   "Give KEY a local definition of COMMAND.\n\
        !           478: COMMAND is a symbol naming an interactively-callable function.\n\
        !           479: KEY is a string representing a sequence of keystrokes.\n\
        !           480: The definition goes in the current buffer's local map,\n\
        !           481: which is shared with other buffers in the same major mode.")
        !           482:   (keys, function)
        !           483:      Lisp_Object keys, function;
        !           484: {
        !           485:   register Lisp_Object map;
        !           486:   map = bf_cur->keymap;
        !           487:   if (NULL (map))
        !           488:     {
        !           489:       map = Fmake_sparse_keymap ();
        !           490:       bf_cur->keymap = map;
        !           491:     }
        !           492: 
        !           493:   CHECK_STRING (keys, 1);
        !           494:   Fdefine_key (map, keys, function);
        !           495:   return Qnil;
        !           496: }
        !           497: 
        !           498: DEFUN ("global-unset-key", Fglobal_unset_key, Sglobal_unset_key,
        !           499:   1, 1, "kUnset key globally: ",
        !           500:   "Remove global definition of KEY.\n\
        !           501: KEY is a string representing a sequence of keystrokes.")
        !           502:   (keys)
        !           503:      Lisp_Object keys;
        !           504: {
        !           505:   return Fglobal_set_key (keys, Qnil);
        !           506: }
        !           507: 
        !           508: DEFUN ("local-unset-key", Flocal_unset_key, Slocal_unset_key, 1, 1,
        !           509:   "kUnset key locally: ",
        !           510:   "Remove local definition of KEY.\n\
        !           511: KEY is a string representing a sequence of keystrokes.")
        !           512:   (keys)
        !           513:      Lisp_Object keys;
        !           514: {
        !           515:   if (!NULL (bf_cur->keymap))
        !           516:     Flocal_set_key (keys, Qnil);
        !           517:   return Qnil;
        !           518: }
        !           519: 
        !           520: DEFUN ("define-prefix-command", Fdefine_prefix_command, Sdefine_prefix_command, 1, 1, 0,
        !           521:   "Define SYMBOL as a prefix command.\n\
        !           522: A keymap is created and stored as SYMBOL's function definition.")
        !           523:   (name)
        !           524:      Lisp_Object name;
        !           525: {
        !           526:   Ffset (name, Fmake_keymap ());
        !           527:   return name;
        !           528: }
        !           529: 
        !           530: DEFUN ("use-global-map", Fuse_global_map, Suse_global_map, 1, 1, 0,
        !           531:   "Selects KEYMAP as the global keymap.")
        !           532:   (keymap)
        !           533:      Lisp_Object keymap;
        !           534: {
        !           535:   keymap = get_keymap (keymap);
        !           536:   CHECK_VECTOR (keymap, 0);
        !           537:   CurrentGlobalMap = XVECTOR (keymap);
        !           538:   return Qnil;
        !           539: }
        !           540: 
        !           541: DEFUN ("use-local-map", Fuse_local_map, Suse_local_map, 1, 1, 0,
        !           542:   "Selects KEYMAP as the local keymap.\n\
        !           543: nil for KEYMAP means no local keymap.")
        !           544:   (keymap)
        !           545:      Lisp_Object keymap;
        !           546: {
        !           547:   if (!NULL (keymap))
        !           548:     keymap = get_keymap (keymap);
        !           549: 
        !           550:   bf_cur->keymap = keymap;
        !           551: 
        !           552:   return Qnil;
        !           553: }
        !           554: 
        !           555: DEFUN ("current-local-map", Fcurrent_local_map, Scurrent_local_map, 0, 0, 0,
        !           556:   "Return current buffer's local keymap, or nil if it has none.")
        !           557:   ()
        !           558: {
        !           559:   return bf_cur->keymap;
        !           560: }
        !           561: 
        !           562: DEFUN ("current-global-map", Fcurrent_global_map, Scurrent_global_map, 0, 0, 0,
        !           563:   "Return the current global keymap.")
        !           564:   ()
        !           565: {
        !           566:   register Lisp_Object tem;
        !           567:   XSET (tem, Lisp_Vector, CurrentGlobalMap);
        !           568:   return tem;
        !           569: }
        !           570: 
        !           571: DEFUN ("accessible-keymaps", Faccessible_keymaps, Saccessible_keymaps,
        !           572:   1, 1, 0,
        !           573:   "Find all keymaps accessible via prefix characters from KEYMAP.\n\
        !           574: Returns a list of elements of the form (KEYS . MAP), where the sequence\n\
        !           575: KEYS starting from KEYMAP gets you to MAP.  These elements are ordered\n\
        !           576: so that the KEYS increase in length.  The first element is (\"\" . KEYMAP).")
        !           577:   (startmap)
        !           578:      Lisp_Object startmap;
        !           579: {
        !           580:   Lisp_Object maps, tail;
        !           581:   register Lisp_Object thismap, thisseq;
        !           582:   register Lisp_Object dummy;
        !           583:   register Lisp_Object tem;
        !           584:   register Lisp_Object cmd;
        !           585:   register int i;
        !           586: 
        !           587:   maps = Fcons (Fcons (build_string (""), get_keymap (startmap)), Qnil);
        !           588:   tail = maps;
        !           589: 
        !           590:   /* For each map in the list maps,
        !           591:      look at any other maps it points to
        !           592:      and stick them at the end if they are not already in the list */
        !           593: 
        !           594:   while (!NULL (tail))
        !           595:     {
        !           596:       thisseq = Fcar (Fcar (tail));
        !           597:       thismap = Fcdr (Fcar (tail));
        !           598:       for (i = 0; i < 0200; i++)
        !           599:        {
        !           600:          cmd = get_keyelt (access_keymap (thismap, i));
        !           601:          if (NULL (cmd)) continue;
        !           602:          tem = Fkeymapp (cmd);
        !           603:          if (!NULL (tem))
        !           604:            {
        !           605:              cmd = get_keymap (cmd);
        !           606:              tem = Frassq (cmd, maps);
        !           607:              if (NULL (tem))
        !           608:                {
        !           609:                  XFASTINT (dummy) = i;
        !           610:                  dummy = concat2 (thisseq, Fchar_to_string (dummy));
        !           611:                  nconc2 (tail, Fcons (Fcons (dummy, cmd), Qnil));
        !           612:                }
        !           613:            }
        !           614:        }
        !           615:       tail = Fcdr (tail);
        !           616:     }
        !           617: 
        !           618:   return maps;
        !           619: }
        !           620: 
        !           621: Lisp_Object Qsingle_key_description, Qkey_description;
        !           622: 
        !           623: DEFUN ("key-description", Fkey_description, Skey_description, 1, 1, 0,
        !           624:   "Return a pretty description of key-sequence KEYS.\n\
        !           625: Control characters turn into \"C-foo\" sequences, meta into \"M-foo\"\n\
        !           626: spaces are put between sequence elements, etc.")
        !           627:   (keys)
        !           628:      Lisp_Object keys;
        !           629: {
        !           630:   return Fmapconcat (Qsingle_key_description, keys, build_string (" "));
        !           631: }
        !           632: 
        !           633: char *
        !           634: push_key_description (c, p)
        !           635:      register unsigned int c;
        !           636:      register char *p;
        !           637: {
        !           638:   if (c >= 0200)
        !           639:     {
        !           640:       *p++ = 'M';
        !           641:       *p++ = '-';
        !           642:       c -= 0200;
        !           643:     }
        !           644:   if (c < 040)
        !           645:     {
        !           646:       if (c == 033)
        !           647:        {
        !           648:          *p++ = 'E';
        !           649:          *p++ = 'S';
        !           650:          *p++ = 'C';
        !           651:        }
        !           652:       else if (c == Ctl('I'))
        !           653:        {
        !           654:          *p++ = 'T';
        !           655:          *p++ = 'A';
        !           656:          *p++ = 'B';
        !           657:        }
        !           658:       else if (c == Ctl('J'))
        !           659:        {
        !           660:          *p++ = 'L';
        !           661:          *p++ = 'F';
        !           662:          *p++ = 'D';
        !           663:        }
        !           664:       else if (c == Ctl('M'))
        !           665:        {
        !           666:          *p++ = 'R';
        !           667:          *p++ = 'E';
        !           668:          *p++ = 'T';
        !           669:        }
        !           670:       else
        !           671:        {
        !           672:          *p++ = 'C';
        !           673:          *p++ = '-';
        !           674:          if (c > 0 && c <= Ctl ('Z'))
        !           675:            *p++ = c + 0140;
        !           676:          else
        !           677:            *p++ = c + 0100;
        !           678:        }
        !           679:     }
        !           680:   else if (c == 0177)
        !           681:     {
        !           682:       *p++ = 'D';
        !           683:       *p++ = 'E';
        !           684:       *p++ = 'L';
        !           685:     }
        !           686:   else if (c == ' ')
        !           687:     {
        !           688:       *p++ = 'S';
        !           689:       *p++ = 'P';
        !           690:       *p++ = 'C';
        !           691:     }
        !           692:   else
        !           693:     *p++ = c;
        !           694:   return p;  
        !           695: }
        !           696: 
        !           697: DEFUN ("single-key-description", Fsingle_key_description, Ssingle_key_description, 1, 1, 0,
        !           698:   "Return a pretty description of command character KEY.\n\
        !           699: Control characters turn into C-whatever, etc.")
        !           700:   (key)
        !           701:      Lisp_Object key;
        !           702: {
        !           703:   register unsigned char c;
        !           704:   char tem[6];
        !           705: 
        !           706:   CHECK_NUMBER (key, 0);
        !           707:   c = XINT (key) & 0377;
        !           708: 
        !           709:   *push_key_description (c, tem) = 0;
        !           710: 
        !           711:   return build_string (tem);
        !           712: }
        !           713: 
        !           714: char *
        !           715: push_text_char_description (c, p)
        !           716:      register unsigned int c;
        !           717:      register char *p;
        !           718: {
        !           719:   if (c >= 0200)
        !           720:     {
        !           721:       *p++ = 'M';
        !           722:       *p++ = '-';
        !           723:       c -= 0200;
        !           724:     }
        !           725:   if (c < 040)
        !           726:     {
        !           727:       *p++ = '^';
        !           728:       *p++ = c + 64;           /* 'A' - 1 */
        !           729:     }
        !           730:   else if (c == 0177)
        !           731:     {
        !           732:       *p++ = '^';
        !           733:       *p++ = '?';
        !           734:     }
        !           735:   else
        !           736:     *p++ = c;
        !           737:   return p;  
        !           738: }
        !           739: 
        !           740: DEFUN ("text-char-description", Ftext_char_description, Stext_char_description, 1, 1, 0,
        !           741:   "Return a pretty description of file-character CHAR.\n\
        !           742: Control characters turn into \"^char\", etc.")
        !           743:   (chr)
        !           744:      Lisp_Object chr;
        !           745: {
        !           746:   char tem[6];
        !           747: 
        !           748:   CHECK_NUMBER (chr, 0);
        !           749: 
        !           750:   *push_text_char_description (XINT (chr) & 0377, tem) = 0;
        !           751: 
        !           752:   return build_string (tem);
        !           753: }
        !           754: 
        !           755: DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 3, 0,
        !           756:   "Return list of key sequences that currently invoke command DEFINITION\n\
        !           757: in KEYMAP or (current-global-map).  If KEYMAP is nil, only search for\n\
        !           758: keys in the global map.\n\
        !           759: \n\
        !           760: If FIRSTONLY is non-nil, returns a string representing the first key\n\
        !           761: sequence found, rather than a list of all possible key sequences.")
        !           762:   (definition, local_keymap, firstonly)
        !           763:      Lisp_Object definition, local_keymap, firstonly;
        !           764: {
        !           765:   Lisp_Object start1;
        !           766:   register Lisp_Object maps;
        !           767:   Lisp_Object found;
        !           768: 
        !           769:   XSET (start1, Lisp_Vector, CurrentGlobalMap);
        !           770: 
        !           771:   if (!NULL (local_keymap))
        !           772:     maps = nconc2 (Faccessible_keymaps (get_keymap (local_keymap)),
        !           773:                   Faccessible_keymaps (start1));
        !           774:   else
        !           775:     maps = Faccessible_keymaps (start1);
        !           776: 
        !           777:   found = Qnil;
        !           778: 
        !           779:   for (; !NULL (maps); maps = Fcdr (maps))
        !           780:     {
        !           781:       register this = Fcar (Fcar (maps)); /* Key sequence to reach map */
        !           782:       register map = Fcdr (Fcar (maps)); /* The map that it reaches */
        !           783:       register int i = 0;
        !           784:         
        !           785:       if (CONSP (map))
        !           786:        map = Fcdr (map);
        !           787: 
        !           788:       /* If the MAP is a vector, I increments and eventually reaches 0200.
        !           789:         Otherwise I remains 0; MAP is cdr'd and eventually becomes nil.  */
        !           790: 
        !           791:       while (!NULL (map) && i < 0200)
        !           792:        {
        !           793:          register Lisp_Object elt, dummy;
        !           794: 
        !           795:          QUIT;
        !           796:          if (CONSP (map))
        !           797:            {
        !           798:              elt = Fcdr (Fcar (map));
        !           799:              dummy = Fcar (Fcar (map));
        !           800:              map = Fcdr (map);
        !           801:            }
        !           802:          else
        !           803:            {
        !           804:              elt = XVECTOR (map)->contents[i];
        !           805:              XFASTINT (dummy) = i;
        !           806:              i++;
        !           807:            }
        !           808: 
        !           809:          if (XTYPE (definition) != Lisp_Cons)
        !           810:            elt = get_keyelt (elt);
        !           811: 
        !           812:          /* End this iteration if this element does not match
        !           813:             the target.  */
        !           814: 
        !           815:          if (XTYPE (definition) == Lisp_Cons)
        !           816:            {
        !           817:              Lisp_Object tem;
        !           818:              tem = Fequal (elt, definition);
        !           819:              if (NULL (tem))
        !           820:                continue;
        !           821:            }
        !           822:          else
        !           823:            if (!EQ (elt, definition))
        !           824:              continue;
        !           825: 
        !           826:          /* We have found a match.
        !           827:             Construct the key sequence where we found it.  */
        !           828: 
        !           829:          dummy = concat2 (this, Fchar_to_string (dummy));
        !           830: 
        !           831:          /* Verify that this key binding is not shadowed
        !           832:             by another binding for the same key,
        !           833:             before we say it exists.
        !           834:             The mechanism: look for local definition of this key
        !           835:             and if it is defined and does not match what we found
        !           836:             then ignore this key.
        !           837:             Either nil or number as value from Flookup_key
        !           838:             means undefined.  */
        !           839: 
        !           840:          if (!NULL (local_keymap))
        !           841:            elt = Flookup_key (local_keymap, dummy);
        !           842:          if (!NULL (elt) && XTYPE (elt) != Lisp_Int)
        !           843:            {
        !           844:              if (XTYPE (definition) == Lisp_Cons)
        !           845:                {
        !           846:                  Lisp_Object tem;
        !           847:                  tem = Fequal (elt, definition);
        !           848:                  if (NULL (tem))
        !           849:                    continue;
        !           850:                }
        !           851:              else
        !           852:                if (!EQ (elt, definition))
        !           853:                  continue;
        !           854:            }
        !           855: 
        !           856:          /* It is a true unshadowed match  Record it.  */
        !           857: 
        !           858:          if (!NULL (firstonly))
        !           859:            return dummy;
        !           860:          found = Fcons (dummy, found);
        !           861:        }
        !           862:     }
        !           863:   return Fnreverse (found);
        !           864: }
        !           865: 
        !           866: DEFUN ("where-is", Fwhere_is, Swhere_is, 1, 1, "CWhere is command: ",
        !           867:   "Print message listing key sequences that invoke specified command.\n\
        !           868: Argument is a command definition, usually a symbol with a function definition.")
        !           869:   (definition)
        !           870:      Lisp_Object definition;
        !           871: {
        !           872:   register Lisp_Object tem;
        !           873:   CHECK_SYMBOL (definition, 0);
        !           874:   tem = Fmapconcat (Qkey_description,
        !           875:                    Fwhere_is_internal (definition, bf_cur->keymap, Qnil),
        !           876:                    build_string (", "));
        !           877:   if (XSTRING (tem)->size)
        !           878:     message ("%s is on %s", XSYMBOL (definition)->name->data, XSTRING (tem)->data);
        !           879:   else
        !           880:     message ("%s is not on any keys", XSYMBOL (definition)->name->data);
        !           881:   return Qnil;
        !           882: }
        !           883: 
        !           884: Lisp_Object describe_buffer_bindings ();
        !           885: 
        !           886: DEFUN ("describe-bindings", Fdescribe_bindings, Sdescribe_bindings, 0, 0, "",
        !           887:   "Show a list of all defined keys, and their definitions.\n\
        !           888: The list is put in a buffer, which is displayed.")
        !           889:   ()
        !           890: {
        !           891:   register Lisp_Object thisbuf;
        !           892:   XSET (thisbuf, Lisp_Buffer, bf_cur);
        !           893:   internal_with_output_to_temp_buffer ("*Help*", describe_buffer_bindings, thisbuf);
        !           894:   return Qnil;
        !           895: }
        !           896: 
        !           897: Lisp_Object
        !           898: describe_buffer_bindings (descbuf)
        !           899:      Lisp_Object descbuf;
        !           900: {
        !           901:   register Lisp_Object start1;
        !           902:   char *heading = "key         binding\n---            -------\n";
        !           903: 
        !           904:   Fset_buffer (Vstandard_output);
        !           905: 
        !           906:   start1 = XBUFFER (descbuf)->keymap;
        !           907:   if (!NULL (start1))
        !           908:     {
        !           909:       InsStr ("Local Bindings:\n");
        !           910:       InsStr (heading);
        !           911:       heading = 0;
        !           912:       describe_map_tree (start1, 0, Qnil);
        !           913:       InsStr ("\n");
        !           914:     }
        !           915: 
        !           916:   InsStr ("Global Bindings:\n");
        !           917:   if (heading)
        !           918:     InsStr (heading);
        !           919: 
        !           920:   XSET (start1, Lisp_Vector, CurrentGlobalMap);
        !           921:   describe_map_tree (start1, 0, XBUFFER (descbuf)->keymap);
        !           922: 
        !           923:   Fset_buffer (descbuf);
        !           924:   return Qnil;
        !           925: }
        !           926: 
        !           927: /* Insert a desription of the key bindings in STARTMAP,
        !           928:    followed by those of all maps reachable through STARTMAP.
        !           929:    If PARTIAL is nonzero, omit certain "uninteresting" commands
        !           930:    (such as `undefined').
        !           931:    If SHADOW is non-nil, don't mention keys which would be shadowed by it */
        !           932: 
        !           933: describe_map_tree (startmap, partial, shadow)
        !           934:      Lisp_Object startmap, shadow;
        !           935:      int partial;
        !           936: {
        !           937:   register Lisp_Object maps, elt, sh;
        !           938: 
        !           939:   maps = Faccessible_keymaps (startmap);
        !           940: 
        !           941:   for (; !NULL (maps); maps = Fcdr (maps))
        !           942:     {
        !           943:       elt = Fcar (maps);
        !           944:       sh = Fcar (elt);
        !           945:       if (NULL (shadow))
        !           946:        sh = Qnil;
        !           947:       else if (XTYPE (sh) == Lisp_String &&
        !           948:               XSTRING (sh)->size == 0)
        !           949:        sh = shadow;
        !           950:       else
        !           951:        {
        !           952:          sh = Flookup_key (shadow, Fcar (elt));
        !           953:          if (XTYPE (sh) == Lisp_Int)
        !           954:            sh = Qnil;
        !           955:        }
        !           956:       if (NULL (sh) || !NULL (Fkeymapp (sh)))
        !           957:        describe_map (Fcdr (elt), Fcar (elt), partial, sh);
        !           958:     }
        !           959: }
        !           960: 
        !           961: describe_command (definition)
        !           962:      Lisp_Object definition;
        !           963: {
        !           964:   register Lisp_Object tem1;
        !           965: 
        !           966:   if (XTYPE (definition) == Lisp_Symbol)
        !           967:     {
        !           968:       XSET (tem1, Lisp_String, XSYMBOL (definition)->name);
        !           969:       InsCStr (XSTRING (tem1)->data, XSTRING (tem1)->size);
        !           970:     }
        !           971:   else
        !           972:     {
        !           973:       tem1 = Fkeymapp (definition);
        !           974:       if (!NULL (tem1))
        !           975:        InsStr ("Prefix Command");
        !           976:       else
        !           977:        InsStr ("??");
        !           978:     }
        !           979: }
        !           980: 
        !           981: /* Describe the contents of map MAP, assuming that this map
        !           982:    itself is reached by the sequence of prefix keys KEYS (a string).
        !           983:    PARTIAL and SHADOW are the same as in `describe_map_tree' above.  */
        !           984: 
        !           985: describe_map (map, keys, partial, shadow)
        !           986:      Lisp_Object map, keys;
        !           987:      int partial;
        !           988:      Lisp_Object shadow;
        !           989: {
        !           990:   register Lisp_Object keysdesc;
        !           991: 
        !           992:   if (!NULL (keys) && XSTRING (keys)->size > 0)
        !           993:     keysdesc = Fkey_description (keys);
        !           994:   else
        !           995:     keysdesc = Qnil;
        !           996: 
        !           997:   if (CONSP (map))
        !           998:     describe_alist (Fcdr (map), keysdesc, describe_command,
        !           999:                    partial, shadow);
        !          1000:   else
        !          1001:     describe_vector (map, keysdesc, describe_command,
        !          1002:                     partial, shadow);
        !          1003: }
        !          1004: 
        !          1005: describe_alist (alist, elt_prefix, elt_describer, partial, shadow)
        !          1006:      register Lisp_Object alist;
        !          1007:      register Lisp_Object elt_prefix;
        !          1008:      int (*elt_describer) ();
        !          1009:      int partial;
        !          1010:      Lisp_Object shadow;
        !          1011: {
        !          1012:   Lisp_Object this;
        !          1013:   register Lisp_Object tem1, tem2;
        !          1014:   int indent;
        !          1015:   Lisp_Object suppress;
        !          1016:   Lisp_Object kludge = Qnil;
        !          1017:   int first = 1;
        !          1018: 
        !          1019:   if (partial)
        !          1020:     suppress = intern ("suppress-keymap");
        !          1021: 
        !          1022:   for (; CONSP (alist); alist = Fcdr (alist))
        !          1023:     {
        !          1024:       QUIT;
        !          1025:       tem1 = Fcar (Fcar (alist));
        !          1026:       tem2 = get_keyelt (Fcdr (Fcar (alist)));
        !          1027:       if (NULL (tem2)) continue;
        !          1028:       if (XTYPE (tem2) == Lisp_Symbol && partial)
        !          1029:        {
        !          1030:          this = Fget (tem2, suppress);
        !          1031:          if (!NULL (this))
        !          1032:            continue;
        !          1033:        }
        !          1034: 
        !          1035:       if (!NULL (shadow))
        !          1036:        {
        !          1037:          Lisp_Object tem;
        !          1038:          if (NULL (kludge)) kludge = build_string ("x");
        !          1039:          XSTRING (kludge)->data[0] = XINT (tem1);
        !          1040:          tem = Flookup_key (shadow, kludge);
        !          1041:          if (!NULL (tem)) continue;
        !          1042:        }
        !          1043: 
        !          1044:       indent = 0;
        !          1045: 
        !          1046:       if (first)
        !          1047:        {
        !          1048:          InsCStr ("\n", 1);
        !          1049:          first = 0;
        !          1050:        }
        !          1051: 
        !          1052:       if (!NULL (elt_prefix))
        !          1053:        {
        !          1054:          InsCStr (XSTRING (elt_prefix)->data, XSTRING (elt_prefix)->size);
        !          1055:          InsCStr (" ", 1);
        !          1056:          indent += XSTRING (elt_prefix)->size + 1;
        !          1057:        }
        !          1058: 
        !          1059:       this = Fsingle_key_description (tem1);
        !          1060:       InsCStr (XSTRING (this)->data, XSTRING (this)->size);
        !          1061:       indent += XSTRING (this)->size;
        !          1062: 
        !          1063:       InsCStr ("                    ", indent<16 ? 16-indent : 1);
        !          1064: 
        !          1065:       (*elt_describer) (tem2);
        !          1066:       InsCStr ("\n", 1);
        !          1067:     }
        !          1068: }
        !          1069: 
        !          1070: describe_vector (vector, elt_prefix, elt_describer, partial, shadow)
        !          1071:      register Lisp_Object vector;
        !          1072:      register Lisp_Object elt_prefix;
        !          1073:      int (*elt_describer) ();
        !          1074:      int partial;
        !          1075:      Lisp_Object shadow;
        !          1076: {
        !          1077:   Lisp_Object this;
        !          1078:   Lisp_Object dummy;
        !          1079:   Lisp_Object tem1, tem2;
        !          1080:   register int i, size = XVECTOR (vector)->size;
        !          1081:   int indent;
        !          1082:   Lisp_Object suppress;
        !          1083:   Lisp_Object kludge = Qnil;
        !          1084:   int first = 1;
        !          1085: 
        !          1086:   if (partial)
        !          1087:     suppress = intern ("suppress-keymap");
        !          1088: 
        !          1089:   for (i = 0; i < size; i++)
        !          1090:     {
        !          1091:       QUIT;
        !          1092:       tem1 = get_keyelt (XVECTOR (vector)->contents[i]);
        !          1093:       if (NULL (tem1)) continue;      
        !          1094:       if (XTYPE (tem1) == Lisp_Symbol && partial)
        !          1095:        {
        !          1096:          this = Fget (tem1, suppress);
        !          1097:          if (!NULL (this))
        !          1098:            continue;
        !          1099:        }
        !          1100: 
        !          1101:       if (!NULL (shadow))
        !          1102:        {
        !          1103:          Lisp_Object tem;
        !          1104:          if (NULL (kludge)) kludge = build_string ("x");
        !          1105:          XSTRING (kludge)->data[0] = XINT (i);
        !          1106:          tem = Flookup_key (shadow, kludge);
        !          1107:          if (!NULL (tem)) continue;
        !          1108:        }
        !          1109: 
        !          1110:       indent = 0;
        !          1111: 
        !          1112:       if (first)
        !          1113:        {
        !          1114:          InsCStr ("\n", 1);
        !          1115:          first = 0;
        !          1116:        }
        !          1117: 
        !          1118:       if (!NULL (elt_prefix))
        !          1119:        {
        !          1120:          InsCStr (XSTRING (elt_prefix)->data, XSTRING (elt_prefix)->size);
        !          1121:          InsCStr (" ", 1);
        !          1122:          indent += XSTRING (elt_prefix)->size + 1;
        !          1123:        }
        !          1124:       XFASTINT (dummy) = i;
        !          1125:       this = Fsingle_key_description (dummy);
        !          1126:       InsCStr (XSTRING (this)->data, XSTRING (this)->size);
        !          1127:       indent += XSTRING (this)->size;
        !          1128: 
        !          1129:       while (i + 1 < size
        !          1130:             && (tem2 = get_keyelt (XVECTOR (vector)->contents[i+1]),
        !          1131:                 EQ (tem2, tem1)))
        !          1132:        i++;
        !          1133: 
        !          1134:       if (i != XINT (dummy))
        !          1135:        {
        !          1136:          InsCStr (" .. ", 4);
        !          1137:          indent += 4;
        !          1138:          if (!NULL (elt_prefix))
        !          1139:            {
        !          1140:              InsCStr (XSTRING (elt_prefix)->data, XSTRING (elt_prefix)->size);
        !          1141:              InsCStr (" ", 1);
        !          1142:              indent += XSTRING (elt_prefix)->size + 1;
        !          1143:            }
        !          1144:          XFASTINT (dummy) = i;
        !          1145:          this = Fsingle_key_description (dummy);
        !          1146:          InsCStr (XSTRING (this)->data, XSTRING (this)->size);
        !          1147:          indent += XSTRING (this)->size;
        !          1148:        }
        !          1149: 
        !          1150:       InsCStr ("                    ", indent<16 ? 16-indent : 1);
        !          1151: 
        !          1152:       (*elt_describer) (tem1);
        !          1153:       InsCStr ("\n", 1);
        !          1154:     }
        !          1155: }
        !          1156: 
        !          1157: /* Apropos */
        !          1158: Lisp_Object apropos_predicate;
        !          1159: Lisp_Object apropos_accumulate;
        !          1160: 
        !          1161: static
        !          1162: apropos_accum (symbol, string)
        !          1163:      Lisp_Object symbol, string;
        !          1164: {
        !          1165:   register Lisp_Object tem;
        !          1166: 
        !          1167:   tem = Fstring_match (string, Fsymbol_name (symbol), Qnil);
        !          1168:   if (!NULL (tem) && !NULL (apropos_predicate))
        !          1169:     tem = call1 (apropos_predicate, symbol);
        !          1170:   if (!NULL (tem))
        !          1171:     apropos_accumulate = Fcons (symbol, apropos_accumulate);
        !          1172: }
        !          1173: 
        !          1174: static Lisp_Object
        !          1175: apropos1 (list)
        !          1176:      register Lisp_Object list;
        !          1177: {
        !          1178:   struct buffer *old = bf_cur;
        !          1179:   register Lisp_Object symbol, col, tem;
        !          1180: 
        !          1181:   while (!NULL (list))
        !          1182:     {
        !          1183:       QUIT;
        !          1184: 
        !          1185:       symbol = Fcar (list);
        !          1186:       list = Fcdr (list);
        !          1187: 
        !          1188:       tem = Fwhere_is_internal (symbol, bf_cur->keymap, Qnil);
        !          1189:       tem = Fmapconcat (Qkey_description, tem, build_string (", "));
        !          1190:       XFASTINT (col) = 30;
        !          1191: 
        !          1192:       SetBfp (XBUFFER (Vstandard_output));
        !          1193:       Fprin1 (symbol, Qnil);
        !          1194:       Findent_to (col, Qnil);
        !          1195:       Fprinc (tem, Qnil);
        !          1196:       Fterpri (Qnil);
        !          1197:       tem = Ffboundp (symbol);
        !          1198:       if (!NULL (tem))
        !          1199:         tem = Fdocumentation (symbol);
        !          1200:       if (XTYPE (tem) == Lisp_String)
        !          1201:        insert_first_line ("  Function: ", tem);
        !          1202:       tem = Fdocumentation_property (symbol, Qvariable_documentation);
        !          1203:       if (XTYPE (tem) == Lisp_String)
        !          1204:        insert_first_line ("  Variable: ", tem);
        !          1205:       SetBfp (old);
        !          1206:     }
        !          1207:   return Qnil;
        !          1208: }
        !          1209: 
        !          1210: static
        !          1211: insert_first_line (prefix, str)
        !          1212:      char *prefix;
        !          1213:      Lisp_Object str;
        !          1214: {
        !          1215:   extern char *index ();
        !          1216:   register unsigned char *p;
        !          1217:   register unsigned char *p1;
        !          1218:   register unsigned char *p2;
        !          1219: 
        !          1220:   InsStr (prefix);
        !          1221: 
        !          1222:  retry:
        !          1223:   p = XSTRING (str)->data;
        !          1224:   p1 = (unsigned char *) index (p, '\n');
        !          1225: 
        !          1226:   for (p2 = p; *p2 && p2 != p1; p2++)
        !          1227:     if (p2[0] == '\\' && p2[1] == '[')
        !          1228:       {
        !          1229:        str = Fsubstitute_command_keys (str);
        !          1230:        goto retry;
        !          1231:       }
        !          1232: 
        !          1233:   InsCStr (p, p1 ? p1 - p : strlen (p));
        !          1234:   InsCStr ("\n", 1);
        !          1235: }
        !          1236: 
        !          1237: DEFUN ("apropos", Fapropos, Sapropos, 1, 3, "sApropos: ",
        !          1238:   "Show all symbols whose names contain match for REGEXP.\n\
        !          1239: If optional arg PRED is non-nil, (funcall PRED SYM) is done\n\
        !          1240: for each symbol and a symbol is mentioned if that returns non-nil.\n\
        !          1241: Returns list of symbols found; if third arg NOPRINT is non-nil,\n\
        !          1242: does not display them, just returns the list.")
        !          1243:   (string, pred, noprint)
        !          1244:      Lisp_Object string, pred, noprint;
        !          1245: {
        !          1246:   struct gcpro gcpro1, gcpro2;
        !          1247:   CHECK_STRING (string, 0);
        !          1248:   apropos_predicate = pred;
        !          1249:   GCPRO2 (apropos_predicate, apropos_accumulate);
        !          1250:   apropos_accumulate = Qnil;
        !          1251:   map_obarray (Vobarray, apropos_accum, string);
        !          1252:   apropos_accumulate = Fsort (apropos_accumulate, Qstring_lessp);
        !          1253:   if (NULL (noprint))
        !          1254:     internal_with_output_to_temp_buffer ("*Help*", apropos1,
        !          1255:                                         apropos_accumulate);
        !          1256:   UNGCPRO;
        !          1257:   return apropos_accumulate;
        !          1258: }
        !          1259: 
        !          1260: syms_of_keymap ()
        !          1261: {
        !          1262:   Lisp_Object tem;
        !          1263: 
        !          1264:   Qkeymap = intern ("keymap");
        !          1265:   staticpro (&Qkeymap);
        !          1266: 
        !          1267: /* Initialize the keymaps standardly used.
        !          1268:    Each one is the value of a Lisp variable, and is also
        !          1269:    pointed to by a C variable */
        !          1270: 
        !          1271: #ifdef HAVE_X_WINDOWS
        !          1272:   tem = Fmake_keymap ();
        !          1273:   MouseMap = tem;
        !          1274:   Fset (intern ("mouse-map"), tem);
        !          1275: #endif /* HAVE_X_WINDOWS */
        !          1276: 
        !          1277:   tem = Fmake_keymap ();
        !          1278:   GlobalMap = XVECTOR (tem);
        !          1279:   Fset (intern ("global-map"), tem);
        !          1280: 
        !          1281:   tem = Fmake_keymap ();
        !          1282:   ESCmap = XVECTOR (tem);
        !          1283:   Fset (intern ("esc-map"), tem);
        !          1284:   Ffset (intern ("ESC-prefix"), tem);
        !          1285: 
        !          1286:   tem = Fmake_keymap ();
        !          1287:   CtlXmap = XVECTOR (tem);
        !          1288:   Fset (intern ("ctl-x-map"), tem);
        !          1289:   Ffset (intern ("Control-X-prefix"), tem);
        !          1290: 
        !          1291:   DEFVAR_LISP ("minibuffer-local-map", &Vminibuffer_local_map,
        !          1292:     "Default keymap to use when reading from the minibuffer.");
        !          1293:   Vminibuffer_local_map = Fmake_sparse_keymap ();
        !          1294: 
        !          1295:   DEFVAR_LISP ("minibuffer-local-ns-map", &Vminibuffer_local_ns_map,
        !          1296:     "The keymap used by the minibuf for local bindings when spaces are not\n\
        !          1297: to be allowed in input string.");
        !          1298:   Vminibuffer_local_ns_map = Fmake_sparse_keymap ();
        !          1299: 
        !          1300:   DEFVAR_LISP ("minibuffer-local-completion-map", &Vminibuffer_local_completion_map,
        !          1301:     "Keymap to use when reading from the minibuffer with completion.");
        !          1302:   Vminibuffer_local_completion_map = Fmake_sparse_keymap ();
        !          1303: 
        !          1304:   DEFVAR_LISP ("minibuffer-local-must-match-map", &Vminibuffer_local_must_match_map,
        !          1305:     "Keymap to use when reading from the minibuffer with completion and\n\
        !          1306: an exact match of one of the completions is required.");
        !          1307:   Vminibuffer_local_must_match_map = Fmake_sparse_keymap ();
        !          1308: 
        !          1309:   CurrentGlobalMap = GlobalMap;
        !          1310: 
        !          1311:   Qsingle_key_description = intern ("single-key-description");
        !          1312:   staticpro (&Qsingle_key_description);
        !          1313: 
        !          1314:   Qkey_description = intern ("key-description");
        !          1315:   staticpro (&Qkey_description);
        !          1316: 
        !          1317:   Qkeymapp = intern ("keymapp");
        !          1318:   staticpro (&Qkeymapp);
        !          1319: 
        !          1320:   defsubr (&Skeymapp);
        !          1321:   defsubr (&Smake_keymap);
        !          1322:   defsubr (&Smake_sparse_keymap);
        !          1323:   defsubr (&Scopy_keymap);
        !          1324:   defsubr (&Skey_binding);
        !          1325:   defsubr (&Slocal_key_binding);
        !          1326:   defsubr (&Sglobal_key_binding);
        !          1327:   defsubr (&Sglobal_set_key);
        !          1328:   defsubr (&Slocal_set_key);
        !          1329:   defsubr (&Sdefine_key);
        !          1330:   defsubr (&Slookup_key);
        !          1331:   defsubr (&Sglobal_unset_key);
        !          1332:   defsubr (&Slocal_unset_key);
        !          1333:   defsubr (&Sdefine_prefix_command);
        !          1334:   defsubr (&Suse_global_map);
        !          1335:   defsubr (&Suse_local_map);
        !          1336:   defsubr (&Scurrent_local_map);
        !          1337:   defsubr (&Scurrent_global_map);
        !          1338:   defsubr (&Saccessible_keymaps);
        !          1339:   defsubr (&Skey_description);
        !          1340:   defsubr (&Ssingle_key_description);
        !          1341:   defsubr (&Stext_char_description);
        !          1342:   defsubr (&Swhere_is_internal);
        !          1343:   defsubr (&Swhere_is);
        !          1344:   defsubr (&Sdescribe_bindings);
        !          1345:   defsubr (&Sapropos);
        !          1346: }
        !          1347: 
        !          1348: keys_of_keymap ()
        !          1349: {
        !          1350:   defkey (GlobalMap, 033, "ESC-prefix");
        !          1351:   defkey (GlobalMap, Ctl('X'), "Control-X-prefix");
        !          1352: }

unix.superglobalmegacorp.com

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