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