aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman2005-12-30 04:52:32 +0000
committerRichard M. Stallman2005-12-30 04:52:32 +0000
commitc36238ee75f3dfab037a2694cf21c0f213432a92 (patch)
tree8d00a1cdc6b3025e694fb985da6e46d161aeb35d /src
parentaf3d4246e08b6a8831cdd912486e5458c7fa4643 (diff)
downloademacs-c36238ee75f3dfab037a2694cf21c0f213432a92.tar.gz
emacs-c36238ee75f3dfab037a2694cf21c0f213432a92.zip
(describe_map): Put sparse map elements into an array,
sort them, then output a sequence of identical bindings on one line. (struct describe_map_elt): New data type. (describe_map_compare): New function.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog7
-rw-r--r--src/keymap.c129
2 files changed, 115 insertions, 21 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 4f6cb895004..019e12fed2e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
12005-12-29 Richard M. Stallman <rms@gnu.org>
2
3 * keymap.c (describe_map): Put sparse map elements into an array,
4 sort them, then output a sequence of identical bindings on one line.
5 (struct describe_map_elt): New data type.
6 (describe_map_compare): New function.
7
12005-12-28 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> 82005-12-28 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
2 9
3 * gtkutil.c (xg_get_file_with_chooser): Changed message shown 10 * gtkutil.c (xg_get_file_with_chooser): Changed message shown
diff --git a/src/keymap.c b/src/keymap.c
index 74a1cc15024..f12a66c6326 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -3174,6 +3174,34 @@ describe_translation (definition, args)
3174 insert_string ("??\n"); 3174 insert_string ("??\n");
3175} 3175}
3176 3176
3177/* describe_map puts all the usable elements of a sparse keymap
3178 into an array of `struct describe_map_elt',
3179 then sorts them by the events. */
3180
3181struct describe_map_elt { Lisp_Object event; Lisp_Object definition; int shadowed; };
3182
3183/* qsort comparison function for sorting `struct describe_map_elt' by
3184 the event field. */
3185
3186static int
3187describe_map_compare (aa, bb)
3188 const void *aa, *bb;
3189{
3190 const struct describe_map_elt *a = aa, *b = bb;
3191 if (INTEGERP (a->event) && INTEGERP (b->event))
3192 return ((XINT (a->event) > XINT (b->event))
3193 - (XINT (a->event) < XINT (b->event)));
3194 if (!INTEGERP (a->event) && INTEGERP (b->event))
3195 return 1;
3196 if (INTEGERP (a->event) && !INTEGERP (b->event))
3197 return -1;
3198 if (SYMBOLP (a->event) && SYMBOLP (b->event))
3199 return (Fstring_lessp (a->event, b->event) ? -1
3200 : Fstring_lessp (b->event, a->event) ? 1
3201 : 0);
3202 return 0;
3203}
3204
3177/* Describe the contents of map MAP, assuming that this map itself is 3205/* Describe the contents of map MAP, assuming that this map itself is
3178 reached by the sequence of prefix keys PREFIX (a string or vector). 3206 reached by the sequence of prefix keys PREFIX (a string or vector).
3179 PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above. */ 3207 PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above. */
@@ -3197,6 +3225,13 @@ describe_map (map, prefix, elt_describer, partial, shadow,
3197 int first = 1; 3225 int first = 1;
3198 struct gcpro gcpro1, gcpro2, gcpro3; 3226 struct gcpro gcpro1, gcpro2, gcpro3;
3199 3227
3228 /* These accumulate the values from sparse keymap bindings,
3229 so we can sort them and handle them in order. */
3230 int length_needed = 0;
3231 struct describe_map_elt *vect;
3232 int slots_used = 0;
3233 int i;
3234
3200 suppress = Qnil; 3235 suppress = Qnil;
3201 3236
3202 if (partial) 3237 if (partial)
@@ -3208,6 +3243,12 @@ describe_map (map, prefix, elt_describer, partial, shadow,
3208 kludge = Fmake_vector (make_number (1), Qnil); 3243 kludge = Fmake_vector (make_number (1), Qnil);
3209 definition = Qnil; 3244 definition = Qnil;
3210 3245
3246 for (tail = map; CONSP (tail); tail = XCDR (tail))
3247 length_needed++;
3248
3249 vect = ((struct describe_map_elt *)
3250 alloca (sizeof (struct describe_map_elt) * length_needed));
3251
3211 GCPRO3 (prefix, definition, kludge); 3252 GCPRO3 (prefix, definition, kludge);
3212 3253
3213 for (tail = map; CONSP (tail); tail = XCDR (tail)) 3254 for (tail = map; CONSP (tail); tail = XCDR (tail))
@@ -3222,6 +3263,7 @@ describe_map (map, prefix, elt_describer, partial, shadow,
3222 else if (CONSP (XCAR (tail))) 3263 else if (CONSP (XCAR (tail)))
3223 { 3264 {
3224 int this_shadowed = 0; 3265 int this_shadowed = 0;
3266
3225 event = XCAR (XCAR (tail)); 3267 event = XCAR (XCAR (tail));
3226 3268
3227 /* Ignore bindings whose "prefix" are not really valid events. 3269 /* Ignore bindings whose "prefix" are not really valid events.
@@ -3262,27 +3304,10 @@ describe_map (map, prefix, elt_describer, partial, shadow,
3262 tem = Flookup_key (map, kludge, Qt); 3304 tem = Flookup_key (map, kludge, Qt);
3263 if (!EQ (tem, definition)) continue; 3305 if (!EQ (tem, definition)) continue;
3264 3306
3265 if (first) 3307 vect[slots_used].event = event;
3266 { 3308 vect[slots_used].definition = definition;
3267 previous_description_column = 0; 3309 vect[slots_used].shadowed = this_shadowed;
3268 insert ("\n", 1); 3310 slots_used++;
3269 first = 0;
3270 }
3271
3272 /* THIS gets the string to describe the character EVENT. */
3273 insert1 (Fkey_description (kludge, prefix));
3274
3275 /* Print a description of the definition of this character.
3276 elt_describer will take care of spacing out far enough
3277 for alignment purposes. */
3278 (*elt_describer) (definition, Qnil);
3279
3280 if (this_shadowed)
3281 {
3282 SET_PT (PT - 1);
3283 insert_string (" (binding currently shadowed)");
3284 SET_PT (PT + 1);
3285 }
3286 } 3311 }
3287 else if (EQ (XCAR (tail), Qkeymap)) 3312 else if (EQ (XCAR (tail), Qkeymap))
3288 { 3313 {
@@ -3296,6 +3321,68 @@ describe_map (map, prefix, elt_describer, partial, shadow,
3296 } 3321 }
3297 } 3322 }
3298 3323
3324 /* If we found some sparse map events, sort them. */
3325
3326 qsort (vect, slots_used, sizeof (struct describe_map_elt),
3327 describe_map_compare);
3328
3329 /* Now output them in sorted order. */
3330
3331 for (i = 0; i < slots_used; i++)
3332 {
3333 Lisp_Object start, end;
3334
3335 if (first)
3336 {
3337 previous_description_column = 0;
3338 insert ("\n", 1);
3339 first = 0;
3340 }
3341
3342 ASET (kludge, 0, vect[i].event);
3343 start = vect[i].event;
3344 end = start;
3345
3346 definition = vect[i].definition;
3347
3348 /* Find consecutive chars that are identically defined. */
3349 if (INTEGERP (vect[i].event))
3350 {
3351 while (i + 1 < slots_used
3352 && XINT (vect[i + 1].event) == XINT (vect[i].event) + 1
3353 && !NILP (Fequal (vect[i + 1].definition, definition))
3354 && vect[i].shadowed == vect[i + 1].shadowed)
3355 i++;
3356 end = vect[i].event;
3357 }
3358
3359 /* Now START .. END is the range to describe next. */
3360
3361 /* Insert the string to describe the event START. */
3362 insert1 (Fkey_description (kludge, prefix));
3363
3364 if (!EQ (start, end))
3365 {
3366 insert (" .. ", 4);
3367
3368 ASET (kludge, 0, end);
3369 /* Insert the string to describe the character END. */
3370 insert1 (Fkey_description (kludge, prefix));
3371 }
3372
3373 /* Print a description of the definition of this character.
3374 elt_describer will take care of spacing out far enough
3375 for alignment purposes. */
3376 (*elt_describer) (vect[i].definition, Qnil);
3377
3378 if (vect[i].shadowed)
3379 {
3380 SET_PT (PT - 1);
3381 insert_string (" (binding currently shadowed)");
3382 SET_PT (PT + 1);
3383 }
3384 }
3385
3299 UNGCPRO; 3386 UNGCPRO;
3300} 3387}
3301 3388