Mercurial > emacs
comparison src/xdisp.c @ 38190:dcc5dde7a1a0
(handle_invisible_prop): Deal with overlay strings at
the start of invisible text.
(setup_for_ellipsis): New function.
(next_overlay_string): After all overlay strings have been
processed, display an ellipsis if necessary.
(load_overlay_strings, get_overlay_strings): Add parameter CHARPOS.
(push_it): Initialize display_ellipsis_p on the iterator's stack.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Tue, 26 Jun 2001 09:47:11 +0000 |
parents | 22571591f506 |
children | 2b6f6e16b9b6 |
comparison
equal
deleted
inserted
replaced
38189:770e48dacf6e | 38190:dcc5dde7a1a0 |
---|---|
657 | 657 |
658 | 658 |
659 | 659 |
660 /* Function prototypes. */ | 660 /* Function prototypes. */ |
661 | 661 |
662 static void setup_for_ellipsis P_ ((struct it *)); | |
662 static void mark_window_display_accurate_1 P_ ((struct window *, int)); | 663 static void mark_window_display_accurate_1 P_ ((struct window *, int)); |
663 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object)); | 664 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object)); |
664 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object)); | 665 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object)); |
665 static int cursor_row_p P_ ((struct window *, struct glyph_row *)); | 666 static int cursor_row_p P_ ((struct window *, struct glyph_row *)); |
666 static int redisplay_mode_lines P_ ((Lisp_Object, int)); | 667 static int redisplay_mode_lines P_ ((Lisp_Object, int)); |
730 static int display_count_lines P_ ((int, int, int, int, int *)); | 731 static int display_count_lines P_ ((int, int, int, int, int *)); |
731 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object, | 732 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object, |
732 int, int, struct it *, int, int, int, int)); | 733 int, int, struct it *, int, int, int, int)); |
733 static void compute_line_metrics P_ ((struct it *)); | 734 static void compute_line_metrics P_ ((struct it *)); |
734 static void run_redisplay_end_trigger_hook P_ ((struct it *)); | 735 static void run_redisplay_end_trigger_hook P_ ((struct it *)); |
735 static int get_overlay_strings P_ ((struct it *)); | 736 static int get_overlay_strings P_ ((struct it *, int)); |
736 static void next_overlay_string P_ ((struct it *)); | 737 static void next_overlay_string P_ ((struct it *)); |
737 static void reseat P_ ((struct it *, struct text_pos, int)); | 738 static void reseat P_ ((struct it *, struct text_pos, int)); |
738 static void reseat_1 P_ ((struct it *, struct text_pos, int)); | 739 static void reseat_1 P_ ((struct it *, struct text_pos, int)); |
739 static void back_to_previous_visible_line_start P_ ((struct it *)); | 740 static void back_to_previous_visible_line_start P_ ((struct it *)); |
740 static void reseat_at_previous_visible_line_start P_ ((struct it *)); | 741 static void reseat_at_previous_visible_line_start P_ ((struct it *)); |
744 static int next_element_from_c_string P_ ((struct it *)); | 745 static int next_element_from_c_string P_ ((struct it *)); |
745 static int next_element_from_buffer P_ ((struct it *)); | 746 static int next_element_from_buffer P_ ((struct it *)); |
746 static int next_element_from_composition P_ ((struct it *)); | 747 static int next_element_from_composition P_ ((struct it *)); |
747 static int next_element_from_image P_ ((struct it *)); | 748 static int next_element_from_image P_ ((struct it *)); |
748 static int next_element_from_stretch P_ ((struct it *)); | 749 static int next_element_from_stretch P_ ((struct it *)); |
749 static void load_overlay_strings P_ ((struct it *)); | 750 static void load_overlay_strings P_ ((struct it *, int)); |
750 static void init_from_display_pos P_ ((struct it *, struct window *, | 751 static void init_from_display_pos P_ ((struct it *, struct window *, |
751 struct display_pos *)); | 752 struct display_pos *)); |
752 static void reseat_to_string P_ ((struct it *, unsigned char *, | 753 static void reseat_to_string P_ ((struct it *, unsigned char *, |
753 Lisp_Object, int, int, int, int)); | 754 Lisp_Object, int, int, int, int)); |
754 static enum move_it_result move_it_in_display_line_to P_ ((struct it *, | 755 static enum move_it_result move_it_in_display_line_to P_ ((struct it *, |
1846 { | 1847 { |
1847 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE; | 1848 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE; |
1848 it->current.overlay_string_index = 0; | 1849 it->current.overlay_string_index = 0; |
1849 while (n--) | 1850 while (n--) |
1850 { | 1851 { |
1851 load_overlay_strings (it); | 1852 load_overlay_strings (it, 0); |
1852 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE; | 1853 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE; |
1853 } | 1854 } |
1854 } | 1855 } |
1855 | 1856 |
1856 it->current.overlay_string_index = pos->overlay_string_index; | 1857 it->current.overlay_string_index = pos->overlay_string_index; |
2529 } | 2530 } |
2530 } | 2531 } |
2531 } | 2532 } |
2532 else | 2533 else |
2533 { | 2534 { |
2534 int visible_p, newpos, next_stop; | 2535 int visible_p, newpos, next_stop, start_charpos; |
2535 Lisp_Object pos, prop; | 2536 Lisp_Object pos, prop, overlay; |
2536 | 2537 |
2537 /* First of all, is there invisible text at this position? */ | 2538 /* First of all, is there invisible text at this position? */ |
2539 start_charpos = IT_CHARPOS (*it); | |
2538 pos = make_number (IT_CHARPOS (*it)); | 2540 pos = make_number (IT_CHARPOS (*it)); |
2539 prop = Fget_char_property (pos, Qinvisible, it->window); | 2541 prop = get_char_property_and_overlay (pos, Qinvisible, it->window, |
2542 &overlay); | |
2540 | 2543 |
2541 /* If we are on invisible text, skip over it. */ | 2544 /* If we are on invisible text, skip over it. */ |
2542 if (TEXT_PROP_MEANS_INVISIBLE (prop) | 2545 if (TEXT_PROP_MEANS_INVISIBLE (prop) |
2543 && IT_CHARPOS (*it) < it->end_charpos) | 2546 && IT_CHARPOS (*it) < it->end_charpos) |
2544 { | 2547 { |
2583 skip starting with next_stop. */ | 2586 skip starting with next_stop. */ |
2584 if (!visible_p) | 2587 if (!visible_p) |
2585 IT_CHARPOS (*it) = next_stop; | 2588 IT_CHARPOS (*it) = next_stop; |
2586 } | 2589 } |
2587 while (!visible_p); | 2590 while (!visible_p); |
2588 | 2591 |
2589 /* The position newpos is now either ZV or on visible text. */ | 2592 /* The position newpos is now either ZV or on visible text. */ |
2590 IT_CHARPOS (*it) = newpos; | 2593 IT_CHARPOS (*it) = newpos; |
2591 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos); | 2594 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos); |
2592 | 2595 |
2593 /* Maybe return `...' next for the end of the invisible text. */ | 2596 /* If there are before-strings at the start of invisible |
2594 if (display_ellipsis_p) | 2597 text, and the text is invisible because of a text |
2598 property, arrange to show before-strings because 20.x did | |
2599 it that way. (If the text is invisible because of an | |
2600 overlay property instead of a text property, this is | |
2601 already handled in the overlay code.) */ | |
2602 if (NILP (overlay) | |
2603 && get_overlay_strings (it, start_charpos)) | |
2595 { | 2604 { |
2596 if (it->dp | 2605 handled = HANDLED_RECOMPUTE_PROPS; |
2597 && VECTORP (DISP_INVIS_VECTOR (it->dp))) | 2606 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p; |
2598 { | |
2599 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp)); | |
2600 it->dpvec = v->contents; | |
2601 it->dpend = v->contents + v->size; | |
2602 } | |
2603 else | |
2604 { | |
2605 /* Default `...'. */ | |
2606 it->dpvec = default_invis_vector; | |
2607 it->dpend = default_invis_vector + 3; | |
2608 } | |
2609 | |
2610 /* The ellipsis display does not replace the display of | |
2611 the character at the new position. Indicate this by | |
2612 setting IT->dpvec_char_len to zero. */ | |
2613 it->dpvec_char_len = 0; | |
2614 | |
2615 it->current.dpvec_index = 0; | |
2616 it->method = next_element_from_display_vector; | |
2617 } | 2607 } |
2608 else if (display_ellipsis_p) | |
2609 setup_for_ellipsis (it); | |
2618 } | 2610 } |
2619 } | 2611 } |
2620 | 2612 |
2621 return handled; | 2613 return handled; |
2614 } | |
2615 | |
2616 | |
2617 /* Make iterator IT return `...' next. */ | |
2618 | |
2619 static void | |
2620 setup_for_ellipsis (it) | |
2621 struct it *it; | |
2622 { | |
2623 if (it->dp | |
2624 && VECTORP (DISP_INVIS_VECTOR (it->dp))) | |
2625 { | |
2626 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp)); | |
2627 it->dpvec = v->contents; | |
2628 it->dpend = v->contents + v->size; | |
2629 } | |
2630 else | |
2631 { | |
2632 /* Default `...'. */ | |
2633 it->dpvec = default_invis_vector; | |
2634 it->dpend = default_invis_vector + 3; | |
2635 } | |
2636 | |
2637 /* The ellipsis display does not replace the display of the | |
2638 character at the new position. Indicate this by setting | |
2639 IT->dpvec_char_len to zero. */ | |
2640 it->dpvec_char_len = 0; | |
2641 | |
2642 it->current.dpvec_index = 0; | |
2643 it->method = next_element_from_display_vector; | |
2622 } | 2644 } |
2623 | 2645 |
2624 | 2646 |
2625 | 2647 |
2626 /*********************************************************************** | 2648 /*********************************************************************** |
3283 | 3305 |
3284 static enum prop_handled | 3306 static enum prop_handled |
3285 handle_overlay_change (it) | 3307 handle_overlay_change (it) |
3286 struct it *it; | 3308 struct it *it; |
3287 { | 3309 { |
3288 if (!STRINGP (it->string) && get_overlay_strings (it)) | 3310 if (!STRINGP (it->string) && get_overlay_strings (it, 0)) |
3289 return HANDLED_RECOMPUTE_PROPS; | 3311 return HANDLED_RECOMPUTE_PROPS; |
3290 else | 3312 else |
3291 return HANDLED_NORMALLY; | 3313 return HANDLED_NORMALLY; |
3292 } | 3314 } |
3293 | 3315 |
3307 if (it->current.overlay_string_index == it->n_overlay_strings) | 3329 if (it->current.overlay_string_index == it->n_overlay_strings) |
3308 { | 3330 { |
3309 /* No more overlay strings. Restore IT's settings to what | 3331 /* No more overlay strings. Restore IT's settings to what |
3310 they were before overlay strings were processed, and | 3332 they were before overlay strings were processed, and |
3311 continue to deliver from current_buffer. */ | 3333 continue to deliver from current_buffer. */ |
3334 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p; | |
3335 | |
3312 pop_it (it); | 3336 pop_it (it); |
3313 xassert (it->stop_charpos >= BEGV | 3337 xassert (it->stop_charpos >= BEGV |
3314 && it->stop_charpos <= it->end_charpos); | 3338 && it->stop_charpos <= it->end_charpos); |
3315 it->string = Qnil; | 3339 it->string = Qnil; |
3316 it->current.overlay_string_index = -1; | 3340 it->current.overlay_string_index = -1; |
3321 /* If we're at the end of the buffer, record that we have | 3345 /* If we're at the end of the buffer, record that we have |
3322 processed the overlay strings there already, so that | 3346 processed the overlay strings there already, so that |
3323 next_element_from_buffer doesn't try it again. */ | 3347 next_element_from_buffer doesn't try it again. */ |
3324 if (IT_CHARPOS (*it) >= it->end_charpos) | 3348 if (IT_CHARPOS (*it) >= it->end_charpos) |
3325 it->overlay_strings_at_end_processed_p = 1; | 3349 it->overlay_strings_at_end_processed_p = 1; |
3350 | |
3351 /* If we have to display `...' for invisible text, set | |
3352 the iterator up for that. */ | |
3353 if (display_ellipsis_p) | |
3354 setup_for_ellipsis (it); | |
3326 } | 3355 } |
3327 else | 3356 else |
3328 { | 3357 { |
3329 /* There are more overlay strings to process. If | 3358 /* There are more overlay strings to process. If |
3330 IT->current.overlay_string_index has advanced to a position | 3359 IT->current.overlay_string_index has advanced to a position |
3331 where we must load IT->overlay_strings with more strings, do | 3360 where we must load IT->overlay_strings with more strings, do |
3332 it. */ | 3361 it. */ |
3333 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE; | 3362 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE; |
3334 | 3363 |
3335 if (it->current.overlay_string_index && i == 0) | 3364 if (it->current.overlay_string_index && i == 0) |
3336 load_overlay_strings (it); | 3365 load_overlay_strings (it, 0); |
3337 | 3366 |
3338 /* Initialize IT to deliver display elements from the overlay | 3367 /* Initialize IT to deliver display elements from the overlay |
3339 string. */ | 3368 string. */ |
3340 it->string = it->overlay_strings[i]; | 3369 it->string = it->overlay_strings[i]; |
3341 it->multibyte_p = STRING_MULTIBYTE (it->string); | 3370 it->multibyte_p = STRING_MULTIBYTE (it->string); |
3391 return result; | 3420 return result; |
3392 } | 3421 } |
3393 | 3422 |
3394 | 3423 |
3395 /* Load the vector IT->overlay_strings with overlay strings from IT's | 3424 /* Load the vector IT->overlay_strings with overlay strings from IT's |
3396 current buffer position. Set IT->n_overlays to the total number of | 3425 current buffer position, or from CHARPOS if that is > 0. Set |
3397 overlay strings found. | 3426 IT->n_overlays to the total number of overlay strings found. |
3398 | 3427 |
3399 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at | 3428 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at |
3400 a time. On entry into load_overlay_strings, | 3429 a time. On entry into load_overlay_strings, |
3401 IT->current.overlay_string_index gives the number of overlay | 3430 IT->current.overlay_string_index gives the number of overlay |
3402 strings that have already been loaded by previous calls to this | 3431 strings that have already been loaded by previous calls to this |
3415 front of before-string strings. Within before and after-strings, | 3444 front of before-string strings. Within before and after-strings, |
3416 strings are sorted by overlay priority. See also function | 3445 strings are sorted by overlay priority. See also function |
3417 compare_overlay_entries. */ | 3446 compare_overlay_entries. */ |
3418 | 3447 |
3419 static void | 3448 static void |
3420 load_overlay_strings (it) | 3449 load_overlay_strings (it, charpos) |
3421 struct it *it; | 3450 struct it *it; |
3451 int charpos; | |
3422 { | 3452 { |
3423 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority; | 3453 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority; |
3424 Lisp_Object ov, overlay, window, str, invisible; | 3454 Lisp_Object ov, overlay, window, str, invisible; |
3425 int start, end; | 3455 int start, end; |
3426 int size = 20; | 3456 int size = 20; |
3427 int n = 0, i, j, invis_p; | 3457 int n = 0, i, j, invis_p; |
3428 struct overlay_entry *entries | 3458 struct overlay_entry *entries |
3429 = (struct overlay_entry *) alloca (size * sizeof *entries); | 3459 = (struct overlay_entry *) alloca (size * sizeof *entries); |
3430 int charpos = IT_CHARPOS (*it); | 3460 |
3461 if (charpos <= 0) | |
3462 charpos = IT_CHARPOS (*it); | |
3431 | 3463 |
3432 /* Append the overlay string STRING of overlay OVERLAY to vector | 3464 /* Append the overlay string STRING of overlay OVERLAY to vector |
3433 `entries' which has size `size' and currently contains `n' | 3465 `entries' which has size `size' and currently contains `n' |
3434 elements. AFTER_P non-zero means STRING is an after-string of | 3466 elements. AFTER_P non-zero means STRING is an after-string of |
3435 OVERLAY. */ | 3467 OVERLAY. */ |
3557 CHECK_IT (it); | 3589 CHECK_IT (it); |
3558 } | 3590 } |
3559 | 3591 |
3560 | 3592 |
3561 /* Get the first chunk of overlay strings at IT's current buffer | 3593 /* Get the first chunk of overlay strings at IT's current buffer |
3562 position. Value is non-zero if at least one overlay string was | 3594 position, or at CHARPOS if that is > 0. Value is non-zero if at |
3563 found. */ | 3595 least one overlay string was found. */ |
3564 | 3596 |
3565 static int | 3597 static int |
3566 get_overlay_strings (it) | 3598 get_overlay_strings (it, charpos) |
3567 struct it *it; | 3599 struct it *it; |
3600 int charpos; | |
3568 { | 3601 { |
3569 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to | 3602 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to |
3570 process. This fills IT->overlay_strings with strings, and sets | 3603 process. This fills IT->overlay_strings with strings, and sets |
3571 IT->n_overlay_strings to the total number of strings to process. | 3604 IT->n_overlay_strings to the total number of strings to process. |
3572 IT->pos.overlay_string_index has to be set temporarily to zero | 3605 IT->pos.overlay_string_index has to be set temporarily to zero |
3573 because load_overlay_strings needs this; it must be set to -1 | 3606 because load_overlay_strings needs this; it must be set to -1 |
3574 when no overlay strings are found because a zero value would | 3607 when no overlay strings are found because a zero value would |
3575 indicate a position in the first overlay string. */ | 3608 indicate a position in the first overlay string. */ |
3576 it->current.overlay_string_index = 0; | 3609 it->current.overlay_string_index = 0; |
3577 load_overlay_strings (it); | 3610 load_overlay_strings (it, charpos); |
3578 | 3611 |
3579 /* If we found overlay strings, set up IT to deliver display | 3612 /* If we found overlay strings, set up IT to deliver display |
3580 elements from the first one. Otherwise set up IT to deliver | 3613 elements from the first one. Otherwise set up IT to deliver |
3581 from current_buffer. */ | 3614 from current_buffer. */ |
3582 if (it->n_overlay_strings) | 3615 if (it->n_overlay_strings) |
3646 p->multibyte_p = it->multibyte_p; | 3679 p->multibyte_p = it->multibyte_p; |
3647 p->space_width = it->space_width; | 3680 p->space_width = it->space_width; |
3648 p->font_height = it->font_height; | 3681 p->font_height = it->font_height; |
3649 p->voffset = it->voffset; | 3682 p->voffset = it->voffset; |
3650 p->string_from_display_prop_p = it->string_from_display_prop_p; | 3683 p->string_from_display_prop_p = it->string_from_display_prop_p; |
3684 p->display_ellipsis_p = 0; | |
3651 ++it->sp; | 3685 ++it->sp; |
3652 } | 3686 } |
3653 | 3687 |
3654 | 3688 |
3655 /* Restore IT's settings from IT->stack. Called, for example, when no | 3689 /* Restore IT's settings from IT->stack. Called, for example, when no |
4700 if (it->overlay_strings_at_end_processed_p) | 4734 if (it->overlay_strings_at_end_processed_p) |
4701 overlay_strings_follow_p = 0; | 4735 overlay_strings_follow_p = 0; |
4702 else | 4736 else |
4703 { | 4737 { |
4704 it->overlay_strings_at_end_processed_p = 1; | 4738 it->overlay_strings_at_end_processed_p = 1; |
4705 overlay_strings_follow_p = get_overlay_strings (it); | 4739 overlay_strings_follow_p = get_overlay_strings (it, 0); |
4706 } | 4740 } |
4707 | 4741 |
4708 if (overlay_strings_follow_p) | 4742 if (overlay_strings_follow_p) |
4709 success_p = get_next_display_element (it); | 4743 success_p = get_next_display_element (it); |
4710 else | 4744 else |