mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-23 04:53:12 -08:00
(IT_OVERFLOW_NEWLINE_INTO_FRINGE): Turn it off if word-wrapping.
(IT_DISPLAYING_WHITESPACE): New macro. (move_it_in_display_line_to): Handle MOVE_TO_X requests properly when word-wrapping. Simplify word-wrapping logic. Use correct pixel positions when saving copies of the iterator. (display_line): Use proper wrap point if the last character on a line was preceded by whitespace.
This commit is contained in:
parent
59230395e9
commit
4636d4bd84
1 changed files with 108 additions and 68 deletions
176
src/xdisp.c
176
src/xdisp.c
|
|
@ -346,10 +346,17 @@ extern Lisp_Object Voverflow_newline_into_fringe;
|
|||
(!NILP (Voverflow_newline_into_fringe) \
|
||||
&& FRAME_WINDOW_P (it->f) \
|
||||
&& WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
|
||||
&& it->current_x == it->last_visible_x)
|
||||
&& it->current_x == it->last_visible_x \
|
||||
&& it->line_wrap != WORD_WRAP)
|
||||
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
|
||||
/* Test if the display element loaded in IT is a space or tab
|
||||
character. This is used to determine word wrapping. */
|
||||
|
||||
#define IT_DISPLAYING_WHITESPACE(it) \
|
||||
(it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
|
||||
|
||||
/* Non-nil means show the text cursor in void text areas
|
||||
i.e. in blank areas after eol and eob. This used to be
|
||||
the default in 21.3. */
|
||||
|
|
@ -6664,7 +6671,7 @@ move_it_in_display_line_to (struct it *it,
|
|||
{
|
||||
enum move_it_result result = MOVE_UNDEFINED;
|
||||
struct glyph_row *saved_glyph_row;
|
||||
struct it wrap_it, atpos_it;
|
||||
struct it wrap_it, atpos_it, atx_it;
|
||||
int may_wrap = 0;
|
||||
|
||||
/* Don't produce glyphs in produce_glyphs. */
|
||||
|
|
@ -6672,11 +6679,13 @@ move_it_in_display_line_to (struct it *it,
|
|||
it->glyph_row = NULL;
|
||||
|
||||
/* Use wrap_it to save a copy of IT wherever a word wrap could
|
||||
occur. Use atpos_it to save a copy of IT at the desired
|
||||
occur. Use atpos_it to save a copy of IT at the desired buffer
|
||||
position, if found, so that we can scan ahead and check if the
|
||||
word later overshoots the window edge. */
|
||||
word later overshoots the window edge. Use atx_it similarly, for
|
||||
pixel positions. */
|
||||
wrap_it.sp = -1;
|
||||
atpos_it.sp = -1;
|
||||
atx_it.sp = -1;
|
||||
|
||||
#define BUFFER_POS_REACHED_P() \
|
||||
((op & MOVE_TO_POS) != 0 \
|
||||
|
|
@ -6689,38 +6698,34 @@ move_it_in_display_line_to (struct it *it,
|
|||
/* If there's a line-/wrap-prefix, handle it. */
|
||||
if (it->hpos == 0 && it->method == GET_FROM_BUFFER
|
||||
&& it->current_y < it->last_visible_y)
|
||||
{
|
||||
handle_line_prefix (it);
|
||||
}
|
||||
handle_line_prefix (it);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int x, i, ascent = 0, descent = 0;
|
||||
|
||||
/* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph). */
|
||||
/* Utility macro to reset an iterator with x, ascent, and descent. */
|
||||
#define IT_RESET_X_ASCENT_DESCENT(IT) \
|
||||
((IT)->current_x = x, (IT)->max_ascent = ascent, \
|
||||
(IT)->max_descent = descent)
|
||||
|
||||
/* Stop if we move beyond TO_CHARPOS (after an image or stretch
|
||||
glyph). */
|
||||
if ((op & MOVE_TO_POS) != 0
|
||||
&& BUFFERP (it->object)
|
||||
&& it->method == GET_FROM_BUFFER
|
||||
&& IT_CHARPOS (*it) > to_charpos)
|
||||
{
|
||||
if (it->line_wrap == WORD_WRAP)
|
||||
{
|
||||
/* If wrap_it is valid, the current position might be in
|
||||
a word that is wrapped to the next line, so continue
|
||||
to see if that happens. */
|
||||
if (wrap_it.sp < 0)
|
||||
{
|
||||
result = MOVE_POS_MATCH_OR_ZV;
|
||||
break;
|
||||
}
|
||||
if (atpos_it.sp < 0)
|
||||
atpos_it = *it;
|
||||
}
|
||||
else
|
||||
if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
|
||||
{
|
||||
result = MOVE_POS_MATCH_OR_ZV;
|
||||
break;
|
||||
}
|
||||
else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
|
||||
/* If wrap_it is valid, the current position might be in a
|
||||
word that is wrapped. So, save the iterator in
|
||||
atpos_it and continue to see if wrapping happens. */
|
||||
atpos_it = *it;
|
||||
}
|
||||
|
||||
/* Stop when ZV reached.
|
||||
|
|
@ -6743,31 +6748,39 @@ move_it_in_display_line_to (struct it *it,
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Remember the line height so far in case the next element
|
||||
doesn't fit on the line. */
|
||||
ascent = it->max_ascent;
|
||||
descent = it->max_descent;
|
||||
|
||||
if (it->line_wrap == WORD_WRAP)
|
||||
{
|
||||
if (it->what == IT_CHARACTER
|
||||
&& (it->c == ' ' || it->c == '\t'))
|
||||
if (IT_DISPLAYING_WHITESPACE (it))
|
||||
may_wrap = 1;
|
||||
else if (may_wrap)
|
||||
{
|
||||
/* We are done if the position is already found. */
|
||||
/* We have reached a glyph that follows one or more
|
||||
whitespace characters. If the position is
|
||||
already found, we are done. */
|
||||
if (atpos_it.sp >= 0)
|
||||
{
|
||||
*it = atpos_it;
|
||||
atpos_it.sp = -1;
|
||||
goto buffer_pos_reached;
|
||||
result = MOVE_POS_MATCH_OR_ZV;
|
||||
goto done;
|
||||
}
|
||||
if (atx_it.sp >= 0)
|
||||
{
|
||||
*it = atx_it;
|
||||
result = MOVE_X_REACHED;
|
||||
goto done;
|
||||
}
|
||||
/* Otherwise, we can wrap here. */
|
||||
wrap_it = *it;
|
||||
may_wrap = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remember the line height for the current line, in case
|
||||
the next element doesn't fit on the line. */
|
||||
ascent = it->max_ascent;
|
||||
descent = it->max_descent;
|
||||
|
||||
/* The call to produce_glyphs will get the metrics of the
|
||||
display element IT is loaded with. Record the x-position
|
||||
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,
|
|||
{
|
||||
if (BUFFER_POS_REACHED_P ())
|
||||
{
|
||||
if (it->line_wrap == WORD_WRAP)
|
||||
{
|
||||
if (wrap_it.sp < 0)
|
||||
goto buffer_pos_reached;
|
||||
if (atpos_it.sp < 0)
|
||||
atpos_it = *it;
|
||||
}
|
||||
else
|
||||
if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
|
||||
goto buffer_pos_reached;
|
||||
if (atpos_it.sp < 0)
|
||||
{
|
||||
atpos_it = *it;
|
||||
IT_RESET_X_ASCENT_DESCENT (&atpos_it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
|
||||
{
|
||||
it->current_x = x;
|
||||
result = MOVE_X_REACHED;
|
||||
break;
|
||||
}
|
||||
if (atx_it.sp < 0)
|
||||
{
|
||||
atx_it = *it;
|
||||
IT_RESET_X_ASCENT_DESCENT (&atx_it);
|
||||
}
|
||||
}
|
||||
it->current_x = x;
|
||||
result = MOVE_X_REACHED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (/* Lines are continued. */
|
||||
|
|
@ -6860,10 +6882,21 @@ move_it_in_display_line_to (struct it *it,
|
|||
now that we know it fits in this row. */
|
||||
if (BUFFER_POS_REACHED_P ())
|
||||
{
|
||||
it->hpos = hpos_before_this_char;
|
||||
it->current_x = x_before_this_char;
|
||||
result = MOVE_POS_MATCH_OR_ZV;
|
||||
break;
|
||||
if (it->line_wrap != WORD_WRAP
|
||||
|| wrap_it.sp < 0)
|
||||
{
|
||||
it->hpos = hpos_before_this_char;
|
||||
it->current_x = x_before_this_char;
|
||||
result = MOVE_POS_MATCH_OR_ZV;
|
||||
break;
|
||||
}
|
||||
if (it->line_wrap == WORD_WRAP
|
||||
&& atpos_it.sp < 0)
|
||||
{
|
||||
atpos_it = *it;
|
||||
atpos_it.current_x = x_before_this_char;
|
||||
atpos_it.hpos = hpos_before_this_char;
|
||||
}
|
||||
}
|
||||
|
||||
set_iterator_to_next (it, 1);
|
||||
|
|
@ -6893,16 +6926,13 @@ move_it_in_display_line_to (struct it *it,
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
it->current_x = x;
|
||||
it->max_ascent = ascent;
|
||||
it->max_descent = descent;
|
||||
}
|
||||
IT_RESET_X_ASCENT_DESCENT (it);
|
||||
|
||||
if (wrap_it.sp >= 0)
|
||||
{
|
||||
*it = wrap_it;
|
||||
atpos_it.sp = -1;
|
||||
atx_it.sp = -1;
|
||||
}
|
||||
|
||||
TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
|
||||
|
|
@ -6913,15 +6943,13 @@ move_it_in_display_line_to (struct it *it,
|
|||
|
||||
if (BUFFER_POS_REACHED_P ())
|
||||
{
|
||||
if (it->line_wrap == WORD_WRAP)
|
||||
{
|
||||
if (wrap_it.sp < 0)
|
||||
goto buffer_pos_reached;
|
||||
if (atpos_it.sp < 0)
|
||||
atpos_it = *it;
|
||||
}
|
||||
else
|
||||
if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
|
||||
goto buffer_pos_reached;
|
||||
if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
|
||||
{
|
||||
atpos_it = *it;
|
||||
IT_RESET_X_ASCENT_DESCENT (&atpos_it);
|
||||
}
|
||||
}
|
||||
|
||||
if (new_x > it->first_visible_x)
|
||||
|
|
@ -6938,9 +6966,7 @@ move_it_in_display_line_to (struct it *it,
|
|||
else if (BUFFER_POS_REACHED_P ())
|
||||
{
|
||||
buffer_pos_reached:
|
||||
it->current_x = x;
|
||||
it->max_ascent = ascent;
|
||||
it->max_descent = descent;
|
||||
IT_RESET_X_ASCENT_DESCENT (it);
|
||||
result = MOVE_POS_MATCH_OR_ZV;
|
||||
break;
|
||||
}
|
||||
|
|
@ -6990,14 +7016,19 @@ move_it_in_display_line_to (struct it *it,
|
|||
result = MOVE_LINE_TRUNCATED;
|
||||
break;
|
||||
}
|
||||
#undef IT_RESET_X_ASCENT_DESCENT
|
||||
}
|
||||
|
||||
#undef BUFFER_POS_REACHED_P
|
||||
|
||||
/* If we scanned beyond to_pos and didn't find a point to wrap at,
|
||||
return iterator at to_pos. */
|
||||
restore the saved iterator. */
|
||||
if (atpos_it.sp >= 0)
|
||||
*it = atpos_it;
|
||||
else if (atx_it.sp >= 0)
|
||||
*it = atx_it;
|
||||
|
||||
done:
|
||||
|
||||
/* Restore the iterator settings altered at the beginning of this
|
||||
function. */
|
||||
|
|
@ -16506,8 +16537,7 @@ display_line (it)
|
|||
|
||||
if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
|
||||
{
|
||||
if (it->what == IT_CHARACTER
|
||||
&& (it->c == ' ' || it->c == '\t'))
|
||||
if (IT_DISPLAYING_WHITESPACE (it))
|
||||
may_wrap = 1;
|
||||
else if (may_wrap)
|
||||
{
|
||||
|
|
@ -16604,6 +16634,18 @@ display_line (it)
|
|||
++it->hpos;
|
||||
if (i == nglyphs - 1)
|
||||
{
|
||||
/* If line-wrap is on, check if a previous
|
||||
wrap point was found. */
|
||||
if (wrap_row_used > 0
|
||||
/* Even if there is a previous wrap
|
||||
point, continue the line here as
|
||||
usual, if (i) the previous character
|
||||
was a space or tab AND (ii) the
|
||||
current character is not. */
|
||||
&& (!may_wrap
|
||||
|| IT_DISPLAYING_WHITESPACE (it)))
|
||||
goto back_to_wrap;
|
||||
|
||||
set_iterator_to_next (it, 1);
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
|
||||
|
|
@ -16622,8 +16664,6 @@ display_line (it)
|
|||
}
|
||||
}
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
if (wrap_row_used > 0)
|
||||
goto back_to_wrap;
|
||||
}
|
||||
}
|
||||
else if (CHAR_GLYPH_PADDING_P (*glyph)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue