diff src/keymap.c @ 90261:7beb78bc1f8e

Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-97 Merge from emacs--cvs-trunk--0 Patches applied: * emacs--cvs-trunk--0 (patch 616-696) - Add lisp/mh-e/.arch-inventory - Update from CVS - Merge from gnus--rel--5.10 - Update from CVS: lisp/smerge-mode.el: Add 'tools' to file keywords. - lisp/gnus/ChangeLog: Remove duplicate entry * gnus--rel--5.10 (patch 147-181) - Update from CVS - Merge from emacs--cvs-trunk--0 - Update from CVS: lisp/mml.el (mml-preview): Doc fix. - Update from CVS: texi/message.texi: Fix default values. - Update from CVS: texi/gnus.texi (RSS): Addition.
author Miles Bader <miles@gnu.org>
date Mon, 16 Jan 2006 08:37:27 +0000
parents fa0da9b57058 2e977adcc0e5
children 5b7d410e31f9
line wrap: on
line diff
--- a/src/keymap.c	Mon Jan 16 06:59:21 2006 +0000
+++ b/src/keymap.c	Mon Jan 16 08:37:27 2006 +0000
@@ -66,6 +66,13 @@
 /* was MinibufLocalCompletionMap */
 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 
+   with require-match*/
+Lisp_Object Vminibuffer_local_must_match_filename_map;
+
 /* keymap used for minibuffers when doing completion and require a match */
 /* was MinibufLocalMustMatchMap */
 Lisp_Object Vminibuffer_local_must_match_map;
@@ -390,6 +397,7 @@
 	  if (EQ (XCDR (prev), parent))
 	    RETURN_UNGCPRO (parent);
 
+	  CHECK_IMPURE (prev);
 	  XSETCDR (prev, parent);
 	  break;
 	}
@@ -886,6 +894,7 @@
 	  {
 	    if (NATNUMP (idx) && XFASTINT (idx) < ASIZE (elt))
 	      {
+		CHECK_IMPURE (elt);
 		ASET (elt, XFASTINT (idx), def);
 		return def;
 	      }
@@ -929,6 +938,7 @@
 	  {
 	    if (EQ (idx, XCAR (elt)))
 	      {
+		CHECK_IMPURE (elt);
 		XSETCDR (elt, def);
 		return def;
 	      }
@@ -972,6 +982,7 @@
 	}
       else
 	elt = Fcons (idx, def);
+      CHECK_IMPURE (insertion_point);
       XSETCDR (insertion_point, Fcons (elt, XCDR (insertion_point)));
     }
   }
@@ -1243,7 +1254,7 @@
 that is, characters or symbols in it except for the last one
 fail to be a valid sequence of prefix characters in KEYMAP.
 The number is how many characters at the front of KEY
-it takes to reach a non-prefix command.
+it takes to reach a non-prefix key.
 
 Normally, `lookup-key' ignores bindings for t, which act as default
 bindings, used when nothing else in the keymap applies; this makes it
@@ -2368,7 +2379,14 @@
   for (tail = shadow; CONSP (tail); tail = XCDR (tail))
     {
       value = Flookup_key (XCAR (tail), key, flag);
-      if (!NILP (value) && !NATNUMP (value))
+      if (NATNUMP (value))
+	{
+	  value = Flookup_key (XCAR (tail),
+			       Fsubstring (key, make_number (0), value), flag);
+	  if (!NILP (value))
+	    return Qnil;
+	}
+      else if (!NILP (value))
 	return value;
     }
   return Qnil;
@@ -3175,6 +3193,34 @@
     insert_string ("??\n");
 }
 
+/* describe_map puts all the usable elements of a sparse keymap
+   into an array of `struct describe_map_elt',
+   then sorts them by the events.  */
+
+struct describe_map_elt { Lisp_Object event; Lisp_Object definition; int shadowed; };
+
+/* qsort comparison function for sorting `struct describe_map_elt' by
+   the event field.  */
+
+static int
+describe_map_compare (aa, bb)
+     const void *aa, *bb;
+{
+  const struct describe_map_elt *a = aa, *b = bb;
+  if (INTEGERP (a->event) && INTEGERP (b->event))
+    return ((XINT (a->event) > XINT (b->event))
+	    - (XINT (a->event) < XINT (b->event)));
+  if (!INTEGERP (a->event) && INTEGERP (b->event))
+    return 1;
+  if (INTEGERP (a->event) && !INTEGERP (b->event))
+    return -1;
+  if (SYMBOLP (a->event) && SYMBOLP (b->event))
+    return (!NILP (Fstring_lessp (a->event, b->event)) ? -1
+	    : !NILP (Fstring_lessp (b->event, a->event)) ? 1
+	    : 0);
+  return 0;
+}
+
 /* Describe the contents of map MAP, assuming that this map itself is
    reached by the sequence of prefix keys PREFIX (a string or vector).
    PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above.  */
@@ -3198,6 +3244,13 @@
   int first = 1;
   struct gcpro gcpro1, gcpro2, gcpro3;
 
+  /* These accumulate the values from sparse keymap bindings,
+     so we can sort them and handle them in order.  */
+  int length_needed = 0;
+  struct describe_map_elt *vect;
+  int slots_used = 0;
+  int i;
+
   suppress = Qnil;
 
   if (partial)
@@ -3209,6 +3262,12 @@
   kludge = Fmake_vector (make_number (1), Qnil);
   definition = Qnil;
 
+  for (tail = map; CONSP (tail); tail = XCDR (tail))
+    length_needed++;
+
+  vect = ((struct describe_map_elt *)
+	  alloca (sizeof (struct describe_map_elt) * length_needed));
+
   GCPRO3 (prefix, definition, kludge);
 
   for (tail = map; CONSP (tail); tail = XCDR (tail))
@@ -3223,6 +3282,7 @@
       else if (CONSP (XCAR (tail)))
 	{
 	  int this_shadowed = 0;
+
 	  event = XCAR (XCAR (tail));
 
 	  /* Ignore bindings whose "prefix" are not really valid events.
@@ -3263,27 +3323,10 @@
 	  tem = Flookup_key (map, kludge, Qt);
 	  if (!EQ (tem, definition)) continue;
 
-	  if (first)
-	    {
-	      previous_description_column = 0;
-	      insert ("\n", 1);
-	      first = 0;
-	    }
-
-	  /* THIS gets the string to describe the character EVENT.  */
-	  insert1 (Fkey_description (kludge, prefix));
-
-	  /* Print a description of the definition of this character.
-	     elt_describer will take care of spacing out far enough
-	     for alignment purposes.  */
-	  (*elt_describer) (definition, Qnil);
-
-	  if (this_shadowed)
-	    {
-	      SET_PT (PT - 1);
-	      insert_string ("  (binding currently shadowed)");
-	      SET_PT (PT + 1);
-	    }
+	  vect[slots_used].event = event;
+	  vect[slots_used].definition = definition;
+	  vect[slots_used].shadowed = this_shadowed;
+	  slots_used++;
 	}
       else if (EQ (XCAR (tail), Qkeymap))
 	{
@@ -3297,6 +3340,68 @@
 	}
     }
 
+  /* If we found some sparse map events, sort them.  */
+
+  qsort (vect, slots_used, sizeof (struct describe_map_elt),
+	 describe_map_compare);
+
+  /* Now output them in sorted order.  */
+
+  for (i = 0; i < slots_used; i++)
+    {
+      Lisp_Object start, end;
+
+      if (first)
+	{
+	  previous_description_column = 0;
+	  insert ("\n", 1);
+	  first = 0;
+	}
+
+      ASET (kludge, 0, vect[i].event);
+      start = vect[i].event;
+      end = start;
+
+      definition = vect[i].definition;
+
+      /* Find consecutive chars that are identically defined.  */
+      if (INTEGERP (vect[i].event))
+	{
+	  while (i + 1 < slots_used
+		 && XINT (vect[i + 1].event) == XINT (vect[i].event) + 1
+		 && !NILP (Fequal (vect[i + 1].definition, definition))
+		 && vect[i].shadowed == vect[i + 1].shadowed)
+	    i++;
+	  end = vect[i].event;
+	}
+
+      /* Now START .. END is the range to describe next.  */
+
+      /* Insert the string to describe the event START.  */
+      insert1 (Fkey_description (kludge, prefix));
+
+      if (!EQ (start, end))
+	{
+	  insert (" .. ", 4);
+
+	  ASET (kludge, 0, end);
+	  /* Insert the string to describe the character END.  */
+	  insert1 (Fkey_description (kludge, prefix));
+	}
+
+      /* Print a description of the definition of this character.
+	 elt_describer will take care of spacing out far enough
+	 for alignment purposes.  */
+      (*elt_describer) (vect[i].definition, Qnil);
+
+      if (vect[i].shadowed)
+	{
+	  SET_PT (PT - 1);
+	  insert_string ("  (binding currently shadowed)");
+	  SET_PT (PT + 1);
+	}
+    }
+
   UNGCPRO;
 }
 
@@ -3646,12 +3751,27 @@
   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", 
+	       &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, 
+		      Vminibuffer_local_completion_map);
+
+
   DEFVAR_LISP ("minibuffer-local-must-match-map", &Vminibuffer_local_must_match_map,
 	       doc: /* Local keymap for minibuffer input with completion, for exact match.  */);
   Vminibuffer_local_must_match_map = Fmake_sparse_keymap (Qnil);
   Fset_keymap_parent (Vminibuffer_local_must_match_map,
 		      Vminibuffer_local_completion_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, 
+		      Vminibuffer_local_must_match_map);
+
   DEFVAR_LISP ("minor-mode-map-alist", &Vminor_mode_map_alist,
 	       doc: /* Alist of keymaps to use for minor modes.
 Each element looks like (VARIABLE . KEYMAP); KEYMAP is used to read
@@ -3678,9 +3798,9 @@
 
 
   DEFVAR_LISP ("function-key-map", &Vfunction_key_map,
-	       doc: /* Keymap mapping ASCII function key sequences onto their preferred forms.
-This allows Emacs to recognize function keys sent from ASCII
-terminals at any point in a key sequence.
+	       doc: /* Keymap that translates key sequences to key sequences during input.
+This is used mainly for mapping ASCII function key sequences into
+real Emacs function key events (symbols).
 
 The `read-key-sequence' function replaces any subsequence bound by
 `function-key-map' with its binding.  More precisely, when the active
@@ -3689,6 +3809,9 @@
 `read-key-sequence' replaces the matching suffix with its binding, and
 continues with the new sequence.
 
+If the binding is a function, it is called with one argument (the prompt)
+and its return value (a key sequence) is used.
+
 The events that come from bindings in `function-key-map' are not
 themselves looked up in `function-key-map'.