summaryrefslogtreecommitdiff
path: root/src/keymap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/keymap.c')
-rw-r--r--src/keymap.c175
1 files changed, 149 insertions, 26 deletions
diff --git a/src/keymap.c b/src/keymap.c
index 271b0672b1e..07bf957cdca 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -66,6 +66,13 @@ Lisp_Object Vminibuffer_local_ns_map;
/* 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 @@ Return PARENT. PARENT should be nil or another keymap. */)
if (EQ (XCDR (prev), parent))
RETURN_UNGCPRO (parent);
+ CHECK_IMPURE (prev);
XSETCDR (prev, parent);
break;
}
@@ -886,6 +894,7 @@ store_in_keymap (keymap, idx, def)
{
if (NATNUMP (idx) && XFASTINT (idx) < ASIZE (elt))
{
+ CHECK_IMPURE (elt);
ASET (elt, XFASTINT (idx), def);
return def;
}
@@ -929,6 +938,7 @@ store_in_keymap (keymap, idx, def)
{
if (EQ (idx, XCAR (elt)))
{
+ CHECK_IMPURE (elt);
XSETCDR (elt, def);
return def;
}
@@ -972,6 +982,7 @@ store_in_keymap (keymap, idx, def)
}
else
elt = Fcons (idx, def);
+ CHECK_IMPURE (insertion_point);
XSETCDR (insertion_point, Fcons (elt, XCDR (insertion_point)));
}
}
@@ -1243,7 +1254,7 @@ A number as value means KEY is "too long";
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 @@ shadow_lookup (shadow, key, flag)
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 @@ describe_translation (definition, args)
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 @@ describe_map (map, prefix, elt_describer, partial, shadow,
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 @@ describe_map (map, prefix, elt_describer, partial, shadow,
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 @@ describe_map (map, prefix, elt_describer, partial, shadow,
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 @@ describe_map (map, prefix, elt_describer, partial, shadow,
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 @@ describe_map (map, prefix, elt_describer, partial, shadow,
}
}
+ /* 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 @@ 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",
+ &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 @@ the same way. The "active" keymaps in each alist are used before
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 @@ keymaps have no binding for the current key sequence but
`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'.