Doc fix.
[bpt/emacs.git] / src / keymap.c
index b2eb948..6f3cd35 100644 (file)
@@ -73,11 +73,11 @@ Lisp_Object Vminor_mode_map_alist;
    documentation.  */
 Lisp_Object Vfunction_key_map;
 
-Lisp_Object Qkeymapp, Qkeymap;
-
-/* A char over 0200 in a key sequence
-   is equivalent to prefixing with this character.  */
+Lisp_Object Qkeymapp, Qkeymap, Qnon_ascii;
 
+/* A char with the CHAR_META bit set in a vector or the 0200 bit set
+   in a string key sequence is equivalent to prefixing with this
+   character.  */
 extern Lisp_Object meta_prefix_char;
 
 void describe_map_tree ();
@@ -90,7 +90,7 @@ static void describe_map_2 ();
 
 DEFUN ("make-keymap", Fmake_keymap, Smake_keymap, 0, 1, 0,
   "Construct and return a new keymap, of the form (keymap VECTOR . ALIST).\n\
-VECTOR is a 128-element vector which holds the bindings for the ASCII\n\
+VECTOR is a vector which holds the bindings for the ASCII\n\
 characters.  ALIST is an assoc-list which holds bindings for function keys,\n\
 mouse events, and any other things that appear in the input stream.\n\
 All entries in it are initially nil, meaning \"command undefined\".\n\n\
@@ -170,10 +170,11 @@ synkey (frommap, fromchar, tomap, tochar)
 DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0,
   "Return t if ARG is a keymap.\n\
 \n\
-A keymap is a list (keymap . ALIST), a list (keymap VECTOR . ALIST),\n\
+A keymap is a list (keymap . ALIST),\n\
 or a symbol whose function definition is a keymap is itself a keymap.\n\
 ALIST elements look like (CHAR . DEFN) or (SYMBOL . DEFN);\n\
-VECTOR is a 128-element vector of bindings for ASCII characters.")
+a vector of densely packed bindings for small character codes\n\
+is also allowed as an element.")
   (object)
      Lisp_Object object;
 {
@@ -290,10 +291,9 @@ access_keymap (map, idx, t_ok)
            break;
 
          case Lisp_Vector:
-           if (XVECTOR (binding)->size == DENSE_TABLE_SIZE
-               && XTYPE (idx) == Lisp_Int
+           if (XTYPE (idx) == Lisp_Int
                && XINT (idx) >= 0
-               && XINT (idx) < DENSE_TABLE_SIZE)
+               && XINT (idx) < XVECTOR (binding)->size)
              return XVECTOR (binding)->contents[XINT (idx)];
            break;
          }
@@ -389,10 +389,8 @@ store_in_keymap (keymap, idx, def)
        switch (XTYPE (elt))
          {
          case Lisp_Vector:
-           if (XVECTOR (elt)->size != DENSE_TABLE_SIZE)
-             break;
            if (XTYPE (idx) == Lisp_Int
-               && XINT (idx) >= 0 && XINT (idx) < DENSE_TABLE_SIZE)
+               && XINT (idx) >= 0 && XINT (idx) < XVECTOR (elt)->size)
              {
                XVECTOR (elt)->contents[XFASTINT (idx)] = def;
                return def;
@@ -450,15 +448,14 @@ is not copied.")
     {
       Lisp_Object elt = XCONS (tail)->car;
 
-      if (XTYPE (elt) == Lisp_Vector
-         && XVECTOR (elt)->size == DENSE_TABLE_SIZE)
+      if (XTYPE (elt) == Lisp_Vector)
        {
          int i;
 
          elt = Fcopy_sequence (elt);
          XCONS (tail)->car = elt;
 
-         for (i = 0; i < DENSE_TABLE_SIZE; i++)
+         for (i = 0; i < XVECTOR (elt)->size; i++)
            if (XTYPE (XVECTOR (elt)->contents[i]) != Lisp_Symbol
                && Fkeymapp (XVECTOR (elt)->contents[i]))
              XVECTOR (elt)->contents[i] =
@@ -730,7 +727,7 @@ current_minor_maps (modeptr, mapptr)
              break;
          }
        cmm_modes[i] = var;
-       cmm_maps [i] = XCONS (assoc)->cdr;
+       cmm_maps [i] = Findirect_function (XCONS (assoc)->cdr);
        i++;
       }
 
@@ -913,7 +910,7 @@ KEY is a string representing a sequence of keystrokes.")
 }
 
 DEFUN ("define-prefix-command", Fdefine_prefix_command, Sdefine_prefix_command, 1, 2, 0,
-  "Define COMMAND as a prefix command.\n\
+  "Define COMMAND as a prefix command.  COMMAND should be a symbol.\n\
 A new sparse keymap is stored as COMMAND's function definition and its value.\n\
 If a second optional argument MAPVAR is given, the map is stored as\n\
 its value instead of as COMMAND's value; but COMMAND is still defined\n\
@@ -1024,7 +1021,7 @@ so that the KEYS increase in length.  The first element is (\"\" . KEYMAP).")
              register int i;
 
              /* Vector keymap.  Scan all the elements.  */
-             for (i = 0; i < DENSE_TABLE_SIZE; i++)
+             for (i = 0; i < XVECTOR (elt)->size; i++)
                {
                  register Lisp_Object tem;
                  register Lisp_Object cmd;
@@ -1311,6 +1308,28 @@ Control characters turn into \"^char\", etc.")
 
   return build_string (tem);
 }
+
+/* Return non-zero if SEQ contains only ASCII characters, perhaps with
+   a meta bit.  */
+static int
+ascii_sequence_p (seq)
+     Lisp_Object seq;
+{
+  Lisp_Object i;
+  int len = XINT (Flength (seq));
+  
+  for (XFASTINT (i) = 0; XFASTINT (i) < len; XFASTINT (i)++)
+    {
+      Lisp_Object elt = Faref (seq, i);
+
+      if (XTYPE (elt) != Lisp_Int
+         || (XUINT (elt) & ~CHAR_META) >= 0x80)
+       return 0;
+    }
+
+  return 1;
+}
+
 \f
 /* where-is - finding a command in a set of keymaps.                   */
 
@@ -1319,9 +1338,12 @@ DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 5, 0,
 If KEYMAP is nil, search only KEYMAP1.\n\
 If KEYMAP1 is nil, use the current global map.\n\
 \n\
-If optional 4th arg FIRSTONLY is non-nil,\n\
-return a string representing the first key sequence found,\n\
-rather than a list of all possible key sequences.\n\
+If optional 4th arg FIRSTONLY is non-nil, return a string representing\n\
+the first key sequence found, rather than a list of all possible key\n\
+sequences.  If FIRSTONLY is t, avoid key sequences which use non-ASCII\n\
+keys and therefore may not be usable on ASCII terminals.  If FIRSTONLY\n\
+is the symbol `non-ascii', return the first binding found, no matter\n\
+what its components.\n\
 \n\
 If optional 5th arg NOINDIRECT is non-nil, don't follow indirections\n\
 to other keymaps or slots.  This makes it possible to search for an\n\
@@ -1392,7 +1414,7 @@ indirect definition itself.")
              /* If we've just finished scanning a vector, advance map
                 to the next element, and reset i in anticipation of the
                 next vector we may find.  */
-             if (i >= DENSE_TABLE_SIZE)
+             if (i >= XVECTOR (elt)->size)
                {
                  map = XCONS (map)->cdr;
                  i = 0;
@@ -1469,13 +1491,28 @@ indirect definition itself.")
            }
 
          /* It is a true unshadowed match.  Record it.  */
+         found = Fcons (sequence, found);
 
-         if (!NILP (firstonly))
+         /* If firstonly is Qnon_ascii, then we can return the first
+            binding we find.  If firstonly is not Qnon_ascii but not
+            nil, then we should return the first ascii-only binding
+            we find.  */
+         if (EQ (firstonly, Qnon_ascii))
+           return sequence;
+         else if (! NILP (firstonly) && ascii_sequence_p (sequence))
            return sequence;
-         found = Fcons (sequence, found);
        }
     }
-  return Fnreverse (found);
+
+  found = Fnreverse (found);
+
+  /* firstonly may have been t, but we may have gone all the way through
+     the keymaps without finding an all-ASCII key sequence.  So just
+     return the best we could find.  */
+  if (! NILP (firstonly))
+    return Fcar (found);
+    
+  return found;
 }
 
 /* Return a string listing the keys and buttons that run DEFINITION.  */
@@ -1856,7 +1893,7 @@ describe_vector (vector, elt_prefix, elt_describer, partial, shadow)
   if (partial)
     suppress = intern ("suppress-keymap");
 
-  for (i = 0; i < DENSE_TABLE_SIZE; i++)
+  for (i = 0; i < XVECTOR (vector)->size; i++)
     {
       QUIT;
       tem1 = get_keyelt (XVECTOR (vector)->contents[i]);
@@ -1901,7 +1938,7 @@ describe_vector (vector, elt_prefix, elt_describer, partial, shadow)
       insert1 (this);
 
       /* Find all consecutive characters that have the same definition.  */
-      while (i + 1 < DENSE_TABLE_SIZE
+      while (i + 1 < XVECTOR (vector)->size
             && (tem2 = get_keyelt (XVECTOR (vector)->contents[i+1]),
                 EQ (tem2, tem1)))
        i++;
@@ -2039,6 +2076,9 @@ key, typing `ESC O P x' would return [pf1 x].");
   Qkeymapp = intern ("keymapp");
   staticpro (&Qkeymapp);
 
+  Qnon_ascii = intern ("non-ascii");
+  staticpro (&Qnon_ascii);
+
   defsubr (&Skeymapp);
   defsubr (&Smake_keymap);
   defsubr (&Smake_sparse_keymap);