Mercurial > vim
changeset 18291:11f68eb58fda v8.1.2140
patch 8.1.2140: "gk" and "gj" do not work correctly in number column
Commit: https://github.com/vim/vim/commit/ceba3dd5187788e09f65bd41b07b40f6f9aab953
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Oct 12 16:12:54 2019 +0200
patch 8.1.2140: "gk" and "gj" do not work correctly in number column
Problem: "gk" and "gj" do not work correctly in number column.
Solution: Allow for a negative "curswant". (Zach Wegner, closes https://github.com/vim/vim/issues/4969)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 12 Oct 2019 16:15:03 +0200 |
parents | b31d3745f179 |
children | d10f337d9fd3 |
files | src/misc2.c src/normal.c src/testdir/test_normal.vim src/version.c |
diffstat | 4 files changed, 46 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- 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; }
--- a/src/normal.c +++ b/src/normal.c @@ -2499,17 +2499,18 @@ nv_screengo(oparg_T *oap, int dir, long 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 } 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()); } }
--- 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