diff options
| author | Richard M. Stallman | 2005-12-30 04:52:32 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2005-12-30 04:52:32 +0000 |
| commit | c36238ee75f3dfab037a2694cf21c0f213432a92 (patch) | |
| tree | 8d00a1cdc6b3025e694fb985da6e46d161aeb35d /src | |
| parent | af3d4246e08b6a8831cdd912486e5458c7fa4643 (diff) | |
| download | emacs-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/ChangeLog | 7 | ||||
| -rw-r--r-- | src/keymap.c | 129 |
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 @@ | |||
| 1 | 2005-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 | |||
| 1 | 2005-12-28 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> | 8 | 2005-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 | |||
| 3181 | struct 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 | |||
| 3186 | static int | ||
| 3187 | describe_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 | ||