aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/xdisp.c172
1 files changed, 106 insertions, 66 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index c0f0ca9df1b..28a5c4e0c0a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -346,10 +346,17 @@ extern Lisp_Object Voverflow_newline_into_fringe;
346 (!NILP (Voverflow_newline_into_fringe) \ 346 (!NILP (Voverflow_newline_into_fringe) \
347 && FRAME_WINDOW_P (it->f) \ 347 && FRAME_WINDOW_P (it->f) \
348 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \ 348 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
349 && it->current_x == it->last_visible_x) 349 && it->current_x == it->last_visible_x \
350 && it->line_wrap != WORD_WRAP)
350 351
351#endif /* HAVE_WINDOW_SYSTEM */ 352#endif /* HAVE_WINDOW_SYSTEM */
352 353
354/* Test if the display element loaded in IT is a space or tab
355 character. This is used to determine word wrapping. */
356
357#define IT_DISPLAYING_WHITESPACE(it) \
358 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
359
353/* Non-nil means show the text cursor in void text areas 360/* Non-nil means show the text cursor in void text areas
354 i.e. in blank areas after eol and eob. This used to be 361 i.e. in blank areas after eol and eob. This used to be
355 the default in 21.3. */ 362 the default in 21.3. */
@@ -6664,7 +6671,7 @@ move_it_in_display_line_to (struct it *it,
6664{ 6671{
6665 enum move_it_result result = MOVE_UNDEFINED; 6672 enum move_it_result result = MOVE_UNDEFINED;
6666 struct glyph_row *saved_glyph_row; 6673 struct glyph_row *saved_glyph_row;
6667 struct it wrap_it, atpos_it; 6674 struct it wrap_it, atpos_it, atx_it;
6668 int may_wrap = 0; 6675 int may_wrap = 0;
6669 6676
6670 /* Don't produce glyphs in produce_glyphs. */ 6677 /* Don't produce glyphs in produce_glyphs. */
@@ -6672,11 +6679,13 @@ move_it_in_display_line_to (struct it *it,
6672 it->glyph_row = NULL; 6679 it->glyph_row = NULL;
6673 6680
6674 /* Use wrap_it to save a copy of IT wherever a word wrap could 6681 /* Use wrap_it to save a copy of IT wherever a word wrap could
6675 occur. Use atpos_it to save a copy of IT at the desired 6682 occur. Use atpos_it to save a copy of IT at the desired buffer
6676 position, if found, so that we can scan ahead and check if the 6683 position, if found, so that we can scan ahead and check if the
6677 word later overshoots the window edge. */ 6684 word later overshoots the window edge. Use atx_it similarly, for
6685 pixel positions. */
6678 wrap_it.sp = -1; 6686 wrap_it.sp = -1;
6679 atpos_it.sp = -1; 6687 atpos_it.sp = -1;
6688 atx_it.sp = -1;
6680 6689
6681#define BUFFER_POS_REACHED_P() \ 6690#define BUFFER_POS_REACHED_P() \
6682 ((op & MOVE_TO_POS) != 0 \ 6691 ((op & MOVE_TO_POS) != 0 \
@@ -6689,38 +6698,34 @@ move_it_in_display_line_to (struct it *it,
6689 /* If there's a line-/wrap-prefix, handle it. */ 6698 /* If there's a line-/wrap-prefix, handle it. */
6690 if (it->hpos == 0 && it->method == GET_FROM_BUFFER 6699 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
6691 && it->current_y < it->last_visible_y) 6700 && it->current_y < it->last_visible_y)
6692 { 6701 handle_line_prefix (it);
6693 handle_line_prefix (it);
6694 }
6695 6702
6696 while (1) 6703 while (1)
6697 { 6704 {
6698 int x, i, ascent = 0, descent = 0; 6705 int x, i, ascent = 0, descent = 0;
6699 6706
6700 /* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph). */ 6707/* Utility macro to reset an iterator with x, ascent, and descent. */
6708#define IT_RESET_X_ASCENT_DESCENT(IT) \
6709 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
6710 (IT)->max_descent = descent)
6711
6712 /* Stop if we move beyond TO_CHARPOS (after an image or stretch
6713 glyph). */
6701 if ((op & MOVE_TO_POS) != 0 6714 if ((op & MOVE_TO_POS) != 0
6702 && BUFFERP (it->object) 6715 && BUFFERP (it->object)
6703 && it->method == GET_FROM_BUFFER 6716 && it->method == GET_FROM_BUFFER
6704 && IT_CHARPOS (*it) > to_charpos) 6717 && IT_CHARPOS (*it) > to_charpos)
6705 { 6718 {
6706 if (it->line_wrap == WORD_WRAP) 6719 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
6707 {
6708 /* If wrap_it is valid, the current position might be in
6709 a word that is wrapped to the next line, so continue
6710 to see if that happens. */
6711 if (wrap_it.sp < 0)
6712 {
6713 result = MOVE_POS_MATCH_OR_ZV;
6714 break;
6715 }
6716 if (atpos_it.sp < 0)
6717 atpos_it = *it;
6718 }
6719 else
6720 { 6720 {
6721 result = MOVE_POS_MATCH_OR_ZV; 6721 result = MOVE_POS_MATCH_OR_ZV;
6722 break; 6722 break;
6723 } 6723 }
6724 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
6725 /* If wrap_it is valid, the current position might be in a
6726 word that is wrapped. So, save the iterator in
6727 atpos_it and continue to see if wrapping happens. */
6728 atpos_it = *it;
6724 } 6729 }
6725 6730
6726 /* Stop when ZV reached. 6731 /* Stop when ZV reached.
@@ -6743,31 +6748,39 @@ move_it_in_display_line_to (struct it *it,
6743 } 6748 }
6744 else 6749 else
6745 { 6750 {
6746 /* Remember the line height so far in case the next element
6747 doesn't fit on the line. */
6748 ascent = it->max_ascent;
6749 descent = it->max_descent;
6750
6751 if (it->line_wrap == WORD_WRAP) 6751 if (it->line_wrap == WORD_WRAP)
6752 { 6752 {
6753 if (it->what == IT_CHARACTER 6753 if (IT_DISPLAYING_WHITESPACE (it))
6754 && (it->c == ' ' || it->c == '\t'))
6755 may_wrap = 1; 6754 may_wrap = 1;
6756 else if (may_wrap) 6755 else if (may_wrap)
6757 { 6756 {
6758 /* We are done if the position is already found. */ 6757 /* We have reached a glyph that follows one or more
6758 whitespace characters. If the position is
6759 already found, we are done. */
6759 if (atpos_it.sp >= 0) 6760 if (atpos_it.sp >= 0)
6760 { 6761 {
6761 *it = atpos_it; 6762 *it = atpos_it;
6762 atpos_it.sp = -1; 6763 result = MOVE_POS_MATCH_OR_ZV;
6763 goto buffer_pos_reached; 6764 goto done;
6764 } 6765 }
6766 if (atx_it.sp >= 0)
6767 {
6768 *it = atx_it;
6769 result = MOVE_X_REACHED;
6770 goto done;
6771 }
6772 /* Otherwise, we can wrap here. */
6765 wrap_it = *it; 6773 wrap_it = *it;
6766 may_wrap = 0; 6774 may_wrap = 0;
6767 } 6775 }
6768 } 6776 }
6769 } 6777 }
6770 6778
6779 /* Remember the line height for the current line, in case
6780 the next element doesn't fit on the line. */
6781 ascent = it->max_ascent;
6782 descent = it->max_descent;
6783
6771 /* The call to produce_glyphs will get the metrics of the 6784 /* The call to produce_glyphs will get the metrics of the
6772 display element IT is loaded with. Record the x-position 6785 display element IT is loaded with. Record the x-position
6773 before this display element, in case it doesn't fit on the 6786 before this display element, in case it doesn't fit on the
@@ -6818,19 +6831,28 @@ move_it_in_display_line_to (struct it *it,
6818 { 6831 {
6819 if (BUFFER_POS_REACHED_P ()) 6832 if (BUFFER_POS_REACHED_P ())
6820 { 6833 {
6821 if (it->line_wrap == WORD_WRAP) 6834 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
6835 goto buffer_pos_reached;
6836 if (atpos_it.sp < 0)
6822 { 6837 {
6823 if (wrap_it.sp < 0) 6838 atpos_it = *it;
6824 goto buffer_pos_reached; 6839 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
6825 if (atpos_it.sp < 0) 6840 }
6826 atpos_it = *it; 6841 }
6842 else
6843 {
6844 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
6845 {
6846 it->current_x = x;
6847 result = MOVE_X_REACHED;
6848 break;
6849 }
6850 if (atx_it.sp < 0)
6851 {
6852 atx_it = *it;
6853 IT_RESET_X_ASCENT_DESCENT (&atx_it);
6827 } 6854 }
6828 else
6829 goto buffer_pos_reached;
6830 } 6855 }
6831 it->current_x = x;
6832 result = MOVE_X_REACHED;
6833 break;
6834 } 6856 }
6835 6857
6836 if (/* Lines are continued. */ 6858 if (/* Lines are continued. */
@@ -6860,10 +6882,21 @@ move_it_in_display_line_to (struct it *it,
6860 now that we know it fits in this row. */ 6882 now that we know it fits in this row. */
6861 if (BUFFER_POS_REACHED_P ()) 6883 if (BUFFER_POS_REACHED_P ())
6862 { 6884 {
6863 it->hpos = hpos_before_this_char; 6885 if (it->line_wrap != WORD_WRAP
6864 it->current_x = x_before_this_char; 6886 || wrap_it.sp < 0)
6865 result = MOVE_POS_MATCH_OR_ZV; 6887 {
6866 break; 6888 it->hpos = hpos_before_this_char;
6889 it->current_x = x_before_this_char;
6890 result = MOVE_POS_MATCH_OR_ZV;
6891 break;
6892 }
6893 if (it->line_wrap == WORD_WRAP
6894 && atpos_it.sp < 0)
6895 {
6896 atpos_it = *it;
6897 atpos_it.current_x = x_before_this_char;
6898 atpos_it.hpos = hpos_before_this_char;
6899 }
6867 } 6900 }
6868 6901
6869 set_iterator_to_next (it, 1); 6902 set_iterator_to_next (it, 1);
@@ -6893,16 +6926,13 @@ move_it_in_display_line_to (struct it *it,
6893 } 6926 }
6894 } 6927 }
6895 else 6928 else
6896 { 6929 IT_RESET_X_ASCENT_DESCENT (it);
6897 it->current_x = x;
6898 it->max_ascent = ascent;
6899 it->max_descent = descent;
6900 }
6901 6930
6902 if (wrap_it.sp >= 0) 6931 if (wrap_it.sp >= 0)
6903 { 6932 {
6904 *it = wrap_it; 6933 *it = wrap_it;
6905 atpos_it.sp = -1; 6934 atpos_it.sp = -1;
6935 atx_it.sp = -1;
6906 } 6936 }
6907 6937
6908 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n", 6938 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
@@ -6913,15 +6943,13 @@ move_it_in_display_line_to (struct it *it,
6913 6943
6914 if (BUFFER_POS_REACHED_P ()) 6944 if (BUFFER_POS_REACHED_P ())
6915 { 6945 {
6916 if (it->line_wrap == WORD_WRAP) 6946 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
6947 goto buffer_pos_reached;
6948 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
6917 { 6949 {
6918 if (wrap_it.sp < 0) 6950 atpos_it = *it;
6919 goto buffer_pos_reached; 6951 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
6920 if (atpos_it.sp < 0)
6921 atpos_it = *it;
6922 } 6952 }
6923 else
6924 goto buffer_pos_reached;
6925 } 6953 }
6926 6954
6927 if (new_x > it->first_visible_x) 6955 if (new_x > it->first_visible_x)
@@ -6938,9 +6966,7 @@ move_it_in_display_line_to (struct it *it,
6938 else if (BUFFER_POS_REACHED_P ()) 6966 else if (BUFFER_POS_REACHED_P ())
6939 { 6967 {
6940 buffer_pos_reached: 6968 buffer_pos_reached:
6941 it->current_x = x; 6969 IT_RESET_X_ASCENT_DESCENT (it);
6942 it->max_ascent = ascent;
6943 it->max_descent = descent;
6944 result = MOVE_POS_MATCH_OR_ZV; 6970 result = MOVE_POS_MATCH_OR_ZV;
6945 break; 6971 break;
6946 } 6972 }
@@ -6990,14 +7016,19 @@ move_it_in_display_line_to (struct it *it,
6990 result = MOVE_LINE_TRUNCATED; 7016 result = MOVE_LINE_TRUNCATED;
6991 break; 7017 break;
6992 } 7018 }
7019#undef IT_RESET_X_ASCENT_DESCENT
6993 } 7020 }
6994 7021
6995#undef BUFFER_POS_REACHED_P 7022#undef BUFFER_POS_REACHED_P
6996 7023
6997 /* If we scanned beyond to_pos and didn't find a point to wrap at, 7024 /* If we scanned beyond to_pos and didn't find a point to wrap at,
6998 return iterator at to_pos. */ 7025 restore the saved iterator. */
6999 if (atpos_it.sp >= 0) 7026 if (atpos_it.sp >= 0)
7000 *it = atpos_it; 7027 *it = atpos_it;
7028 else if (atx_it.sp >= 0)
7029 *it = atx_it;
7030
7031 done:
7001 7032
7002 /* Restore the iterator settings altered at the beginning of this 7033 /* Restore the iterator settings altered at the beginning of this
7003 function. */ 7034 function. */
@@ -16506,8 +16537,7 @@ display_line (it)
16506 16537
16507 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA) 16538 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
16508 { 16539 {
16509 if (it->what == IT_CHARACTER 16540 if (IT_DISPLAYING_WHITESPACE (it))
16510 && (it->c == ' ' || it->c == '\t'))
16511 may_wrap = 1; 16541 may_wrap = 1;
16512 else if (may_wrap) 16542 else if (may_wrap)
16513 { 16543 {
@@ -16604,6 +16634,18 @@ display_line (it)
16604 ++it->hpos; 16634 ++it->hpos;
16605 if (i == nglyphs - 1) 16635 if (i == nglyphs - 1)
16606 { 16636 {
16637 /* If line-wrap is on, check if a previous
16638 wrap point was found. */
16639 if (wrap_row_used > 0
16640 /* Even if there is a previous wrap
16641 point, continue the line here as
16642 usual, if (i) the previous character
16643 was a space or tab AND (ii) the
16644 current character is not. */
16645 && (!may_wrap
16646 || IT_DISPLAYING_WHITESPACE (it)))
16647 goto back_to_wrap;
16648
16607 set_iterator_to_next (it, 1); 16649 set_iterator_to_next (it, 1);
16608#ifdef HAVE_WINDOW_SYSTEM 16650#ifdef HAVE_WINDOW_SYSTEM
16609 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)) 16651 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
@@ -16622,8 +16664,6 @@ display_line (it)
16622 } 16664 }
16623 } 16665 }
16624#endif /* HAVE_WINDOW_SYSTEM */ 16666#endif /* HAVE_WINDOW_SYSTEM */
16625 if (wrap_row_used > 0)
16626 goto back_to_wrap;
16627 } 16667 }
16628 } 16668 }
16629 else if (CHAR_GLYPH_PADDING_P (*glyph) 16669 else if (CHAR_GLYPH_PADDING_P (*glyph)