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