Subject: Re: bug#2749: 23.0.91; Visual Line Mode: incorrect line wrapping in corner case

From: Stephen Berman <[email-masked]>
Date: Fri, 10 May 2013 16:01:22 +0200

On Mon, 18 Feb 2013 12:31:10 +0100 Stephen Berman <[email-masked]> wrote:

> On Tue, 24 Mar 2009 21:35:02 -0400 Stefan Monnier <[email-masked]> wrote:
>
>>> This behavior is expected.  The word wrap algorithm treats lines that
>>> are too long to wrap using the ordinary line-wrapping rules, and since
>>> overflow-newline-into-fringe is disabled in Visual Line mode, the extra
>>> empty line is used to show the non-overflowed newline character.
>>
>>> After the release, I might look into letting word wrap handle
>>> overflow-newline-into-fringe behavior.  I suspect, however, that this
>>> may lead to confusing results in some circumstances.
>>
>> BTW: why is overflow-newline-into-fringe ignored when word-wrap is
>> non-nil?  What kind of confusing results are you thinking of?
>
> I would like to use a string of length window-width in a display overlay
> together with word-wrap and a non-nil wrap-prefix.  Currently this
> results in a following empty line with indentation, which is rather
> disconcerting.  But after removing `&& (IT)->line_wrap != WORD_WRAP'
> from the definition of IT_OVERFLOW_NEWLINE_INTO_FRINGE and rebuilding
> Emacs, the empty indented line is gone and I have just what I want.  I
> haven't yet seen anything confusing.  So I too would be very interested
> to know if there are known or suspected problems with allowing non-nil
> overflow-newline-into-fringe with word-wrap.  If it's not clear there
> are any, could we allow it and then see if anyone screams bloody murder?

I've been using Emacs as described above (i.e., with the patch below)
and till today have had no problems, but I just bumped into one, which
is indeed confusing, even pretty nasty.  I've reproduced it with -Q on a
fresh build from the latest trunk (with the patch added).  I don't know
how to debug it, but I will describe how to reproduce it, in the hope
that someone can fix it (or at least give me some help in trying to
debug it) and then hopefully overflow-newline-into-fringe can be allowed
in Visual Line mode.

Here's the recipe:

-1. Apply the following patch and rebuild Emacs:

*** /home/steve/bzr/emacs/trunk/src/xdisp.c	2013-05-10 12:51:51.000000000 +0200
--- /home/steve/bzr/emacs/quickfixes/src/xdisp.c	2013-05-10 14:56:22.000000000 +0200
***************
*** 378,385 ****
     && ((IT)->bidi_it.paragraph_dir == R2L		\
         ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0)	\
         : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0))	\
!    && (IT)->current_x == (IT)->last_visible_x		\
!    && (IT)->line_wrap != WORD_WRAP)
  
  #else /* !HAVE_WINDOW_SYSTEM */
  #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
--- 378,384 ----
     && ((IT)->bidi_it.paragraph_dir == R2L		\
         ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0)	\
         : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0))	\
!    && (IT)->current_x == (IT)->last_visible_x)
  
  #else /* !HAVE_WINDOW_SYSTEM */
  #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0

0. emacs -Q
1. Type `C-u 69 x SPC C-u 10 x' to make a string of 69 x's followed by a
   space followed by a string of 10 x's; point should be in the fringe.
2. Type `RET C-u 69 x RET C-u 69 x' to add two more lines 69 x's long
   (this is not essential to show the bug but helps in describing its
   effects).
3. M-x visual-line-mode; now the string of 10 x's in the first line has
   wrapped to occupy its own visual line below the first string of x's,
   i.e., you see a line of 69 x's followed by a line of 10 x's followed
   by two more lines of 69 x's.
4. If you click with the mouse (which button doesn't matter, but mouse-1
   is least intrusive) anywhere in the buffer up to and including the
   space following the last x in the first line of x's, point is set
   where you click, as usual.
Now come the confusing results.
5. If you click with the mouse on the first column after the space at
   the end of the first line of x's, point is set on the first x of the
   following word-wrap line; if you click on the second column after the
   space, point is set on the second x below, and so on up to the fringe
   in the first line of x's.
6. If you click with the mouse on any position starting with the first x
   in the second, visual, line (the word-wrapped line), point is set one
   line below in the same column.  The goes for all following lines in
   the buffer, even if not word-wrapped (actually, with further
   word-wrapping below the first word-wrapped line, I've seen point
   being set two lines below, but it's harder to reproduce that).
7. If you put point (using the keyboard, whose events are not effected
   by this bug) somewhere on the second line of 69 x's (the one just
   below the word-wrapped line of 10 x's) and then type `C-l' twice to
   move that line to the top of the window, now clicking with the mouse
   anywhere on this line or lower again correctly sets point where you
   click.  If you scroll vertically so that the word-wrapped line is
   again visible in the window, the point setting problem happens again.
8. If you add one character to the first line of x's, thus making its
   (unwrapped) length longer than window-width, the point setting
   problem does not happen.