diff options
| author | Stefan Monnier | 2007-07-16 19:26:14 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2007-07-16 19:26:14 +0000 |
| commit | 4bb99e3a15f1e7e13103df4908814294dc974463 (patch) | |
| tree | 9c88a8202037a3e1b95791af84c6b44ac793a645 /src | |
| parent | 8c406a9bc42ee77fcbbb4201fe8bda855eafd832 (diff) | |
| download | emacs-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.unicode | 2 | ||||
| -rw-r--r-- | src/keymap.c | 338 |
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 | ||
| 47 | 2007-06-24 Jason Rumney <jasonr@gnu.org> | 47 | 2007-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 | |||
| 2270 | Lisp_Object Qsingle_key_description, Qkey_description; | 2242 | Lisp_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 | |||
| 2992 | static void | ||
| 2993 | where_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 | ||
| 3049 | static Lisp_Object | 2900 | static void |
| 3050 | where_is_internal_1 (binding, key, definition, noindirect, this, last, | 2901 | where_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. */ |