aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-03-18 10:35:41 +0800
committerGitHub <noreply@github.com>2024-03-18 10:35:41 +0800
commit9d315fb8b728355e8f1872f783b1ae9948e4fd9b (patch)
treed29bafc234075e6b7c7e451d9667fb8808c71f1d
parenteabf9de1dc8c8eeb8246491a0e389b5f9a5fde97 (diff)
downloadrneovim-9d315fb8b728355e8f1872f783b1ae9948e4fd9b.tar.gz
rneovim-9d315fb8b728355e8f1872f783b1ae9948e4fd9b.tar.bz2
rneovim-9d315fb8b728355e8f1872f783b1ae9948e4fd9b.zip
vim-patch:9.1.0186: cursor pos wrong on mouse click after eol with 'rl', 've' and conceal (#27903)
Problem: Wrong cursor position when clicking after end of line with 'rightleft', 'virtualedit' and conceal. Solution: Set values in ScreenCols[] also with SLF_RIGHTLEFT. Also fix off-by-one cursor position with 'colorcolumn' (zeertzjq). closes: vim/vim#14218 https://github.com/vim/vim/commit/deb2204bffa075ed5485415fc2dbd20e75d87ea4
-rw-r--r--src/nvim/drawline.c5
-rw-r--r--src/nvim/grid.c14
-rw-r--r--src/nvim/grid_defs.h2
-rw-r--r--test/old/testdir/test_conceal.vim47
4 files changed, 60 insertions, 8 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index cbe586d103..869fcdf7c0 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -2621,12 +2621,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
// linebuf_vcol[] already filled by the for loop above
wlv.off++;
wlv.col++;
+ wlv.vcol++;
- if (vcol_hlc(wlv) >= rightmost_vcol) {
+ if (vcol_hlc(wlv) > rightmost_vcol) {
break;
}
-
- wlv.vcol++;
}
}
diff --git a/src/nvim/grid.c b/src/nvim/grid.c
index e911e6ad21..f51cdc478a 100644
--- a/src/nvim/grid.c
+++ b/src/nvim/grid.c
@@ -750,10 +750,15 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
}
int clear_dirty_start = -1, clear_end = -1;
+ if (flags & SLF_RIGHTLEFT) {
+ for (col = clear_width - 1; col >= clear_start; col--) {
+ size_t off = off_to + (size_t)col;
+ grid->vcols[off] = (flags & SLF_INC_VCOL) ? ++last_vcol : last_vcol;
+ }
+ }
// blank out the rest of the line
// TODO(bfredl): we could cache winline widths
- col = clear_start;
- while (col < clear_width) {
+ for (col = clear_start; col < clear_width; col++) {
size_t off = off_to + (size_t)col;
if (grid->chars[off] != schar_from_ascii(' ')
|| grid->attrs[off] != bg_attr
@@ -765,8 +770,9 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
}
clear_end = col + 1;
}
- grid->vcols[off] = (flags & SLF_INC_VCOL) ? ++last_vcol : last_vcol;
- col++;
+ if (!(flags & SLF_RIGHTLEFT)) {
+ grid->vcols[off] = (flags & SLF_INC_VCOL) ? ++last_vcol : last_vcol;
+ }
}
if ((flags & SLF_RIGHTLEFT) && start_dirty != -1 && clear_dirty_start != -1) {
diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h
index 10a6161171..ac67f42fe0 100644
--- a/src/nvim/grid_defs.h
+++ b/src/nvim/grid_defs.h
@@ -37,7 +37,7 @@ enum {
/// attrs[] contains the highlighting attribute for each cell.
///
/// vcols[] contains the virtual columns in the line. -1 means not available
-/// or before buffer text, MAXCOL means after the end of the line.
+/// or before buffer text.
/// -2 or -3 means in fold column and a mouse click should:
/// -2: open a fold
/// -3: close a fold
diff --git a/test/old/testdir/test_conceal.vim b/test/old/testdir/test_conceal.vim
index a03ec21e79..84b931f39d 100644
--- a/test/old/testdir/test_conceal.vim
+++ b/test/old/testdir/test_conceal.vim
@@ -462,6 +462,53 @@ func Test_conceal_mouse_click()
call Ntest_setmouse(1, 32)
call feedkeys("\<LeftMouse>", "tx")
call assert_equal([0, 1, 24, 12, 36], getcurpos())
+ " Behavior should also be the same with 'colorcolumn'.
+ setlocal colorcolumn=30
+ redraw
+ call Ntest_setmouse(1, 31)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 11, 35], getcurpos())
+ call Ntest_setmouse(1, 32)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 12, 36], getcurpos())
+ setlocal colorcolumn&
+
+ if has('rightleft')
+ setlocal rightleft
+ call assert_equal([
+ \ ' ereh kcilc laecnoc',
+ \ ], ScreenLines(1, 40))
+ " Click on the space between "this" and "click" puts cursor there.
+ call Ntest_setmouse(1, 41 - 9)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 13, 0, 13], getcurpos())
+ " Click on 'h' of "here" puts cursor there.
+ call Ntest_setmouse(1, 41 - 16)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 20, 0, 20], getcurpos())
+ " Click on 'e' of "here" puts cursor there.
+ call Ntest_setmouse(1, 41 - 19)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 23], getcurpos())
+ " Click after end of line puts cursor there with 'virtualedit'.
+ call Ntest_setmouse(1, 41 - 20)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 0, 24], getcurpos())
+ call Ntest_setmouse(1, 41 - 21)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 1, 25], getcurpos())
+ call Ntest_setmouse(1, 41 - 22)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 2, 26], getcurpos())
+ call Ntest_setmouse(1, 41 - 31)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 11, 35], getcurpos())
+ call Ntest_setmouse(1, 41 - 32)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 12, 36], getcurpos())
+ setlocal rightleft&
+ endif
+
set virtualedit&
" Test with a wrapped line.