diff options
Diffstat (limited to 'src/keymap.c')
-rw-r--r-- | src/keymap.c | 175 |
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'. |