Mercurial > emacs
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 } |