summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/misc2.c12
-rw-r--r--src/normal.c17
-rw-r--r--src/testdir/test_normal.vim25
-rw-r--r--src/version.c2
4 files changed, 46 insertions, 10 deletions
diff --git a/src/misc2.c b/src/misc2.c
index da274e603..3261437db 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -119,10 +119,11 @@ getvpos(pos_T *pos, colnr_T wcol)
static int
coladvance2(
pos_T *pos,
- int addspaces, /* change the text to achieve our goal? */
- int finetune, /* change char offset for the exact column */
- colnr_T wcol) /* column to move to */
+ int addspaces, // change the text to achieve our goal?
+ int finetune, // change char offset for the exact column
+ colnr_T wcol_arg) // column to move to (can be negative)
{
+ colnr_T wcol = wcol_arg;
int idx;
char_u *ptr;
char_u *line;
@@ -136,7 +137,7 @@ coladvance2(
one_more = (State & INSERT)
|| restart_edit != NUL
|| (VIsual_active && *p_sel != 'o')
- || ((ve_flags & VE_ONEMORE) && wcol < MAXCOL) ;
+ || ((ve_flags & VE_ONEMORE) && wcol < MAXCOL);
line = ml_get_buf(curbuf, pos->lnum, FALSE);
if (wcol >= MAXCOL)
@@ -206,6 +207,7 @@ coladvance2(
if (virtual_active()
&& addspaces
+ && wcol >= 0
&& ((col != wcol && col != wcol + 1) || csize > 1))
{
/* 'virtualedit' is set: The difference between wcol and col is
@@ -305,7 +307,7 @@ coladvance2(
if (has_mbyte)
mb_adjustpos(curbuf, pos);
- if (col < wcol)
+ if (wcol < 0 || col < wcol)
return FAIL;
return OK;
}
diff --git a/src/normal.c b/src/normal.c
index 1fddeae07..50f7b3185 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -2499,17 +2499,18 @@ nv_screengo(oparg_T *oap, int dir, long dist)
n = ((linelen - width1 - 1) / width2 + 1) * width2 + width1;
else
n = width1;
- if (curwin->w_curswant > (colnr_T)n + 1)
- curwin->w_curswant -= ((curwin->w_curswant - n) / width2 + 1)
- * width2;
+ if (curwin->w_curswant >= (colnr_T)n)
+ curwin->w_curswant = n - 1;
}
while (dist--)
{
if (dir == BACKWARD)
{
- if ((long)curwin->w_curswant > width2)
- // move back within line
+ if ((long)curwin->w_curswant >= width1)
+ // Move back within the line. This can give a negative value
+ // for w_curswant if width1 < width2 (with cpoptions+=n),
+ // which will get clipped to column 0.
curwin->w_curswant -= width2;
else
{
@@ -2557,6 +2558,12 @@ nv_screengo(oparg_T *oap, int dir, long dist)
}
curwin->w_cursor.lnum++;
curwin->w_curswant %= width2;
+ // Check if the cursor has moved below the number display
+ // when width1 < width2 (with cpoptions+=n). Subtract width2
+ // to get a negative value for w_curswant, which will get
+ // clipped to column 0.
+ if (curwin->w_curswant >= width1)
+ curwin->w_curswant -= width2;
linelen = linetabsize(ml_get_curline());
}
}
diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim
index dcfa929c8..da9c004a8 100644
--- a/src/testdir/test_normal.vim
+++ b/src/testdir/test_normal.vim
@@ -2654,4 +2654,29 @@ func Test_normal_gk()
call assert_equal(95, virtcol('.'))
bw!
bw!
+
+ " needs 80 column new window
+ new
+ vert 80new
+ set number
+ set numberwidth=10
+ set cpoptions+=n
+ put =[repeat('0',90), repeat('1',90)]
+ norm! 075l
+ call assert_equal(76, col('.'))
+ norm! gk
+ call assert_equal(1, col('.'))
+ norm! gk
+ call assert_equal(76, col('.'))
+ norm! gk
+ call assert_equal(1, col('.'))
+ norm! gj
+ call assert_equal(76, col('.'))
+ norm! gj
+ call assert_equal(1, col('.'))
+ norm! gj
+ call assert_equal(76, col('.'))
+ bw!
+ bw!
+ set cpoptions& number& numberwidth&
endfunc
diff --git a/src/version.c b/src/version.c
index 87b3a3399..2ddecaf03 100644
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2140,
+/**/
2139,
/**/
2138,