diff options
| author | Karoly Lorentey | 2006-01-03 02:15:28 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2006-01-03 02:15:28 +0000 |
| commit | b58cb6144c59dfa3a44b9b383cf354bc2c9bebdf (patch) | |
| tree | 87bc562249d9e597e12406e1d9b1c7dfb0f937e5 /src/keymap.c | |
| parent | b3e6f69c10973ff7b040ced07a3a084960619681 (diff) | |
| parent | 55262b16df717fe533ea4ad23dac3f02398c9055 (diff) | |
| download | emacs-b58cb6144c59dfa3a44b9b383cf354bc2c9bebdf.tar.gz emacs-b58cb6144c59dfa3a44b9b383cf354bc2c9bebdf.zip | |
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
Diffstat (limited to 'src/keymap.c')
| -rw-r--r-- | src/keymap.c | 129 |
1 files changed, 108 insertions, 21 deletions
diff --git a/src/keymap.c b/src/keymap.c index 97789a75f1d..64069ca4deb 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -3167,6 +3167,34 @@ describe_translation (definition, args) | |||
| 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. */ |
| @@ -3190,6 +3218,13 @@ describe_map (map, prefix, elt_describer, partial, shadow, | |||
| 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) |
| @@ -3201,6 +3236,12 @@ describe_map (map, prefix, elt_describer, partial, shadow, | |||
| 3201 | kludge = Fmake_vector (make_number (1), Qnil); | 3236 | kludge = Fmake_vector (make_number (1), Qnil); |
| 3202 | definition = Qnil; | 3237 | definition = Qnil; |
| 3203 | 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)); | ||
| 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)) |
| @@ -3215,6 +3256,7 @@ describe_map (map, prefix, elt_describer, partial, 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. |
| @@ -3255,27 +3297,10 @@ describe_map (map, prefix, elt_describer, partial, shadow, | |||
| 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 | { |
| @@ -3289,6 +3314,68 @@ describe_map (map, prefix, elt_describer, partial, shadow, | |||
| 3289 | } | 3314 | } |
| 3290 | } | 3315 | } |
| 3291 | 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); | ||
| 3376 | } | ||
| 3377 | } | ||
| 3378 | |||
| 3292 | UNGCPRO; | 3379 | UNGCPRO; |
| 3293 | } | 3380 | } |
| 3294 | 3381 | ||