comparison src/keymap.c @ 83450:c69d44922688

Merged from miles@gnu.org--gnu-2005 (patch 682) Patches applied: * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-682 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-490
author Karoly Lorentey <lorentey@elte.hu>
date Tue, 03 Jan 2006 02:15:28 +0000
parents 14a4eb789b45 d2dff317d618
children 55e22205ba88
comparison
equal deleted inserted replaced
83449:ff74a86c2b16 83450:c69d44922688
3165 insert_string ("Prefix Command\n"); 3165 insert_string ("Prefix Command\n");
3166 else 3166 else
3167 insert_string ("??\n"); 3167 insert_string ("??\n");
3168 } 3168 }
3169 3169
3170 /* describe_map puts all the usable elements of a sparse keymap
3171 into an array of `struct describe_map_elt',
3172 then sorts them by the events. */
3173
3174 struct describe_map_elt { Lisp_Object event; Lisp_Object definition; int shadowed; };
3175
3176 /* qsort comparison function for sorting `struct describe_map_elt' by
3177 the event field. */
3178
3179 static int
3180 describe_map_compare (aa, bb)
3181 const void *aa, *bb;
3182 {
3183 const struct describe_map_elt *a = aa, *b = bb;
3184 if (INTEGERP (a->event) && INTEGERP (b->event))
3185 return ((XINT (a->event) > XINT (b->event))
3186 - (XINT (a->event) < XINT (b->event)));
3187 if (!INTEGERP (a->event) && INTEGERP (b->event))
3188 return 1;
3189 if (INTEGERP (a->event) && !INTEGERP (b->event))
3190 return -1;
3191 if (SYMBOLP (a->event) && SYMBOLP (b->event))
3192 return (Fstring_lessp (a->event, b->event) ? -1
3193 : Fstring_lessp (b->event, a->event) ? 1
3194 : 0);
3195 return 0;
3196 }
3197
3170 /* Describe the contents of map MAP, assuming that this map itself is 3198 /* Describe the contents of map MAP, assuming that this map itself is
3171 reached by the sequence of prefix keys PREFIX (a string or vector). 3199 reached by the sequence of prefix keys PREFIX (a string or vector).
3172 PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above. */ 3200 PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above. */
3173 3201
3174 static void 3202 static void
3188 Lisp_Object suppress; 3216 Lisp_Object suppress;
3189 Lisp_Object kludge; 3217 Lisp_Object kludge;
3190 int first = 1; 3218 int first = 1;
3191 struct gcpro gcpro1, gcpro2, gcpro3; 3219 struct gcpro gcpro1, gcpro2, gcpro3;
3192 3220
3221 /* These accumulate the values from sparse keymap bindings,
3222 so we can sort them and handle them in order. */
3223 int length_needed = 0;
3224 struct describe_map_elt *vect;
3225 int slots_used = 0;
3226 int i;
3227
3193 suppress = Qnil; 3228 suppress = Qnil;
3194 3229
3195 if (partial) 3230 if (partial)
3196 suppress = intern ("suppress-keymap"); 3231 suppress = intern ("suppress-keymap");
3197 3232
3198 /* This vector gets used to present single keys to Flookup_key. Since 3233 /* This vector gets used to present single keys to Flookup_key. Since
3199 that is done once per keymap element, we don't want to cons up a 3234 that is done once per keymap element, we don't want to cons up a
3200 fresh vector every time. */ 3235 fresh vector every time. */
3201 kludge = Fmake_vector (make_number (1), Qnil); 3236 kludge = Fmake_vector (make_number (1), Qnil);
3202 definition = Qnil; 3237 definition = Qnil;
3238
3239 for (tail = map; CONSP (tail); tail = XCDR (tail))
3240 length_needed++;
3241
3242 vect = ((struct describe_map_elt *)
3243 alloca (sizeof (struct describe_map_elt) * length_needed));
3203 3244
3204 GCPRO3 (prefix, definition, kludge); 3245 GCPRO3 (prefix, definition, kludge);
3205 3246
3206 for (tail = map; CONSP (tail); tail = XCDR (tail)) 3247 for (tail = map; CONSP (tail); tail = XCDR (tail))
3207 { 3248 {
3213 prefix, Qnil, elt_describer, partial, shadow, map, 3254 prefix, Qnil, elt_describer, partial, shadow, map,
3214 (int *)0, 0, 1, mention_shadow); 3255 (int *)0, 0, 1, mention_shadow);
3215 else if (CONSP (XCAR (tail))) 3256 else if (CONSP (XCAR (tail)))
3216 { 3257 {
3217 int this_shadowed = 0; 3258 int this_shadowed = 0;
3259
3218 event = XCAR (XCAR (tail)); 3260 event = XCAR (XCAR (tail));
3219 3261
3220 /* Ignore bindings whose "prefix" are not really valid events. 3262 /* Ignore bindings whose "prefix" are not really valid events.
3221 (We get these in the frames and buffers menu.) */ 3263 (We get these in the frames and buffers menu.) */
3222 if (!(SYMBOLP (event) || INTEGERP (event))) 3264 if (!(SYMBOLP (event) || INTEGERP (event)))
3253 } 3295 }
3254 3296
3255 tem = Flookup_key (map, kludge, Qt); 3297 tem = Flookup_key (map, kludge, Qt);
3256 if (!EQ (tem, definition)) continue; 3298 if (!EQ (tem, definition)) continue;
3257 3299
3258 if (first) 3300 vect[slots_used].event = event;
3259 { 3301 vect[slots_used].definition = definition;
3260 previous_description_column = 0; 3302 vect[slots_used].shadowed = this_shadowed;
3261 insert ("\n", 1); 3303 slots_used++;
3262 first = 0;
3263 }
3264
3265 /* THIS gets the string to describe the character EVENT. */
3266 insert1 (Fkey_description (kludge, prefix));
3267
3268 /* Print a description of the definition of this character.
3269 elt_describer will take care of spacing out far enough
3270 for alignment purposes. */
3271 (*elt_describer) (definition, Qnil);
3272
3273 if (this_shadowed)
3274 {
3275 SET_PT (PT - 1);
3276 insert_string (" (binding currently shadowed)");
3277 SET_PT (PT + 1);
3278 }
3279 } 3304 }
3280 else if (EQ (XCAR (tail), Qkeymap)) 3305 else if (EQ (XCAR (tail), Qkeymap))
3281 { 3306 {
3282 /* The same keymap might be in the structure twice, if we're 3307 /* The same keymap might be in the structure twice, if we're
3283 using an inherited keymap. So skip anything we've already 3308 using an inherited keymap. So skip anything we've already
3284 encountered. */ 3309 encountered. */
3285 tem = Fassq (tail, *seen); 3310 tem = Fassq (tail, *seen);
3286 if (CONSP (tem) && !NILP (Fequal (XCAR (tem), prefix))) 3311 if (CONSP (tem) && !NILP (Fequal (XCAR (tem), prefix)))
3287 break; 3312 break;
3288 *seen = Fcons (Fcons (tail, prefix), *seen); 3313 *seen = Fcons (Fcons (tail, prefix), *seen);
3314 }
3315 }
3316
3317 /* If we found some sparse map events, sort them. */
3318
3319 qsort (vect, slots_used, sizeof (struct describe_map_elt),
3320 describe_map_compare);
3321
3322 /* Now output them in sorted order. */
3323
3324 for (i = 0; i < slots_used; i++)
3325 {
3326 Lisp_Object start, end;
3327
3328 if (first)
3329 {
3330 previous_description_column = 0;
3331 insert ("\n", 1);
3332 first = 0;
3333 }
3334
3335 ASET (kludge, 0, vect[i].event);
3336 start = vect[i].event;
3337 end = start;
3338
3339 definition = vect[i].definition;
3340
3341 /* Find consecutive chars that are identically defined. */
3342 if (INTEGERP (vect[i].event))
3343 {
3344 while (i + 1 < slots_used
3345 && XINT (vect[i + 1].event) == XINT (vect[i].event) + 1
3346 && !NILP (Fequal (vect[i + 1].definition, definition))
3347 && vect[i].shadowed == vect[i + 1].shadowed)
3348 i++;
3349 end = vect[i].event;
3350 }
3351
3352 /* Now START .. END is the range to describe next. */
3353
3354 /* Insert the string to describe the event START. */
3355 insert1 (Fkey_description (kludge, prefix));
3356
3357 if (!EQ (start, end))
3358 {
3359 insert (" .. ", 4);
3360
3361 ASET (kludge, 0, end);
3362 /* Insert the string to describe the character END. */
3363 insert1 (Fkey_description (kludge, prefix));
3364 }
3365
3366 /* Print a description of the definition of this character.
3367 elt_describer will take care of spacing out far enough
3368 for alignment purposes. */
3369 (*elt_describer) (vect[i].definition, Qnil);
3370
3371 if (vect[i].shadowed)
3372 {
3373 SET_PT (PT - 1);
3374 insert_string (" (binding currently shadowed)");
3375 SET_PT (PT + 1);
3289 } 3376 }
3290 } 3377 }
3291 3378
3292 UNGCPRO; 3379 UNGCPRO;
3293 } 3380 }