Mercurial > emacs
comparison src/keymap.c @ 88380:88a2dd2ddb6e
Include "character.h".
(store_in_keymap): Handle the case that IDX is a cons.
(Fdefine_key): Handle the case that KEY is a cons and the car part
is also a cons (range).
(push_key_description): Adjusted for the new character code.
(describe_vector): Call describe_char_table for a char table.
(describe_char_table): New function.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Fri, 01 Mar 2002 01:43:26 +0000 |
parents | 20832766c3e1 |
children | f35665df510f |
comparison
equal
deleted
inserted
replaced
88379:bedac2738d2c | 88380:88a2dd2ddb6e |
---|---|
23 #include <config.h> | 23 #include <config.h> |
24 #include <stdio.h> | 24 #include <stdio.h> |
25 #include "lisp.h" | 25 #include "lisp.h" |
26 #include "commands.h" | 26 #include "commands.h" |
27 #include "buffer.h" | 27 #include "buffer.h" |
28 #include "character.h" | |
28 #include "charset.h" | 29 #include "charset.h" |
29 #include "keyboard.h" | 30 #include "keyboard.h" |
30 #include "termhooks.h" | 31 #include "termhooks.h" |
31 #include "blockinput.h" | 32 #include "blockinput.h" |
32 #include "puresize.h" | 33 #include "puresize.h" |
788 Faset (elt, idx, | 789 Faset (elt, idx, |
789 /* `nil' has a special meaning for char-tables, so | 790 /* `nil' has a special meaning for char-tables, so |
790 we use something else to record an explicitly | 791 we use something else to record an explicitly |
791 unbound entry. */ | 792 unbound entry. */ |
792 NILP (def) ? Qt : def); | 793 NILP (def) ? Qt : def); |
794 return def; | |
795 } | |
796 else if (CONSP (idx) && CHARACTERP (XCAR (idx))) | |
797 { | |
798 Fset_char_table_range (elt, idx, NILP (def) ? Qt : def); | |
793 return def; | 799 return def; |
794 } | 800 } |
795 insertion_point = tail; | 801 insertion_point = tail; |
796 } | 802 } |
797 else if (CONSP (elt)) | 803 else if (CONSP (elt)) |
1017 idx = 0; | 1023 idx = 0; |
1018 while (1) | 1024 while (1) |
1019 { | 1025 { |
1020 c = Faref (key, make_number (idx)); | 1026 c = Faref (key, make_number (idx)); |
1021 | 1027 |
1022 if (CONSP (c) && lucid_event_type_list_p (c)) | 1028 if (CONSP (c)) |
1023 c = Fevent_convert_list (c); | 1029 { |
1030 /* C may be a cons (FROM . TO) specifying a range of | |
1031 characters. */ | |
1032 if (CHARACTERP (XCAR (c))) | |
1033 CHECK_CHARACTER (XCDR (c)); | |
1034 else if (lucid_event_type_list_p (c)) | |
1035 c = Fevent_convert_list (c); | |
1036 } | |
1024 | 1037 |
1025 if (SYMBOLP (c)) | 1038 if (SYMBOLP (c)) |
1026 silly_event_symbol_error (c); | 1039 silly_event_symbol_error (c); |
1027 | 1040 |
1028 if (INTEGERP (c) | 1041 if (INTEGERP (c) |
1039 | 1052 |
1040 metized = 0; | 1053 metized = 0; |
1041 idx++; | 1054 idx++; |
1042 } | 1055 } |
1043 | 1056 |
1044 if (!INTEGERP (c) && !SYMBOLP (c) && !CONSP (c)) | 1057 if (!INTEGERP (c) && !SYMBOLP (c) |
1058 && (!CONSP (c) | |
1059 /* If C is a range, it must be a leaf. */ | |
1060 || (INTEGERP (XCAR (c)) && idx != length))) | |
1045 error ("Key sequence contains invalid event"); | 1061 error ("Key sequence contains invalid event"); |
1046 | 1062 |
1047 if (idx == length) | 1063 if (idx == length) |
1048 RETURN_UNGCPRO (store_in_keymap (keymap, c, def)); | 1064 RETURN_UNGCPRO (store_in_keymap (keymap, c, def)); |
1049 | 1065 |
2026 && SINGLE_BYTE_CHAR_P (c) | 2042 && SINGLE_BYTE_CHAR_P (c) |
2027 && !force_multibyte)) | 2043 && !force_multibyte)) |
2028 { | 2044 { |
2029 *p++ = c; | 2045 *p++ = c; |
2030 } | 2046 } |
2047 else if (CHAR_VALID_P (c, 0)) | |
2048 { | |
2049 if (NILP (current_buffer->enable_multibyte_characters)) | |
2050 *p++ = multibyte_char_to_unibyte (c, Qnil); | |
2051 else | |
2052 p += CHAR_STRING (c, (unsigned char *) p); | |
2053 } | |
2031 else | 2054 else |
2032 { | 2055 { |
2033 int valid_p = SINGLE_BYTE_CHAR_P (c) || char_valid_p (c, 0); | 2056 int bit_offset; |
2034 | 2057 *p++ = '\\'; |
2035 if (force_multibyte && valid_p) | 2058 /* The biggest character code uses 22 bits. */ |
2036 { | 2059 for (bit_offset = 21; bit_offset >= 0; bit_offset -= 3) |
2037 if (SINGLE_BYTE_CHAR_P (c)) | 2060 { |
2038 c = unibyte_char_to_multibyte (c); | 2061 if (c >= (1 << bit_offset)) |
2039 p += CHAR_STRING (c, p); | 2062 *p++ = ((c & (7 << bit_offset)) >> bit_offset) + '0'; |
2040 } | 2063 } |
2041 else if (NILP (current_buffer->enable_multibyte_characters) | |
2042 || valid_p) | |
2043 { | |
2044 int bit_offset; | |
2045 *p++ = '\\'; | |
2046 /* The biggest character code uses 19 bits. */ | |
2047 for (bit_offset = 18; bit_offset >= 0; bit_offset -= 3) | |
2048 { | |
2049 if (c >= (1 << bit_offset)) | |
2050 *p++ = ((c & (7 << bit_offset)) >> bit_offset) + '0'; | |
2051 } | |
2052 } | |
2053 else | |
2054 p += CHAR_STRING (c, p); | |
2055 } | 2064 } |
2056 | 2065 |
2057 return p; | 2066 return p; |
2058 } | 2067 } |
2059 | 2068 |
2073 | 2082 |
2074 key = EVENT_HEAD (key); | 2083 key = EVENT_HEAD (key); |
2075 | 2084 |
2076 if (INTEGERP (key)) /* Normal character */ | 2085 if (INTEGERP (key)) /* Normal character */ |
2077 { | 2086 { |
2078 unsigned int charset, c1, c2; | 2087 char tem[KEY_DESCRIPTION_SIZE]; |
2079 int without_bits = XINT (key) & ~((-1) << CHARACTERBITS); | 2088 |
2080 | 2089 *push_key_description (XUINT (key), tem, 1) = 0; |
2081 if (SINGLE_BYTE_CHAR_P (without_bits)) | 2090 return build_string (tem); |
2082 charset = 0; | |
2083 else | |
2084 SPLIT_CHAR (without_bits, charset, c1, c2); | |
2085 | |
2086 if (charset | |
2087 && CHARSET_DEFINED_P (charset) | |
2088 && ((c1 >= 0 && c1 < 32) | |
2089 || (c2 >= 0 && c2 < 32))) | |
2090 { | |
2091 /* Handle a generic character. */ | |
2092 Lisp_Object name; | |
2093 name = CHARSET_TABLE_INFO (charset, CHARSET_LONG_NAME_IDX); | |
2094 CHECK_STRING (name); | |
2095 return concat2 (build_string ("Character set "), name); | |
2096 } | |
2097 else | |
2098 { | |
2099 char tem[KEY_DESCRIPTION_SIZE], *end; | |
2100 int nbytes, nchars; | |
2101 Lisp_Object string; | |
2102 | |
2103 end = push_key_description (XUINT (key), tem, 1); | |
2104 nbytes = end - tem; | |
2105 nchars = multibyte_chars_in_text (tem, nbytes); | |
2106 if (nchars == nbytes) | |
2107 { | |
2108 *end = '\0'; | |
2109 string = build_string (tem); | |
2110 } | |
2111 else | |
2112 string = make_multibyte_string (tem, nchars, nbytes); | |
2113 return string; | |
2114 } | |
2115 } | 2091 } |
2116 else if (SYMBOLP (key)) /* Function key or event-symbol */ | 2092 else if (SYMBOLP (key)) /* Function key or event-symbol */ |
2117 { | 2093 { |
2118 if (NILP (no_angles)) | 2094 if (NILP (no_angles)) |
2119 { | 2095 { |
3154 | 3130 |
3155 ENTIRE_MAP is the keymap in which this vector appears. | 3131 ENTIRE_MAP is the keymap in which this vector appears. |
3156 If the definition in effect in the whole map does not match | 3132 If the definition in effect in the whole map does not match |
3157 the one in this vector, we ignore this one. | 3133 the one in this vector, we ignore this one. |
3158 | 3134 |
3159 When describing a sub-char-table, INDICES is a list of | 3135 ARGS is simply passed as the second argument to ELT_DESCRIBER. |
3160 indices at higher levels in this char-table, | 3136 |
3161 and CHAR_TABLE_DEPTH says how many levels down we have gone. | 3137 INDICES and CHAR_TABLE_DEPTH are ignored. They will be removed in |
3162 | 3138 the near future. */ |
3163 ARGS is simply passed as the second argument to ELT_DESCRIBER. */ | |
3164 | 3139 |
3165 void | 3140 void |
3166 describe_vector (vector, elt_prefix, args, elt_describer, | 3141 describe_vector (vector, elt_prefix, args, elt_describer, |
3167 partial, shadow, entire_map, | 3142 partial, shadow, entire_map, |
3168 indices, char_table_depth) | 3143 indices, char_table_depth) |
3178 Lisp_Object definition; | 3153 Lisp_Object definition; |
3179 Lisp_Object tem2; | 3154 Lisp_Object tem2; |
3180 register int i; | 3155 register int i; |
3181 Lisp_Object suppress; | 3156 Lisp_Object suppress; |
3182 Lisp_Object kludge; | 3157 Lisp_Object kludge; |
3183 int first = 1; | |
3184 struct gcpro gcpro1, gcpro2, gcpro3; | 3158 struct gcpro gcpro1, gcpro2, gcpro3; |
3185 /* Range of elements to be handled. */ | 3159 /* Range of elements to be handled. */ |
3186 int from, to; | 3160 int from, to; |
3187 /* A flag to tell if a leaf in this level of char-table is not a | 3161 Lisp_Object character; |
3188 generic character (i.e. a complete multibyte character). */ | |
3189 int complete_char; | |
3190 int character; | |
3191 int starting_i; | 3162 int starting_i; |
3192 | 3163 |
3164 if (CHAR_TABLE_P (vector)) | |
3165 { | |
3166 describe_char_table (vector, elt_prefix, args, elt_describer, | |
3167 partial, shadow, entire_map); | |
3168 return; | |
3169 } | |
3170 | |
3193 suppress = Qnil; | 3171 suppress = Qnil; |
3194 | |
3195 if (indices == 0) | |
3196 indices = (int *) alloca (3 * sizeof (int)); | |
3197 | 3172 |
3198 definition = Qnil; | 3173 definition = Qnil; |
3199 | 3174 |
3200 /* This vector gets used to present single keys to Flookup_key. Since | 3175 /* This vector gets used to present single keys to Flookup_key. Since |
3201 that is done once per vector element, we don't want to cons up a | 3176 that is done once per vector element, we don't want to cons up a |
3204 GCPRO3 (elt_prefix, definition, kludge); | 3179 GCPRO3 (elt_prefix, definition, kludge); |
3205 | 3180 |
3206 if (partial) | 3181 if (partial) |
3207 suppress = intern ("suppress-keymap"); | 3182 suppress = intern ("suppress-keymap"); |
3208 | 3183 |
3209 if (CHAR_TABLE_P (vector)) | 3184 from = 0; |
3210 { | 3185 to = XVECTOR (vector)->size; |
3211 if (char_table_depth == 0) | |
3212 { | |
3213 /* VECTOR is a top level char-table. */ | |
3214 complete_char = 1; | |
3215 from = 0; | |
3216 to = CHAR_TABLE_ORDINARY_SLOTS; | |
3217 } | |
3218 else | |
3219 { | |
3220 /* VECTOR is a sub char-table. */ | |
3221 if (char_table_depth >= 3) | |
3222 /* A char-table is never that deep. */ | |
3223 error ("Too deep char table"); | |
3224 | |
3225 complete_char | |
3226 = (CHARSET_VALID_P (indices[0]) | |
3227 && ((CHARSET_DIMENSION (indices[0]) == 1 | |
3228 && char_table_depth == 1) | |
3229 || char_table_depth == 2)); | |
3230 | |
3231 /* Meaningful elements are from 32th to 127th. */ | |
3232 from = 32; | |
3233 to = SUB_CHAR_TABLE_ORDINARY_SLOTS; | |
3234 } | |
3235 } | |
3236 else | |
3237 { | |
3238 /* This does the right thing for ordinary vectors. */ | |
3239 | |
3240 complete_char = 1; | |
3241 from = 0; | |
3242 to = XVECTOR (vector)->size; | |
3243 } | |
3244 | 3186 |
3245 for (i = from; i < to; i++) | 3187 for (i = from; i < to; i++) |
3246 { | 3188 { |
3247 QUIT; | 3189 QUIT; |
3248 | 3190 |
3249 if (CHAR_TABLE_P (vector)) | 3191 definition = get_keyelt (AREF (vector, i), 0); |
3250 { | |
3251 if (char_table_depth == 0 && i >= CHAR_TABLE_SINGLE_BYTE_SLOTS) | |
3252 complete_char = 0; | |
3253 | |
3254 if (i >= CHAR_TABLE_SINGLE_BYTE_SLOTS | |
3255 && !CHARSET_DEFINED_P (i - 128)) | |
3256 continue; | |
3257 | |
3258 definition | |
3259 = get_keyelt (XCHAR_TABLE (vector)->contents[i], 0); | |
3260 } | |
3261 else | |
3262 definition = get_keyelt (AREF (vector, i), 0); | |
3263 | 3192 |
3264 if (NILP (definition)) continue; | 3193 if (NILP (definition)) continue; |
3265 | 3194 |
3266 /* Don't mention suppressed commands. */ | 3195 /* Don't mention suppressed commands. */ |
3267 if (SYMBOLP (definition) && partial) | 3196 if (SYMBOLP (definition) && partial) |
3271 tem = Fget (definition, suppress); | 3200 tem = Fget (definition, suppress); |
3272 | 3201 |
3273 if (!NILP (tem)) continue; | 3202 if (!NILP (tem)) continue; |
3274 } | 3203 } |
3275 | 3204 |
3276 /* Set CHARACTER to the character this entry describes, if any. | 3205 character = make_number (i); |
3277 Also update *INDICES. */ | |
3278 if (CHAR_TABLE_P (vector)) | |
3279 { | |
3280 indices[char_table_depth] = i; | |
3281 | |
3282 if (char_table_depth == 0) | |
3283 { | |
3284 character = i; | |
3285 indices[0] = i - 128; | |
3286 } | |
3287 else if (complete_char) | |
3288 { | |
3289 character = MAKE_CHAR (indices[0], indices[1], indices[2]); | |
3290 } | |
3291 else | |
3292 character = 0; | |
3293 } | |
3294 else | |
3295 character = i; | |
3296 | 3206 |
3297 /* If this binding is shadowed by some other map, ignore it. */ | 3207 /* If this binding is shadowed by some other map, ignore it. */ |
3298 if (!NILP (shadow) && complete_char) | 3208 if (!NILP (shadow)) |
3299 { | 3209 { |
3300 Lisp_Object tem; | 3210 Lisp_Object tem; |
3301 | 3211 |
3302 ASET (kludge, 0, make_number (character)); | 3212 ASET (kludge, 0, character); |
3303 tem = shadow_lookup (shadow, kludge, Qt); | 3213 tem = shadow_lookup (shadow, kludge, Qt); |
3304 | 3214 |
3305 if (!NILP (tem)) continue; | 3215 if (!NILP (tem)) continue; |
3306 } | 3216 } |
3307 | 3217 |
3308 /* Ignore this definition if it is shadowed by an earlier | 3218 /* Ignore this definition if it is shadowed by an earlier |
3309 one in the same keymap. */ | 3219 one in the same keymap. */ |
3310 if (!NILP (entire_map) && complete_char) | 3220 if (!NILP (entire_map)) |
3311 { | 3221 { |
3312 Lisp_Object tem; | 3222 Lisp_Object tem; |
3313 | 3223 |
3314 ASET (kludge, 0, make_number (character)); | 3224 ASET (kludge, 0, make_number (character)); |
3315 tem = Flookup_key (entire_map, kludge, Qt); | 3225 tem = Flookup_key (entire_map, kludge, Qt); |
3316 | 3226 |
3317 if (!EQ (tem, definition)) | 3227 if (!EQ (tem, definition)) |
3318 continue; | 3228 continue; |
3319 } | 3229 } |
3320 | |
3321 if (first) | |
3322 { | |
3323 if (char_table_depth == 0) | |
3324 insert ("\n", 1); | |
3325 first = 0; | |
3326 } | |
3327 | |
3328 /* For a sub char-table, show the depth by indentation. | |
3329 CHAR_TABLE_DEPTH can be greater than 0 only for a char-table. */ | |
3330 if (char_table_depth > 0) | |
3331 insert (" ", char_table_depth * 2); /* depth is 1 or 2. */ | |
3332 | 3230 |
3333 /* Output the prefix that applies to every entry in this map. */ | 3231 /* Output the prefix that applies to every entry in this map. */ |
3334 if (!NILP (elt_prefix)) | 3232 if (!NILP (elt_prefix)) |
3335 insert1 (elt_prefix); | 3233 insert1 (elt_prefix); |
3336 | 3234 |
3337 /* Insert or describe the character this slot is for, | 3235 insert1 (Fsingle_key_description (make_number (character), Qnil)); |
3338 or a description of what it is for. */ | |
3339 if (SUB_CHAR_TABLE_P (vector)) | |
3340 { | |
3341 if (complete_char) | |
3342 insert_char (character); | |
3343 else | |
3344 { | |
3345 /* We need an octal representation for this block of | |
3346 characters. */ | |
3347 char work[16]; | |
3348 sprintf (work, "(row %d)", i); | |
3349 insert (work, strlen (work)); | |
3350 } | |
3351 } | |
3352 else if (CHAR_TABLE_P (vector)) | |
3353 { | |
3354 if (complete_char) | |
3355 insert1 (Fsingle_key_description (make_number (character), Qnil)); | |
3356 else | |
3357 { | |
3358 /* Print the information for this character set. */ | |
3359 insert_string ("<"); | |
3360 tem2 = CHARSET_TABLE_INFO (i - 128, CHARSET_SHORT_NAME_IDX); | |
3361 if (STRINGP (tem2)) | |
3362 insert_from_string (tem2, 0, 0, XSTRING (tem2)->size, | |
3363 STRING_BYTES (XSTRING (tem2)), 0); | |
3364 else | |
3365 insert ("?", 1); | |
3366 insert (">", 1); | |
3367 } | |
3368 } | |
3369 else | |
3370 { | |
3371 insert1 (Fsingle_key_description (make_number (character), Qnil)); | |
3372 } | |
3373 | |
3374 /* If we find a sub char-table within a char-table, | |
3375 scan it recursively; it defines the details for | |
3376 a character set or a portion of a character set. */ | |
3377 if (CHAR_TABLE_P (vector) && SUB_CHAR_TABLE_P (definition)) | |
3378 { | |
3379 insert ("\n", 1); | |
3380 describe_vector (definition, elt_prefix, args, elt_describer, | |
3381 partial, shadow, entire_map, | |
3382 indices, char_table_depth + 1); | |
3383 continue; | |
3384 } | |
3385 | 3236 |
3386 starting_i = i; | 3237 starting_i = i; |
3387 | 3238 |
3388 /* Find all consecutive characters or rows that have the same | 3239 /* Find all consecutive characters or rows that have the same |
3389 definition. But, for elements of a top level char table, if | 3240 definition. But, for elements of a top level char table, if |
3390 they are for charsets, we had better describe one by one even | 3241 they are for charsets, we had better describe one by one even |
3391 if they have the same definition. */ | 3242 if they have the same definition. */ |
3392 if (CHAR_TABLE_P (vector)) | 3243 while (i + 1 < to |
3393 { | 3244 && (tem2 = get_keyelt (AREF (vector, i + 1), 0), |
3394 int limit = to; | 3245 !NILP (tem2)) |
3395 | 3246 && !NILP (Fequal (tem2, definition))) |
3396 if (char_table_depth == 0) | 3247 i++; |
3397 limit = CHAR_TABLE_SINGLE_BYTE_SLOTS; | |
3398 | |
3399 while (i + 1 < limit | |
3400 && (tem2 = get_keyelt (XCHAR_TABLE (vector)->contents[i + 1], 0), | |
3401 !NILP (tem2)) | |
3402 && !NILP (Fequal (tem2, definition))) | |
3403 i++; | |
3404 } | |
3405 else | |
3406 while (i + 1 < to | |
3407 && (tem2 = get_keyelt (AREF (vector, i + 1), 0), | |
3408 !NILP (tem2)) | |
3409 && !NILP (Fequal (tem2, definition))) | |
3410 i++; | |
3411 | |
3412 | 3248 |
3413 /* If we have a range of more than one character, | 3249 /* If we have a range of more than one character, |
3414 print where the range reaches to. */ | 3250 print where the range reaches to. */ |
3415 | 3251 |
3416 if (i != starting_i) | 3252 if (i != starting_i) |
3417 { | 3253 { |
3418 insert (" .. ", 4); | 3254 insert (" .. ", 4); |
3419 | 3255 |
3420 if (!NILP (elt_prefix)) | 3256 if (!NILP (elt_prefix)) |
3421 insert1 (elt_prefix); | 3257 insert1 (elt_prefix); |
3422 | 3258 insert1 (Fsingle_key_description (make_number (i), Qnil)); |
3423 if (CHAR_TABLE_P (vector)) | |
3424 { | |
3425 if (char_table_depth == 0) | |
3426 { | |
3427 insert1 (Fsingle_key_description (make_number (i), Qnil)); | |
3428 } | |
3429 else if (complete_char) | |
3430 { | |
3431 indices[char_table_depth] = i; | |
3432 character = MAKE_CHAR (indices[0], indices[1], indices[2]); | |
3433 insert_char (character); | |
3434 } | |
3435 else | |
3436 { | |
3437 /* We need an octal representation for this block of | |
3438 characters. */ | |
3439 char work[16]; | |
3440 sprintf (work, "(row %d)", i); | |
3441 insert (work, strlen (work)); | |
3442 } | |
3443 } | |
3444 else | |
3445 { | |
3446 insert1 (Fsingle_key_description (make_number (i), Qnil)); | |
3447 } | |
3448 } | 3259 } |
3449 | 3260 |
3450 /* Print a description of the definition of this character. | 3261 /* Print a description of the definition of this character. |
3451 elt_describer will take care of spacing out far enough | 3262 elt_describer will take care of spacing out far enough |
3452 for alignment purposes. */ | 3263 for alignment purposes. */ |
3453 (*elt_describer) (definition, args); | 3264 (*elt_describer) (definition, args); |
3454 } | 3265 } |
3455 | 3266 |
3456 /* For (sub) char-table, print `defalt' slot at last. */ | |
3457 if (CHAR_TABLE_P (vector) && !NILP (XCHAR_TABLE (vector)->defalt)) | |
3458 { | |
3459 insert (" ", char_table_depth * 2); | |
3460 insert_string ("<<default>>"); | |
3461 (*elt_describer) (XCHAR_TABLE (vector)->defalt, args); | |
3462 } | |
3463 | |
3464 UNGCPRO; | 3267 UNGCPRO; |
3465 } | 3268 } |
3269 | |
3270 /* Insert in the current buffer a description of the contents of | |
3271 char-table TABLE. We call ELT_DESCRIBER to insert the description | |
3272 of one value found in TABLE. | |
3273 | |
3274 ELT_PREFIX describes what "comes before" the keys or indices defined | |
3275 by this vector. This is a human-readable string whose size | |
3276 is not necessarily related to the situation. | |
3277 | |
3278 If PARTIAL is nonzero, it means do not mention suppressed commands | |
3279 (that assumes the vector is in a keymap). | |
3280 | |
3281 SHADOW is a list of keymaps that shadow this map. | |
3282 If it is non-nil, then we look up the key in those maps | |
3283 and we don't mention it now if it is defined by any of them. | |
3284 | |
3285 ENTIRE_MAP is the keymap in which this vector appears. | |
3286 If the definition in effect in the whole map does not match | |
3287 the one in this vector, we ignore this one. | |
3288 | |
3289 ARGS is simply passed as the second argument to ELT_DESCRIBER. */ | |
3290 | |
3291 void | |
3292 describe_char_table (table, elt_prefix, args, elt_describer, | |
3293 partial, shadow, entire_map) | |
3294 register Lisp_Object table; | |
3295 Lisp_Object args; | |
3296 Lisp_Object elt_prefix; | |
3297 void (*elt_describer) P_ ((Lisp_Object, Lisp_Object)); | |
3298 int partial; | |
3299 Lisp_Object shadow; | |
3300 Lisp_Object entire_map; | |
3301 { | |
3302 Lisp_Object definition; | |
3303 Lisp_Object tem2; | |
3304 register int i; | |
3305 Lisp_Object suppress; | |
3306 Lisp_Object kludge; | |
3307 struct gcpro gcpro1, gcpro2, gcpro3; | |
3308 /* Range of elements to be handled. */ | |
3309 int from, to; | |
3310 int c; | |
3311 int starting_i; | |
3312 | |
3313 suppress = Qnil; | |
3314 | |
3315 definition = Qnil; | |
3316 | |
3317 /* This vector gets used to present single keys to Flookup_key. Since | |
3318 that is done once per vector element, we don't want to cons up a | |
3319 fresh vector every time. */ | |
3320 kludge = Fmake_vector (make_number (1), Qnil); | |
3321 GCPRO3 (elt_prefix, definition, kludge); | |
3322 | |
3323 if (partial) | |
3324 suppress = intern ("suppress-keymap"); | |
3325 | |
3326 from = 0; | |
3327 to = MAX_CHAR + 1; | |
3328 | |
3329 while (from < to) | |
3330 { | |
3331 int range_beg, range_end; | |
3332 Lisp_Object val; | |
3333 | |
3334 QUIT; | |
3335 | |
3336 val = char_table_ref_and_range (table, from, &range_beg, &range_end); | |
3337 from = range_end + 1; | |
3338 definition = get_keyelt (val, 0); | |
3339 | |
3340 if (NILP (definition)) continue; | |
3341 | |
3342 /* Don't mention suppressed commands. */ | |
3343 if (SYMBOLP (definition) && partial) | |
3344 { | |
3345 Lisp_Object tem; | |
3346 | |
3347 tem = Fget (definition, suppress); | |
3348 | |
3349 if (!NILP (tem)) continue; | |
3350 } | |
3351 | |
3352 /* Output the prefix that applies to every entry in this map. */ | |
3353 if (!NILP (elt_prefix)) | |
3354 insert1 (elt_prefix); | |
3355 | |
3356 starting_i = range_beg; | |
3357 insert_char (starting_i); | |
3358 | |
3359 /* Find all consecutive characters that have the same | |
3360 definition. */ | |
3361 while (from < to | |
3362 && (val = char_table_ref_and_range (table, from, | |
3363 &range_beg, &range_end), | |
3364 tem2 = get_keyelt (val, 0), | |
3365 !NILP (tem2)) | |
3366 && !NILP (Fequal (tem2, definition))) | |
3367 from = range_end + 1; | |
3368 | |
3369 /* If we have a range of more than one character, | |
3370 print where the range reaches to. */ | |
3371 if (starting_i + 1 < from) | |
3372 { | |
3373 insert (" .. ", 4); | |
3374 | |
3375 if (!NILP (elt_prefix)) | |
3376 insert1 (elt_prefix); | |
3377 | |
3378 insert_char (from - 1); | |
3379 } | |
3380 | |
3381 /* Print a description of the definition of this character. | |
3382 elt_describer will take care of spacing out far enough | |
3383 for alignment purposes. */ | |
3384 (*elt_describer) (definition, args); | |
3385 } | |
3386 | |
3387 UNGCPRO; | |
3388 } | |
3389 | |
3466 | 3390 |
3467 /* Apropos - finding all symbols whose names match a regexp. */ | 3391 /* Apropos - finding all symbols whose names match a regexp. */ |
3468 Lisp_Object apropos_predicate; | 3392 Lisp_Object apropos_predicate; |
3469 Lisp_Object apropos_accumulate; | 3393 Lisp_Object apropos_accumulate; |
3470 | 3394 |