Annotation of GNUtools/emacs/src/keymap.c, revision 1.1

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

unix.superglobalmegacorp.com

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