Hi Dominique!

On Fr, 26 Dez 2014, Dominique Pellé wrote:

> On Fri, Dec 26, 2014 at 2:37 PM, Christian Brabandt <[email protected]> 
> wrote:
> > Hi Dominique!
> >
> > On Fr, 26 Dez 2014, Dominique Pellé wrote:
> >
> >> Sorry for the noise.  My latest patch does not fix it.
> >> I had been testing vim small, which does not have
> >> showbreak so it did not show the bug <sigh>
> >> The bug is still present in vim huge with my patch
> >> or with your latest patch, at least when doing:
> >>
> >> $ vim -u NONE -c 'set nu cpo= sbr=: co=49' bug-vim.txt
> >>
> >> And press A in command mode to append
> >> char at the end of the line and see that cursor is
> >> incorrectly positionned.
> >
> > Oh, that happens because the last TAB char at the previous line is drawn
> > too long. Here is an updated patch.
> 
> It's not an easy bug to fix :-(

Yes, the screen drawing code is complex and I think you have now found 
another problem, that is actually not caused by that but by the 
win_lbr_chartabsize function.

> It's still broken with your latest patch using...

I come to the conclusion, this is a different problem, that is 
independent of the problem you reported initially. The problem with the 
screen size of 49 is actually, that Vim does not consider, the 
numberwidth option and thinks the second last tab would not wrap, while 
it does.

The screen drawing code is independent of this, and does take this into 
account (and therefore my previous patch was wrong, because the screen 
drawing code does in fact take the length of the 'sbr' into account and 
adjusts the length of a tab correctly, and therefore, my last attempt 
fixed this special case, but the general case was broken, as you pointed 
out in your last message)

Therefore I think we have observed two different problems that need to 
be fixed. Part one is the wrong drawing of the length of a tab as 
pointed in your initial mail (patch sbr_buf_new.diff), part two is the 
wrong calculation of the column position and therefore not taking into 
account that wrapping will actually happen. This is fixed by the patch
win_lbr_chartabsize_numberwidth.diff. That function is unfortunately 
called a lot and I hope, this patch does not brake at other parts of the 
code).

> 
> $ vim -u NONE -c 'set nu cpo= sbr=: co=90' bug-vim.txt
> 
> It's also broken with:
> 
> $ vim -u NONE -c 'set sbr=: co=84' bug-vim.txt
> 
> Then press A in command mode and cursor gets beyond
> the end of line.

That is the general case and should now again work as expected again.

I have checked will all your 4 provided test cases and it looks good so 
far. However you have successfully found many different problems with 
different screen sizes so you might want to check, that this works as 
well.

I'll copy vim-dev. Once you verified, that it works for you correctly, 
I'll try to create some test cases that catch at least those two 
problems.

Best,
Christian
-- 
Die höchste Liebe glaubt und fordert höchste Vollkommenheit, daher ist
sie ihrem Ende am nächsten.
                -- Jean Paul

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/screen.c b/src/screen.c
--- a/src/screen.c
+++ b/src/screen.c
@@ -2842,6 +2842,9 @@ win_line(wp, lnum, startrow, endrow, noc
     unsigned	off;			/* offset in ScreenLines/ScreenAttrs */
     int		c = 0;			/* init for GCC */
     long	vcol = 0;		/* virtual column (for tabs) */
+#ifdef FEAT_LINEBREAK
+    long	vcol_sbr = 0;		/* virtual column after showbreak */
+#endif
     long	vcol_prev = -1;		/* "vcol" of previous character */
     char_u	*line;			/* current line */
     char_u	*ptr;			/* current position in "line" */
@@ -3759,6 +3762,7 @@ win_line(wp, lnum, startrow, endrow, noc
 		    n_extra = (int)STRLEN(p_sbr);
 		    char_attr = hl_attr(HLF_AT);
 		    need_showbreak = FALSE;
+		    vcol_sbr = vcol + MB_CHARLEN(p_sbr);
 		    /* Correct end of highlighted area for 'showbreak',
 		     * required when 'linebreak' is also set. */
 		    if (tocol == vcol)
@@ -4516,9 +4520,17 @@ win_line(wp, lnum, startrow, endrow, noc
 		if (c == TAB && (!wp->w_p_list || lcs_tab1))
 		{
 		    int tab_len = 0;
+		    long vcol_adjusted = vcol; /* removed showbreak length */
+#ifdef FEAT_LINEBREAK
+		    /* only adjust the tab_len, when at the first column
+		     * after the showbreak value was drawn */
+		    if (*p_sbr != NUL && vcol == vcol_sbr && wp->w_p_wrap)
+			vcol_adjusted = vcol - MB_CHARLEN(p_sbr);
+#endif
 		    /* tab amount depends on current column */
 		    tab_len = (int)wp->w_buffer->b_p_ts
-					- vcol % (int)wp->w_buffer->b_p_ts - 1;
+					- vcol_adjusted % (int)wp->w_buffer->b_p_ts - 1;
+
 #ifdef FEAT_LINEBREAK
 		    if (!wp->w_p_lbr || !wp->w_p_list)
 #endif
diff --git a/src/charset.c b/src/charset.c
--- a/src/charset.c
+++ b/src/charset.c
@@ -1182,6 +1182,7 @@ win_lbr_chartabsize(wp, line, s, col, he
 	col += numberextra + mb_added;
 	if (col >= (colnr_T)W_WIDTH(wp))
 	{
+	    int numberwidth = numberextra;
 	    col -= W_WIDTH(wp);
 	    numberextra = W_WIDTH(wp) - (numberextra - win_col_off2(wp));
 	    if (numberextra > 0)
@@ -1192,8 +1193,10 @@ win_lbr_chartabsize(wp, line, s, col, he
 		if (col >= sbrlen)
 		    col -= sbrlen;
 	    }
-	    if (numberextra > 0)
+	    if (col >= numberextra && numberextra > 0)
 		col = col % numberextra;
+	    else if (numberextra > 0)
+		col += numberwidth - win_col_off2(wp);
 	}
 	if (col == 0 || col + size > (colnr_T)W_WIDTH(wp))
 	{

Raspunde prin e-mail lui