From 6555176f34f102a8878a0bac55fd80459c943aa2 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 22 Sep 2023 05:44:45 +0800 Subject: [PATCH] vim-patch:9.0.1923: curswant wrong on click with 've' and 'nowrap' set (#25293) Problem: curswant wrong on click with 've' and 'nowrap' set Solution: Add w_leftcol to mouse click column. closes: vim/vim#13142 https://github.com/vim/vim/commit/db54e989b5cff3cc6442dfc500e3962cc1c0b6d0 --- src/nvim/drawline.c | 19 +++++---- src/nvim/grid_defs.h | 2 +- src/nvim/mouse.c | 12 +++--- test/old/testdir/test_virtualedit.vim | 55 +++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 73021d83a8..65c400299d 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -3024,14 +3024,17 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl linebuf_attr[wlv.off] = wlv.char_attr; } - linebuf_vcol[wlv.off] = wlv.vcol; - - if (wlv.draw_state == WL_FOLD) { - linebuf_vcol[wlv.off] = -2; + if (wlv.draw_state > WL_STC && wlv.filler_todo <= 0) { + linebuf_vcol[wlv.off] = wlv.vcol; + } else if (wlv.draw_state == WL_FOLD) { if (wlv.n_closing > 0) { linebuf_vcol[wlv.off] = -3; wlv.n_closing--; + } else { + linebuf_vcol[wlv.off] = -2; } + } else { + linebuf_vcol[wlv.off] = -1; } if (utf_char2cells(mb_c) > 1) { @@ -3041,17 +3044,19 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // UTF-8: Put a 0 in the second screen char. linebuf_char[wlv.off] = 0; linebuf_attr[wlv.off] = linebuf_attr[wlv.off - 1]; + if (wlv.draw_state > WL_STC && wlv.filler_todo <= 0) { - wlv.vcol++; + linebuf_vcol[wlv.off] = ++wlv.vcol; + } else { + linebuf_vcol[wlv.off] = -1; } + // When "wlv.tocol" is halfway through a character, set it to the end // of the character, otherwise highlighting won't stop. if (wlv.tocol == wlv.vcol) { wlv.tocol++; } - linebuf_vcol[wlv.off] = wlv.vcol; - if (wp->w_p_rl) { // now it's time to backup one cell wlv.off--; diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h index 207bf72816..100d648263 100644 --- a/src/nvim/grid_defs.h +++ b/src/nvim/grid_defs.h @@ -44,7 +44,7 @@ enum { /// attrs[] contains the highlighting attribute for each cell. /// /// vcols[] contains the virtual columns in the line. -1 means not available -/// (below last line), MAXCOL means after the end of the line. +/// or before buffer text, MAXCOL means after the end of the line. /// -2 or -3 means in fold column and a mouse click should: /// -2: open a fold /// -3: close a fold diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 33d7bc2e51..9b09a3fdf3 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1890,13 +1890,15 @@ static void mouse_check_grid(colnr_T *vcolp, int *flagsp) } colnr_T eol_vcol = gp->vcols[off_r]; assert(eol_vcol < MAXCOL); - // This may be -2 or -3 with 'foldcolumn' and empty line. - // In that case set it to -1 as it's just before start of line. - eol_vcol = MAX(eol_vcol, -1); + if (eol_vcol < 0) { + // Empty line or whole line before w_leftcol, + // with columns before buffer text + eol_vcol = wp->w_leftcol - 1; + } *vcolp = eol_vcol + (int)(off - off_r); } else { - // Clicking on an empty line - *vcolp = click_col - start_col; + // Empty line or whole line before w_leftcol + *vcolp = click_col - start_col + wp->w_leftcol; } } else if (col_from_screen >= 0) { // Use the virtual column from vcols[], it is accurate also after diff --git a/test/old/testdir/test_virtualedit.vim b/test/old/testdir/test_virtualedit.vim index 4c11fcd99e..4ab69d89fe 100644 --- a/test/old/testdir/test_virtualedit.vim +++ b/test/old/testdir/test_virtualedit.vim @@ -599,6 +599,61 @@ func Test_virtualedit_mouse() call feedkeys("\", "xt") call assert_equal([0, 1, 10, 2, 15], getcurpos()) + setlocal nowrap + call setline(2, repeat('a', 19)) + normal! j14zl + redraw + call Ntest_setmouse(row, 21 + 1) + call feedkeys("\", "xt") + call assert_equal([0, 1, 10, 2, 15], getcurpos()) + call Ntest_setmouse(row, 21 + 11) + call feedkeys("\", "xt") + call assert_equal([0, 1, 10, 12, 25], getcurpos()) + call Ntest_setmouse(row + 1, 21 + 1) + call feedkeys("\", "xt") + call assert_equal([0, 2, 15, 0, 15], getcurpos()) + call Ntest_setmouse(row + 1, 21 + 11) + call feedkeys("\", "xt") + call assert_equal([0, 2, 20, 5, 25], getcurpos()) + + setlocal number numberwidth=2 + redraw + call Ntest_setmouse(row, 21 + 3) + call feedkeys("\", "xt") + call assert_equal([0, 1, 10, 2, 15], getcurpos()) + call Ntest_setmouse(row, 21 + 13) + call feedkeys("\", "xt") + call assert_equal([0, 1, 10, 12, 25], getcurpos()) + call Ntest_setmouse(row + 1, 21 + 3) + call feedkeys("\", "xt") + call assert_equal([0, 2, 15, 0, 15], getcurpos()) + call Ntest_setmouse(row + 1, 21 + 13) + call feedkeys("\", "xt") + call assert_equal([0, 2, 20, 5, 25], getcurpos()) + setlocal nonumber + + if has('signs') + sign define Sign1 text=口 + sign place 1 name=Sign1 line=1 + sign place 2 name=Sign1 line=2 + redraw + call Ntest_setmouse(row, 21 + 3) + call feedkeys("\", "xt") + call assert_equal([0, 1, 10, 2, 15], getcurpos()) + call Ntest_setmouse(row, 21 + 13) + call feedkeys("\", "xt") + call assert_equal([0, 1, 10, 12, 25], getcurpos()) + call Ntest_setmouse(row + 1, 21 + 3) + call feedkeys("\", "xt") + call assert_equal([0, 2, 15, 0, 15], getcurpos()) + call Ntest_setmouse(row + 1, 21 + 13) + call feedkeys("\", "xt") + call assert_equal([0, 2, 20, 5, 25], getcurpos()) + sign unplace 1 + sign unplace 2 + sign undefine Sign1 + endif + bwipe! let &mouse = save_mouse set virtualedit&