aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2007-07-16 19:26:14 +0000
committerStefan Monnier2007-07-16 19:26:14 +0000
commit4bb99e3a15f1e7e13103df4908814294dc974463 (patch)
tree9c88a8202037a3e1b95791af84c6b44ac793a645 /src
parent8c406a9bc42ee77fcbbb4201fe8bda855eafd832 (diff)
downloademacs-4bb99e3a15f1e7e13103df4908814294dc974463.tar.gz
emacs-4bb99e3a15f1e7e13103df4908814294dc974463.zip
Fix up failed merge from the trunk:
(Faccessible_keymaps, where_is_internal): Use map_keymap. (where_is_internal_2): Remove. (where_is_internal_1): Update interface for its new use.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog.unicode2
-rw-r--r--src/keymap.c338
2 files changed, 98 insertions, 242 deletions
diff --git a/src/ChangeLog.unicode b/src/ChangeLog.unicode
index 3a739bf7724..58585123587 100644
--- a/src/ChangeLog.unicode
+++ b/src/ChangeLog.unicode
@@ -42,7 +42,7 @@
42 42
43 * chartab.c (map_sub_char_table): Make it work for the top-level 43 * chartab.c (map_sub_char_table): Make it work for the top-level
44 char-table. Fix handling of parent char-table. 44 char-table. Fix handling of parent char-table.
45 (map_char_table): Adjusted for the above change. 45 (map_char_table): Adjust for the above change.
46 46
472007-06-24 Jason Rumney <jasonr@gnu.org> 472007-06-24 Jason Rumney <jasonr@gnu.org>
48 48
diff --git a/src/keymap.c b/src/keymap.c
index 413de76f7d5..195225045e1 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -2219,54 +2219,26 @@ then the value includes only maps for prefixes that start with PREFIX. */)
2219 2219
2220 for (tail = maps; CONSP (tail); tail = XCDR (tail)) 2220 for (tail = maps; CONSP (tail); tail = XCDR (tail))
2221 { 2221 {
2222 register Lisp_Object thisseq, thismap; 2222 struct accessible_keymaps_data data;
2223 register Lisp_Object thismap = Fcdr (XCAR (tail));
2223 Lisp_Object last; 2224 Lisp_Object last;
2224 /* Does the current sequence end in the meta-prefix-char? */
2225 int is_metized;
2226 2225
2227 thisseq = Fcar (Fcar (tail)); 2226 data.thisseq = Fcar (XCAR (tail));
2228 thismap = Fcdr (Fcar (tail)); 2227 data.maps = maps;
2229 last = make_number (XINT (Flength (thisseq)) - 1); 2228 data.tail = tail;
2230 is_metized = (XINT (last) >= 0 2229 last = make_number (XINT (Flength (data.thisseq)) - 1);
2230 /* Does the current sequence end in the meta-prefix-char? */
2231 data.is_metized = (XINT (last) >= 0
2231 /* Don't metize the last char of PREFIX. */ 2232 /* Don't metize the last char of PREFIX. */
2232 && XINT (last) >= prefixlen 2233 && XINT (last) >= prefixlen
2233 && EQ (Faref (thisseq, last), meta_prefix_char)); 2234 && EQ (Faref (data.thisseq, last), meta_prefix_char));
2234
2235 for (; CONSP (thismap); thismap = XCDR (thismap))
2236 {
2237 Lisp_Object elt;
2238
2239 elt = XCAR (thismap);
2240
2241 QUIT;
2242
2243 if (CHAR_TABLE_P (elt))
2244 {
2245 map_char_table (accessible_keymaps_char_table, Qnil,
2246 elt, Fcons (Fcons (maps, make_number (is_metized)),
2247 Fcons (tail, thisseq)));
2248 }
2249 else if (VECTORP (elt))
2250 {
2251 register int i;
2252
2253 /* Vector keymap. Scan all the elements. */
2254 for (i = 0; i < ASIZE (elt); i++)
2255 accessible_keymaps_1 (make_number (i), AREF (elt, i),
2256 maps, tail, thisseq, is_metized);
2257 2235
2258 } 2236 /* Since we can't run lisp code, we can't scan autoloaded maps. */
2259 else if (CONSP (elt)) 2237 if (CONSP (thismap))
2260 accessible_keymaps_1 (XCAR (elt), XCDR (elt), 2238 map_keymap (thismap, accessible_keymaps_1, Qnil, &data, 0);
2261 maps, tail, thisseq,
2262 is_metized && INTEGERP (XCAR (elt)));
2263
2264 }
2265 } 2239 }
2266
2267 return maps; 2240 return maps;
2268} 2241}
2269
2270Lisp_Object Qsingle_key_description, Qkey_description; 2242Lisp_Object Qsingle_key_description, Qkey_description;
2271 2243
2272/* This function cannot GC. */ 2244/* This function cannot GC. */
@@ -2717,146 +2689,94 @@ where_is_internal (definition, keymaps, firstonly, noindirect, no_remap)
2717 2689
2718 QUIT; 2690 QUIT;
2719 2691
2720 while (CONSP (map)) 2692 data.definition = definition;
2721 { 2693 data.noindirect = noindirect;
2722 /* Because the code we want to run on each binding is rather 2694 data.this = this;
2723 large, we don't want to have two separate loop bodies for 2695 data.last = last;
2724 sparse keymap bindings and tables; we want to iterate one 2696 data.last_is_meta = last_is_meta;
2725 loop body over both keymap and vector bindings. 2697 data.sequences = Qnil;
2726
2727 For this reason, if Fcar (map) is a vector, we don't
2728 advance map to the next element until i indicates that we
2729 have finished off the vector. */
2730 Lisp_Object elt, key, binding;
2731 elt = XCAR (map);
2732 map = XCDR (map);
2733 2698
2734 sequences = Qnil; 2699 if (CONSP (map))
2700 map_keymap (map, where_is_internal_1, Qnil, &data, 0);
2735 2701
2736 QUIT; 2702 sequences = data.sequences;
2737 2703
2738 /* Set key and binding to the current key and binding, and 2704 while (CONSP (sequences))
2739 advance map and i to the next binding. */ 2705 {
2740 if (VECTORP (elt)) 2706 Lisp_Object sequence, remapped, function;
2707
2708 sequence = XCAR (sequences);
2709 sequences = XCDR (sequences);
2710
2711 /* If the current sequence is a command remapping with
2712 format [remap COMMAND], find the key sequences
2713 which run COMMAND, and use those sequences instead. */
2714 remapped = Qnil;
2715 if (NILP (no_remap)
2716 && VECTORP (sequence) && XVECTOR (sequence)->size == 2
2717 && EQ (AREF (sequence, 0), Qremap)
2718 && (function = AREF (sequence, 1), SYMBOLP (function)))
2741 { 2719 {
2742 Lisp_Object sequence; 2720 Lisp_Object remapped1;
2743 int i; 2721
2744 /* In a vector, look at each element. */ 2722 remapped1 = where_is_internal (function, keymaps, firstonly, noindirect, Qt);
2745 for (i = 0; i < XVECTOR (elt)->size; i++) 2723 if (CONSP (remapped1))
2746 { 2724 {
2747 binding = AREF (elt, i); 2725 /* Verify that this key binding actually maps to the
2748 XSETFASTINT (key, i); 2726 remapped command (see below). */
2749 sequence = where_is_internal_1 (binding, key, definition, 2727 if (!EQ (shadow_lookup (keymaps, XCAR (remapped1), Qnil), function))
2750 noindirect, this, 2728 continue;
2751 last, nomenus, last_is_meta); 2729 sequence = XCAR (remapped1);
2752 if (!NILP (sequence)) 2730 remapped = XCDR (remapped1);
2753 sequences = Fcons (sequence, sequences); 2731 goto record_sequence;
2754 } 2732 }
2755 } 2733 }
2756 else if (CHAR_TABLE_P (elt))
2757 {
2758 Lisp_Object args;
2759
2760 args = Fcons (Fcons (Fcons (definition, noindirect),
2761 Qnil), /* Result accumulator. */
2762 Fcons (Fcons (this, last),
2763 Fcons (make_number (nomenus),
2764 make_number (last_is_meta))));
2765 map_char_table (where_is_internal_2, Qnil, elt, args);
2766 sequences = XCDR (XCAR (args));
2767 }
2768 else if (CONSP (elt))
2769 {
2770 Lisp_Object sequence;
2771 2734
2772 key = XCAR (elt); 2735 /* Verify that this key binding is not shadowed by another
2773 binding = XCDR (elt); 2736 binding for the same key, before we say it exists.
2774 2737
2775 sequence = where_is_internal_1 (binding, key, definition, 2738 Mechanism: look for local definition of this key and if
2776 noindirect, this, 2739 it is defined and does not match what we found then
2777 last, nomenus, last_is_meta); 2740 ignore this key.
2778 if (!NILP (sequence))
2779 sequences = Fcons (sequence, sequences);
2780 }
2781 2741
2742 Either nil or number as value from Flookup_key
2743 means undefined. */
2744 if (!EQ (shadow_lookup (keymaps, sequence, Qnil), definition))
2745 continue;
2782 2746
2783 while (!NILP (sequences)) 2747 record_sequence:
2748 /* Don't annoy user with strings from a menu such as
2749 Select Paste. Change them all to "(any string)",
2750 so that there seems to be only one menu item
2751 to report. */
2752 if (! NILP (sequence))
2784 { 2753 {
2785 Lisp_Object sequence, remapped, function; 2754 Lisp_Object tem;
2786 2755 tem = Faref (sequence, make_number (XVECTOR (sequence)->size - 1));
2787 sequence = XCAR (sequences); 2756 if (STRINGP (tem))
2788 sequences = XCDR (sequences); 2757 Faset (sequence, make_number (XVECTOR (sequence)->size - 1),
2789 2758 build_string ("(any string)"));
2790 /* If the current sequence is a command remapping with 2759 }
2791 format [remap COMMAND], find the key sequences
2792 which run COMMAND, and use those sequences instead. */
2793 remapped = Qnil;
2794 if (NILP (no_remap)
2795 && VECTORP (sequence) && XVECTOR (sequence)->size == 2
2796 && EQ (AREF (sequence, 0), Qremap)
2797 && (function = AREF (sequence, 1), SYMBOLP (function)))
2798 {
2799 Lisp_Object remapped1;
2800
2801 remapped1 = where_is_internal (function, keymaps, firstonly, noindirect, Qt);
2802 if (CONSP (remapped1))
2803 {
2804 /* Verify that this key binding actually maps to the
2805 remapped command (see below). */
2806 if (!EQ (shadow_lookup (keymaps, XCAR (remapped1), Qnil), function))
2807 continue;
2808 sequence = XCAR (remapped1);
2809 remapped = XCDR (remapped1);
2810 goto record_sequence;
2811 }
2812 }
2813
2814 /* Verify that this key binding is not shadowed by another
2815 binding for the same key, before we say it exists.
2816
2817 Mechanism: look for local definition of this key and if
2818 it is defined and does not match what we found then
2819 ignore this key.
2820
2821 Either nil or number as value from Flookup_key
2822 means undefined. */
2823 if (!EQ (shadow_lookup (keymaps, sequence, Qnil), definition))
2824 continue;
2825
2826 record_sequence:
2827 /* Don't annoy user with strings from a menu such as
2828 Select Paste. Change them all to "(any string)",
2829 so that there seems to be only one menu item
2830 to report. */
2831 if (! NILP (sequence))
2832 {
2833 Lisp_Object tem;
2834 tem = Faref (sequence, make_number (XVECTOR (sequence)->size - 1));
2835 if (STRINGP (tem))
2836 Faset (sequence, make_number (XVECTOR (sequence)->size - 1),
2837 build_string ("(any string)"));
2838 }
2839 2760
2840 /* It is a true unshadowed match. Record it, unless it's already 2761 /* It is a true unshadowed match. Record it, unless it's already
2841 been seen (as could happen when inheriting keymaps). */ 2762 been seen (as could happen when inheriting keymaps). */
2842 if (NILP (Fmember (sequence, found))) 2763 if (NILP (Fmember (sequence, found)))
2843 found = Fcons (sequence, found); 2764 found = Fcons (sequence, found);
2844 2765
2845 /* If firstonly is Qnon_ascii, then we can return the first 2766 /* If firstonly is Qnon_ascii, then we can return the first
2846 binding we find. If firstonly is not Qnon_ascii but not 2767 binding we find. If firstonly is not Qnon_ascii but not
2847 nil, then we should return the first ascii-only binding 2768 nil, then we should return the first ascii-only binding
2848 we find. */ 2769 we find. */
2849 if (EQ (firstonly, Qnon_ascii)) 2770 if (EQ (firstonly, Qnon_ascii))
2850 RETURN_UNGCPRO (sequence); 2771 RETURN_UNGCPRO (sequence);
2851 else if (!NILP (firstonly) && ascii_sequence_p (sequence)) 2772 else if (!NILP (firstonly) && ascii_sequence_p (sequence))
2852 RETURN_UNGCPRO (sequence); 2773 RETURN_UNGCPRO (sequence);
2853 2774
2854 if (CONSP (remapped)) 2775 if (CONSP (remapped))
2855 { 2776 {
2856 sequence = XCAR (remapped); 2777 sequence = XCAR (remapped);
2857 remapped = XCDR (remapped); 2778 remapped = XCDR (remapped);
2858 goto record_sequence; 2779 goto record_sequence;
2859 }
2860 } 2780 }
2861 } 2781 }
2862 } 2782 }
@@ -2975,83 +2895,19 @@ remapped command in the returned list. */)
2975 return result; 2895 return result;
2976} 2896}
2977 2897
2978/* This is the function that Fwhere_is_internal calls using map_char_table.
2979 ARGS has the form
2980 (((DEFINITION . NOINDIRECT) . RESULT)
2981 .
2982 ((THIS . LAST) . (NOMENUS . LAST_IS_META)))
2983 Since map_char_table doesn't really use the return value from this function,
2984 we the result append to RESULT, the slot in ARGS.
2985
2986 KEY may be a cons (FROM . TO) where both FROM and TO are integers
2987 (i.e. character events).
2988
2989 This function can GC because it calls where_is_internal_1 which can
2990 GC. */
2991
2992static void
2993where_is_internal_2 (args, key, binding)
2994 Lisp_Object args, key, binding;
2995{
2996 Lisp_Object definition, noindirect, this, last;
2997 Lisp_Object result, sequence;
2998 int nomenus, last_is_meta;
2999 struct gcpro gcpro1, gcpro2, gcpro3;
3000
3001 GCPRO3 (args, key, binding);
3002 definition = XCAR (XCAR (XCAR (args)));
3003 noindirect = XCDR (XCAR (XCAR (args)));
3004 this = XCAR (XCAR (XCDR (args)));
3005 last = XCDR (XCAR (XCDR (args)));
3006 nomenus = XFASTINT (XCAR (XCDR (XCDR (args))));
3007 last_is_meta = XFASTINT (XCDR (XCDR (XCDR (args))));
3008
3009 result = Qnil;
3010 if (CONSP (key) && INTEGERP (XCAR (key)) && INTEGERP (XCDR (key)))
3011 {
3012 /* Try all ASCII characters. Try also non-ASCII characters but
3013 only the first and last one because trying all of them is
3014 extremely memory and time consuming.
3015
3016 Fixme: Perhaps it should be allowed to store a cons directly
3017 in RESULT. -- handa@m17n.org */
3018 int from = XINT (XCAR (key)), to = XINT (XCDR (key));
3019 Lisp_Object k;
3020
3021 for (; from <= to; to--)
3022 {
3023 k = make_number (to);
3024 sequence = where_is_internal_1 (binding, k, definition, noindirect,
3025 this, last, nomenus, last_is_meta);
3026 if (!NILP (sequence))
3027 result = Fcons (sequence, result);
3028 if (to > 129)
3029 to = 129;
3030 }
3031 }
3032 else
3033 {
3034 sequence = where_is_internal_1 (binding, key, definition, noindirect,
3035 this, last, nomenus, last_is_meta);
3036 if (!NILP (sequence))
3037 result = Fcons (sequence, Qnil);
3038 }
3039
3040 if (! NILP (result))
3041 nconc2 (XCAR (args), result);
3042
3043 UNGCPRO;
3044}
3045
3046
3047/* This function can GC because get_keyelt can. */ 2898/* This function can GC because get_keyelt can. */
3048 2899
3049static Lisp_Object 2900static void
3050where_is_internal_1 (binding, key, definition, noindirect, this, last, 2901where_is_internal_1 (key, binding, args, data)
3051 nomenus, last_is_meta) 2902 Lisp_Object key, binding, args;
3052 Lisp_Object binding, key, definition, noindirect, this, last; 2903 void *data;
3053 int nomenus, last_is_meta;
3054{ 2904{
2905 struct where_is_internal_data *d = data; /* Cast! */
2906 Lisp_Object definition = d->definition;
2907 Lisp_Object noindirect = d->noindirect;
2908 Lisp_Object this = d->this;
2909 Lisp_Object last = d->last;
2910 int last_is_meta = d->last_is_meta;
3055 Lisp_Object sequence; 2911 Lisp_Object sequence;
3056 2912
3057 /* Search through indirections unless that's not wanted. */ 2913 /* Search through indirections unless that's not wanted. */