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);
}