* keymap.c (describe_map): Avoid generating duplicate entries if
[bpt/emacs.git] / src / keymap.c
index f12a66c..ecc2f7b 100644 (file)
@@ -1,7 +1,7 @@
 /* Manipulation of keymaps
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                  1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                 2005 Free Software Foundation, Inc.
+                 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -68,7 +68,7 @@ Lisp_Object Vminibuffer_local_completion_map;
 /* keymap used for minibuffers when doing completion in filenames */
 Lisp_Object Vminibuffer_local_filename_completion_map;
 
-/* keymap used for minibuffers when doing completion in filenames 
+/* keymap used for minibuffers when doing completion in filenames
    with require-match*/
 Lisp_Object Vminibuffer_local_must_match_filename_map;
 
@@ -699,6 +699,7 @@ map_keymap (map, fun, args, data, autoload)
   struct gcpro gcpro1, gcpro2, gcpro3;
   Lisp_Object tail;
 
+  tail = Qnil;
   GCPRO3 (map, args, tail);
   map = get_keymap (map, 1, autoload);
   for (tail = (CONSP (map) && EQ (Qkeymap, XCAR (map))) ? XCDR (map) : map;
@@ -743,8 +744,10 @@ map_keymap_call (key, val, fun, dummy)
 }
 
 DEFUN ("map-keymap", Fmap_keymap, Smap_keymap, 2, 3, 0,
-       doc: /* Call FUNCTION for every binding in KEYMAP.
-FUNCTION is called with two arguments: the event and its binding.
+       doc: /* Call FUNCTION once for each event binding in KEYMAP.
+FUNCTION is called with two arguments: the event that is bound, and
+the definition it is bound to.
+
 If KEYMAP has a parent, the parent's bindings are included as well.
 This works recursively: if the parent has itself a parent, then the
 grandparent's bindings are also included and so on.
@@ -863,7 +866,7 @@ static Lisp_Object
 store_in_keymap (keymap, idx, def)
      Lisp_Object keymap;
      register Lisp_Object idx;
-     register Lisp_Object def;
+     Lisp_Object def;
 {
   /* Flush any reverse-map cache.  */
   where_is_cache = Qnil;
@@ -1190,8 +1193,11 @@ binding KEY to DEF is added at the front of KEYMAP.  */)
       if (!CONSP (keymap))
        /* We must use Fkey_description rather than just passing key to
           error; key might be a vector, not a string.  */
-       error ("Key sequence %s uses invalid prefix characters",
-              SDATA (Fkey_description (key, Qnil)));
+       error ("Key sequence %s starts with non-prefix key %s",
+              SDATA (Fkey_description (key, Qnil)),
+              SDATA (Fkey_description (Fsubstring (key, make_number (0),
+                                                   make_number (idx)),
+                                       Qnil)));
     }
 }
 
@@ -1368,13 +1374,6 @@ silly_event_symbol_error (c)
 static Lisp_Object *cmm_modes = NULL, *cmm_maps = NULL;
 static int cmm_size = 0;
 
-/* Error handler used in current_minor_maps.  */
-static Lisp_Object
-current_minor_maps_error ()
-{
-  return Qnil;
-}
-
 /* Store a pointer to an array of the keymaps of the currently active
    minor modes in *buf, and return the number of maps it contains.
 
@@ -1476,9 +1475,7 @@ current_minor_maps (modeptr, mapptr)
              }
 
            /* Get the keymap definition--or nil if it is not defined.  */
-           temp = internal_condition_case_1 (Findirect_function,
-                                             XCDR (assoc),
-                                             Qerror, current_minor_maps_error);
+           temp = Findirect_function (XCDR (assoc), Qt);
            if (!NILP (temp))
              {
                cmm_modes[i] = var;
@@ -2093,12 +2090,21 @@ push_key_description (c, p, force_multibyte)
      int force_multibyte;
 {
   unsigned c2;
+  int valid_p;
 
   /* Clear all the meaningless bits above the meta bit.  */
   c &= meta_modifier | ~ - meta_modifier;
   c2 = c & ~(alt_modifier | ctrl_modifier | hyper_modifier
             | meta_modifier | shift_modifier | super_modifier);
 
+  valid_p = SINGLE_BYTE_CHAR_P (c2) || char_valid_p (c2, 0);
+  if (! valid_p)
+    {
+      /* KEY_DESCRIPTION_SIZE is large enough for this.  */
+      p += sprintf (p, "[%d]", c);
+      return p;
+    }
+
   if (c & alt_modifier)
     {
       *p++ = 'A';
@@ -2186,16 +2192,13 @@ push_key_description (c, p, force_multibyte)
     }
   else
     {
-      int valid_p = SINGLE_BYTE_CHAR_P (c) || char_valid_p (c, 0);
-
-      if (force_multibyte && valid_p)
+      if (force_multibyte)
        {
          if (SINGLE_BYTE_CHAR_P (c))
            c = unibyte_char_to_multibyte (c);
          p += CHAR_STRING (c, p);
        }
-      else if (NILP (current_buffer->enable_multibyte_characters)
-              || valid_p)
+      else if (NILP (current_buffer->enable_multibyte_characters))
        {
          int bit_offset;
          *p++ = '\\';
@@ -3196,8 +3199,8 @@ describe_map_compare (aa, bb)
   if (INTEGERP (a->event) && !INTEGERP (b->event))
     return -1;
   if (SYMBOLP (a->event) && SYMBOLP (b->event))
-    return (Fstring_lessp (a->event, b->event) ? -1
-           : Fstring_lessp (b->event, a->event) ? 1
+    return (!NILP (Fstring_lessp (a->event, b->event)) ? -1
+           : !NILP (Fstring_lessp (b->event, a->event)) ? 1
            : 0);
   return 0;
 }
@@ -3294,7 +3297,9 @@ describe_map (map, prefix, elt_describer, partial, shadow,
              tem = shadow_lookup (shadow, kludge, Qt);
              if (!NILP (tem))
                {
-                 if (mention_shadow)
+                 /* Avoid generating duplicate entries if the
+                    shadowed binding has the same definition. */
+                 if (mention_shadow && !EQ (tem, definition))
                    this_shadowed = 1;
                  else
                    continue;
@@ -3349,7 +3354,7 @@ describe_map (map, prefix, elt_describer, partial, shadow,
       if (INTEGERP (vect[i].event))
        {
          while (i + 1 < slots_used
-                && XINT (vect[i + 1].event) == XINT (vect[i].event) + 1
+                && EQ (vect[i+1].event, make_number (XINT (vect[i].event) + 1))
                 && !NILP (Fequal (vect[i + 1].definition, definition))
                 && vect[i].shadowed == vect[i + 1].shadowed)
            i++;
@@ -3378,7 +3383,7 @@ describe_map (map, prefix, elt_describer, partial, shadow,
       if (vect[i].shadowed)
        {
          SET_PT (PT - 1);
-         insert_string ("  (binding currently shadowed)");
+         insert_string ("\n  (that binding is currently shadowed by another mode)");
          SET_PT (PT + 1);
        }
     }
@@ -3880,11 +3885,11 @@ don't alter it yourself.  */);
   Vminibuffer_local_completion_map = Fmake_sparse_keymap (Qnil);
   Fset_keymap_parent (Vminibuffer_local_completion_map, Vminibuffer_local_map);
 
-  DEFVAR_LISP ("minibuffer-local-filename-completion-map", 
+  DEFVAR_LISP ("minibuffer-local-filename-completion-map",
               &Vminibuffer_local_filename_completion_map,
               doc: /* Local keymap for minibuffer input with completion for filenames.  */);
   Vminibuffer_local_filename_completion_map = Fmake_sparse_keymap (Qnil);
-  Fset_keymap_parent (Vminibuffer_local_filename_completion_map, 
+  Fset_keymap_parent (Vminibuffer_local_filename_completion_map,
                      Vminibuffer_local_completion_map);
 
 
@@ -3894,11 +3899,11 @@ don't alter it yourself.  */);
   Fset_keymap_parent (Vminibuffer_local_must_match_map,
                      Vminibuffer_local_completion_map);
 
-  DEFVAR_LISP ("minibuffer-local-must-match-filename-map", 
+  DEFVAR_LISP ("minibuffer-local-must-match-filename-map",
               &Vminibuffer_local_must_match_filename_map,
               doc: /* Local keymap for minibuffer input with completion for filenames with exact match.  */);
   Vminibuffer_local_must_match_filename_map = Fmake_sparse_keymap (Qnil);
-  Fset_keymap_parent (Vminibuffer_local_must_match_filename_map, 
+  Fset_keymap_parent (Vminibuffer_local_must_match_filename_map,
                      Vminibuffer_local_must_match_map);
 
   DEFVAR_LISP ("minor-mode-map-alist", &Vminor_mode_map_alist,