Bram,
I have lately worked with very narrow windows¹, and I noticed some 
problems (and even crashes).

1) Setting the foldcolumn might actually fill the complete window. E.g.
   can set fdc=12 and make the current window exactly 12 chars wide. So
   one has a window, that does not draw any text. Patch 
   check_fdc_width.diff fixes that
2) for very narrow window, nv_screengo might actually crash with a
   floating point exception. This is caused be width1 or width2 being 
   zero. Additionally, it might happen, that a tab might span several 
   screen lines and then using gk and gj do not work as expected. Patch 
   screengo.diff fixes those two errors.
3) I got a crash in windgoto(), because screen_cur_col was negative.
   Unfortunately I couldn't reproduce the problem and therefore I do not 
   know, how screen_cur_col could become negative (and I do not see from 
   the code how that could happen). So no fix for that problem.


¹) basically caused by trying to fix the problem reported by Dominique 
when the cursor movement was wrong. While fixing that, I noticed some 
more problems, that I report here. I'll post 2 patches for fixing those 
problems later, after I have tested them some more.

Best,
Christian
-- 
Dass man gerade nur denkt, wenn man das, worüber man denkt, 
nicht ausdenken kann!
                -- Goethe, Maximen und Reflektionen, Nr. 613

-- 
-- 
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/normal.c b/src/normal.c
--- a/src/normal.c
+++ b/src/normal.c
@@ -4408,6 +4408,7 @@ nv_screengo(oap, dir, dist)
     int		col_off2;	/* margin offset for wrapped screen line */
     int		width1;		/* text width for first screen line */
     int		width2;		/* test width for wrapped screen line */
+    pos_T	old_pos = curwin->w_cursor;
 
     oap->motion_type = MCHAR;
     oap->inclusive = (curwin->w_curswant == MAXCOL);
@@ -4417,6 +4418,11 @@ nv_screengo(oap, dir, dist)
     width1 = W_WIDTH(curwin) - col_off1;
     width2 = W_WIDTH(curwin) - col_off2;
 
+    if (width1 == 0)
+	width1 = 1;
+    if (width2 == 0)
+	width2 = 1;
+
 #ifdef FEAT_VERTSPLIT
     if (curwin->w_width != 0)
     {
@@ -4519,15 +4525,16 @@ nv_screengo(oap, dir, dist)
 #if defined(FEAT_LINEBREAK) || defined(FEAT_MBYTE)
     if (curwin->w_cursor.col > 0 && curwin->w_p_wrap)
     {
-	colnr_T virtcol;
+	colnr_T virtcol, virtcol2;
 
 	/*
 	 * Check for landing on a character that got split at the end of the
 	 * last line.  We want to advance a screenline, not end up in the same
 	 * screenline or move two screenlines.
+	 * (except for when e.g. a tab spans several screenlines)
 	 */
 	validate_virtcol();
-	virtcol = curwin->w_virtcol;
+	virtcol2 = virtcol = curwin->w_virtcol;
 # if defined(FEAT_LINEBREAK)
 	if (virtcol > (colnr_T)width1 && *p_sbr != NUL)
 	    virtcol -= vim_strsize(p_sbr);
@@ -4539,6 +4546,27 @@ nv_screengo(oap, dir, dist)
 		    : ((curwin->w_curswant - width1) % width2
 						      > (colnr_T)width2 / 2)))
 	    --curwin->w_cursor.col;
+	while (virtcol2 != curwin->w_curswant || equalpos(old_pos, curwin->w_cursor))
+	{
+	    int rc;
+	    if (atend)
+		curwin->w_curswant = (*mb_ptr2len)(ml_get_curline());
+	    if (dir == FORWARD)
+	    {
+		curwin->w_curswant++;
+		curwin->w_cursor.col++;
+	    }
+	    else
+	    {
+		curwin->w_curswant--;
+		curwin->w_cursor.col--;
+	    }
+	    rc = coladvance(curwin->w_curswant);
+	    validate_virtcol();
+	    if (rc == FAIL)
+		break;
+	    virtcol2 = curwin->w_virtcol;
+	}
     }
 #endif
 
diff --git a/src/option.c b/src/option.c
--- a/src/option.c
+++ b/src/option.c
@@ -8407,6 +8407,8 @@ set_num_option(opt_idx, varp, value, err
 	    errmsg = e_invarg;
 	    curwin->w_p_fdc = 12;
 	}
+	/* check window size */
+	check_fdc_width(curwin);
     }
 #endif /* FEAT_FOLDING */
 
@@ -12098,3 +12100,14 @@ get_bkc_value(buf)
 {
     return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
 }
+
+/*
+ * Check that the window is not completly covered by foldcolumns
+ */
+    void
+    check_fdc_width(wp)
+    win_T *wp;
+{
+    while (wp->w_p_fdc >= W_WIDTH(wp))
+	wp->w_p_fdc--;
+}
diff --git a/src/proto/option.pro b/src/proto/option.pro
--- a/src/proto/option.pro
+++ b/src/proto/option.pro
@@ -63,4 +63,5 @@ long get_sw_value __ARGS((buf_T *buf));
 long get_sts_value __ARGS((void));
 void find_mps_values __ARGS((int *initc, int *findc, int *backwards, int switchit));
 unsigned int get_bkc_value __ARGS((buf_T *buf));
+void check_fdc_width __ARGS((win_T *wp));
 /* vim: set ft=c : */
diff --git a/src/window.c b/src/window.c
--- a/src/window.c
+++ b/src/window.c
@@ -5285,6 +5285,10 @@ win_setwidth_win(width, wp)
     /* recompute the window positions */
     (void)win_comp_pos();
 
+#ifdef FEAT_FOLDING
+    check_fdc_width(wp);
+#endif
+
     redraw_all_later(NOT_VALID);
 }
 

Raspunde prin e-mail lui