aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-03-17 07:26:39 +0800
committerGitHub <noreply@github.com>2024-03-17 07:26:39 +0800
commitd114dbe9f79c1382298b04319b7ded88e95e3ee8 (patch)
treea3ed5239b72332bef8e42afa2b9ba095c74d7afe
parent34b57508a78b0a980e898ee35d950db0a90368ca (diff)
downloadrneovim-d114dbe9f79c1382298b04319b7ded88e95e3ee8.tar.gz
rneovim-d114dbe9f79c1382298b04319b7ded88e95e3ee8.tar.bz2
rneovim-d114dbe9f79c1382298b04319b7ded88e95e3ee8.zip
vim-patch:9.1.0184: Cursor pos wrong when clicking with conceal and wrap (#27890)
Problem: Cursor position wrong when clicking with conceal and wrap. Solution: Use the virtual column of the last char for ScreenCols[] in boguscols. Remove use of MAXCOL in ScreenCols[]. Rename third argument of wlv_screen_line() to "clear_end" as that's clearer what it does (zeertzjq). related: 14192 closes: vim/vim#14200 https://github.com/vim/vim/commit/d0c1b7723f7e73763597af2f97a53d94ab7ed020 Rename win_put_linebuf() to wlv_put_linebuf().
-rw-r--r--src/nvim/drawline.c34
-rw-r--r--src/nvim/grid.c45
-rw-r--r--src/nvim/grid.h8
-rw-r--r--src/nvim/mouse.c28
-rw-r--r--test/old/testdir/test_conceal.vim180
5 files changed, 170 insertions, 125 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index ffe2253cf1..816eb8a674 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -300,6 +300,7 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
if (vt->pos == kVPosEndOfLine && do_eol) {
state->eol_col = col + 1;
}
+ // TODO(zeertzjq): set values in linebuf_vcol[]
*end_col = MAX(*end_col, col);
}
if (!vt || !(vt->flags & kVTRepeatLinebreak)) {
@@ -1549,7 +1550,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
// When only updating the columns and that's done, stop here.
if (col_rows > 0) {
- win_put_linebuf(wp, wlv.row, wlv.off, wlv.off, bg_attr, false);
+ wlv_put_linebuf(wp, &wlv, wlv.off, false, bg_attr, 0);
// Need to update more screen lines if:
// - 'statuscolumn' needs to be drawn, or
// - LineNrAbove or LineNrBelow is used, or
@@ -1606,7 +1607,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
&& lnum == wp->w_cursor.lnum && wlv.vcol >= wp->w_virtcol) {
draw_virt_text(wp, buf, win_col_offset, &wlv.col, wlv.row);
// don't clear anything after wlv.col
- win_put_linebuf(wp, wlv.row, wlv.col, wlv.col, bg_attr, false);
+ wlv_put_linebuf(wp, &wlv, wlv.col, false, bg_attr, 0);
// Pretend we have finished updating the window. Except when
// 'cursorcolumn' is set.
if (wp->w_p_cuc) {
@@ -2539,7 +2540,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
: wlv.char_attr;
linebuf_attr[wlv.off] = eol_attr;
- linebuf_vcol[wlv.off] = MAXCOL;
+ linebuf_vcol[wlv.off] = wlv.vcol;
wlv.col++;
wlv.off++;
wlv.vcol++;
@@ -2595,7 +2596,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
while (wlv.col < grid->cols) {
linebuf_char[wlv.off] = schar_from_ascii(' ');
- linebuf_vcol[wlv.off] = MAXCOL;
+ linebuf_vcol[wlv.off] = wlv.vcol;
wlv.col++;
advance_color_col(&wlv, vcol_hlc(wlv));
@@ -2638,7 +2639,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
draw_virt_text_item(buf, win_col_offset, fold_vt, kHlModeCombine, grid->cols, 0);
}
draw_virt_text(wp, buf, win_col_offset, &wlv.col, wlv.row);
- win_put_linebuf(wp, wlv.row, wlv.col, grid->cols, bg_attr, false);
+ // Set increasing virtual columns in grid->vcols[] to set correct curswant
+ // (or "coladd" for 'virtualedit') when clicking after end of line.
+ wlv_put_linebuf(wp, &wlv, wlv.col, true, bg_attr, SLF_INC_VCOL);
wlv.row++;
// Update w_cline_height and w_cline_folded if the cursor line was
@@ -2869,7 +2872,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
while (draw_col < grid->cols) {
linebuf_char[wlv.off] = schar_from_char(' ');
linebuf_attr[wlv.off] = attr;
- linebuf_vcol[wlv.off] = MAXCOL; // TODO(zeertzjq): this is wrong
+ linebuf_vcol[wlv.off] = wlv.vcol - 1;
wlv.off++;
draw_col++;
}
@@ -2882,7 +2885,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
draw_virt_text(wp, buf, win_col_offset, &draw_col, wlv.row);
}
- win_put_linebuf(wp, wlv.row, draw_col, grid->cols, bg_attr, wrap);
+ wlv_put_linebuf(wp, &wlv, draw_col, true, bg_attr, wrap ? SLF_WRAP : 0);
if (wrap) {
ScreenGrid *current_grid = grid;
int current_row = wlv.row;
@@ -2942,18 +2945,28 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
return wlv.row;
}
-static void win_put_linebuf(win_T *wp, int row, int endcol, int clear_width, int bg_attr, bool wrap)
+/// Call grid_put_linebuf() using values from "wlv".
+/// Also takes care of putting "<<<" on the first line for 'smoothscroll'
+/// when 'showbreak' is not set.
+///
+/// @param clear_end clear until the end of the screen line.
+/// @param flags for grid_put_linebuf(), but shouldn't contain SLF_RIGHTLEFT.
+static void wlv_put_linebuf(win_T *wp, const winlinevars_T *wlv, int endcol, bool clear_end,
+ int bg_attr, int flags)
{
ScreenGrid *grid = &wp->w_grid;
int startcol = 0;
+ int clear_width = clear_end ? grid->cols : endcol;
+ assert(!(flags & SLF_RIGHTLEFT));
if (wp->w_p_rl) {
linebuf_mirror(&startcol, &endcol, &clear_width, grid->cols);
+ flags |= SLF_RIGHTLEFT;
}
// Take care of putting "<<<" on the first line for 'smoothscroll'.
- if (row == 0 && wp->w_skipcol > 0
+ if (wlv->row == 0 && wp->w_skipcol > 0
// do not overwrite the 'showbreak' text with "<<<"
&& *get_showbreak_value(wp) == NUL
// do not overwrite the 'listchars' "precedes" text with "<<<"
@@ -2978,7 +2991,8 @@ static void win_put_linebuf(win_T *wp, int row, int endcol, int clear_width, int
}
}
+ int row = wlv->row;
int coloff = 0;
grid_adjust(&grid, &row, &coloff);
- grid_put_linebuf(grid, row, coloff, startcol, endcol, clear_width, wp->w_p_rl, bg_attr, wrap);
+ grid_put_linebuf(grid, row, coloff, startcol, endcol, clear_width, bg_attr, wlv->vcol - 1, flags);
}
diff --git a/src/nvim/grid.c b/src/nvim/grid.c
index e386853022..e911e6ad21 100644
--- a/src/nvim/grid.c
+++ b/src/nvim/grid.c
@@ -1,3 +1,6 @@
+// Low-level functions to manipulate individual character cells on the
+// screen grid.
+//
// Most of the routines in this file perform screen (grid) manipulations. The
// given operation is performed physically on the screen. The corresponding
// change is also made to the internal screen image. In this way, the editor
@@ -338,7 +341,7 @@ static int grid_line_first = INT_MAX;
static int grid_line_last = 0;
static int grid_line_clear_to = 0;
static int grid_line_clear_attr = 0;
-static bool grid_line_rl = false;
+static int grid_line_flags = 0;
/// Start a group of grid_line_puts calls that builds a single grid line.
///
@@ -358,7 +361,7 @@ void grid_line_start(ScreenGrid *grid, int row)
grid_line_last = 0;
grid_line_clear_to = 0;
grid_line_clear_attr = 0;
- grid_line_rl = false;
+ grid_line_flags = 0;
assert((size_t)grid_line_maxcol <= linebuf_size);
@@ -515,7 +518,7 @@ void grid_line_mirror(void)
return;
}
linebuf_mirror(&grid_line_first, &grid_line_last, &grid_line_clear_to, grid_line_maxcol);
- grid_line_rl = true;
+ grid_line_flags |= SLF_RIGHTLEFT;
}
void linebuf_mirror(int *firstp, int *lastp, int *clearp, int maxcol)
@@ -568,7 +571,7 @@ void grid_line_flush(void)
}
grid_put_linebuf(grid, grid_line_row, grid_line_coloff, grid_line_first, grid_line_last,
- grid_line_clear_to, grid_line_rl, grid_line_clear_attr, false);
+ grid_line_clear_to, grid_line_clear_attr, -1, grid_line_flags);
}
/// flush grid line but only if on a valid row
@@ -619,17 +622,21 @@ static int grid_char_needs_redraw(ScreenGrid *grid, int col, size_t off_to, int
/// Move one buffered line to the window grid, but only the characters that
/// have actually changed. Handle insert/delete character.
-/// "coloff" gives the first column on the grid for this line.
-/// "endcol" gives the columns where valid characters are.
-/// "clear_width" is the width of the window. It's > 0 if the rest of the line
-/// needs to be cleared, negative otherwise.
-/// "rl" is true for rightleft text, like a window with 'rightleft' option set
-/// When true and "clear_width" > 0, clear columns 0 to "endcol"
-/// When false and "clear_width" > 0, clear columns "endcol" to "clear_width"
-/// If "wrap" is true, then hint to the UI that "row" contains a line
-/// which has wrapped into the next row.
+///
+/// @param coloff gives the first column on the grid for this line.
+/// @param endcol gives the columns where valid characters are.
+/// @param clear_width see SLF_RIGHTLEFT.
+/// @param flags can have bits:
+/// - SLF_RIGHTLEFT rightleft text, like a window with 'rightleft' option set:
+/// - When false, clear columns "endcol" to "clear_width".
+/// - When true, clear columns "col" to "endcol".
+/// - SLF_WRAP hint to UI that "row" contains a line wrapped into the next row.
+/// - SLF_INC_VCOL:
+/// - When false, use "last_vcol" for grid->vcols[] of the columns to clear.
+/// - When true, use an increasing sequence starting from "last_vcol + 1" for
+/// grid->vcols[] of the columns to clear.
void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol, int clear_width,
- bool rl, int bg_attr, bool wrap)
+ int bg_attr, colnr_T last_vcol, int flags)
{
bool redraw_next; // redraw_this for next character
bool clear_next = false;
@@ -659,7 +666,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
}
int clear_start = endcol;
- if (rl) {
+ if (flags & SLF_RIGHTLEFT) {
clear_start = col;
col = endcol;
endcol = clear_width;
@@ -758,17 +765,17 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
}
clear_end = col + 1;
}
- grid->vcols[off] = MAXCOL;
+ grid->vcols[off] = (flags & SLF_INC_VCOL) ? ++last_vcol : last_vcol;
col++;
}
- if (rl && start_dirty != -1 && clear_dirty_start != -1) {
+ if ((flags & SLF_RIGHTLEFT) && start_dirty != -1 && clear_dirty_start != -1) {
if (grid->throttled || clear_dirty_start >= start_dirty - 5) {
// cannot draw now or too small to be worth a separate "clear" event
start_dirty = clear_dirty_start;
} else {
ui_line(grid, row, invalid_row, coloff + clear_dirty_start, coloff + clear_dirty_start,
- coloff + clear_end, bg_attr, wrap);
+ coloff + clear_end, bg_attr, flags & SLF_WRAP);
}
clear_end = end_dirty;
} else {
@@ -785,7 +792,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
if (clear_end > start_dirty) {
if (!grid->throttled) {
ui_line(grid, row, invalid_row, coloff + start_dirty, coloff + end_dirty, coloff + clear_end,
- bg_attr, wrap);
+ bg_attr, flags & SLF_WRAP);
} else if (grid->dirty_col) {
// TODO(bfredl): really get rid of the extra pseudo terminal in message.c
// by using a linebuf_char copy for "throttled message line"
diff --git a/src/nvim/grid.h b/src/nvim/grid.h
index 7506f0fc9d..25144cdc2c 100644
--- a/src/nvim/grid.h
+++ b/src/nvim/grid.h
@@ -27,8 +27,12 @@ EXTERN sattr_T *linebuf_attr INIT( = NULL);
EXTERN colnr_T *linebuf_vcol INIT( = NULL);
EXTERN char *linebuf_scratch INIT( = NULL);
-// Low-level functions to manipulate individual character cells on the
-// screen grid.
+/// flags for grid_put_linebuf()
+enum {
+ SLF_RIGHTLEFT = 1,
+ SLF_WRAP = 2,
+ SLF_INC_VCOL = 4,
+};
/// Put a ASCII character in a screen cell.
///
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c
index d82ba58918..a2b4042f30 100644
--- a/src/nvim/mouse.c
+++ b/src/nvim/mouse.c
@@ -1883,33 +1883,7 @@ static void mouse_check_grid(colnr_T *vcolp, int *flagsp)
const size_t off = gp->line_offset[click_row] + (size_t)click_col;
colnr_T col_from_screen = gp->vcols[off];
- if (col_from_screen == MAXCOL) {
- // When clicking after end of line, still need to set correct curswant
- size_t off_l = gp->line_offset[click_row] + (size_t)start_col;
- if (gp->vcols[off_l] < MAXCOL) {
- // Binary search to find last char in line
- size_t off_r = off;
- while (off_l < off_r) {
- size_t off_m = (off_l + off_r + 1) / 2;
- if (gp->vcols[off_m] < MAXCOL) {
- off_l = off_m;
- } else {
- off_r = off_m - 1;
- }
- }
- colnr_T eol_vcol = gp->vcols[off_r];
- assert(eol_vcol < MAXCOL);
- if (eol_vcol < 0) {
- // Empty line or whole line before w_leftcol,
- // with columns before buffer text
- eol_vcol = curwin->w_leftcol - 1;
- }
- *vcolp = eol_vcol + (int)(off - off_r);
- } else {
- // Empty line or whole line before w_leftcol
- *vcolp = click_col - start_col + curwin->w_leftcol;
- }
- } else if (col_from_screen >= 0) {
+ if (col_from_screen >= 0) {
// Use the virtual column from vcols[], it is accurate also after
// concealed characters.
*vcolp = col_from_screen;
diff --git a/test/old/testdir/test_conceal.vim b/test/old/testdir/test_conceal.vim
index 52b0661f85..a03ec21e79 100644
--- a/test/old/testdir/test_conceal.vim
+++ b/test/old/testdir/test_conceal.vim
@@ -387,77 +387,123 @@ func Test_conceal_eol()
endfunc
func Test_conceal_mouse_click()
- enew!
+ call NewWindow(10, 40)
set mouse=a
setlocal conceallevel=2 concealcursor=nc
syn match Concealed "this" conceal
hi link Concealed Search
- call setline(1, 'conceal this click here')
- redraw
- call assert_equal(['conceal click here '], ScreenLines(1, 20))
-
- " click on the space between "this" and "click" puts cursor there
- call Ntest_setmouse(1, 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, 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, 19)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 23, 0, 23], getcurpos())
- " click after end of line puts cursor on 'e' without 'virtualedit'
- call Ntest_setmouse(1, 20)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 23, 0, 24], getcurpos())
- call Ntest_setmouse(1, 21)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 23, 0, 25], getcurpos())
- call Ntest_setmouse(1, 22)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 23, 0, 26], getcurpos())
- call Ntest_setmouse(1, 31)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 23, 0, 35], getcurpos())
- call Ntest_setmouse(1, 32)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 23, 0, 36], getcurpos())
-
- set virtualedit=all
- redraw
- " click on the space between "this" and "click" puts cursor there
- call Ntest_setmouse(1, 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, 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, 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, 20)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 24, 0, 24], getcurpos())
- call Ntest_setmouse(1, 21)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 24, 1, 25], getcurpos())
- call Ntest_setmouse(1, 22)
- call feedkeys("\<LeftMouse>", "tx")
- call assert_equal([0, 1, 24, 2, 26], getcurpos())
- 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())
-
- bwipe!
- set mouse& virtualedit&
+
+ " Test with both 'nocursorline' and 'cursorline', as they use two different
+ " code paths to set virtual columns for the cells to clear.
+ for cul in [v:false, v:true]
+ let &l:cursorline = cul
+
+ call setline(1, 'conceal this click here')
+ call assert_equal([
+ \ 'conceal click here ',
+ \ ], ScreenLines(1, 40))
+
+ " Click on the space between "this" and "click" puts cursor there.
+ call Ntest_setmouse(1, 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, 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, 19)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 23], getcurpos())
+ " Click after end of line puts cursor on 'e' without 'virtualedit'.
+ call Ntest_setmouse(1, 20)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 24], getcurpos())
+ call Ntest_setmouse(1, 21)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 25], getcurpos())
+ call Ntest_setmouse(1, 22)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 26], getcurpos())
+ call Ntest_setmouse(1, 31)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 35], getcurpos())
+ call Ntest_setmouse(1, 32)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 23, 0, 36], getcurpos())
+
+ set virtualedit=all
+ redraw
+ " Click on the space between "this" and "click" puts cursor there.
+ call Ntest_setmouse(1, 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, 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, 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, 20)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 0, 24], getcurpos())
+ call Ntest_setmouse(1, 21)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 1, 25], getcurpos())
+ call Ntest_setmouse(1, 22)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 24, 2, 26], getcurpos())
+ 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())
+ set virtualedit&
+
+ " Test with a wrapped line.
+ call setline(1, ['conceal this click here']->repeat(3)->join())
+ call assert_equal([
+ \ 'conceal click here conceal cli ',
+ \ 'ck here conceal click here ',
+ \ ], ScreenLines([1, 2], 40))
+ " Click on boguscols puts cursor on the last char of a screen line.
+ for col in range(33, 40)
+ call Ntest_setmouse(1, col)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 40, 0, 40], getcurpos())
+ endfor
+
+ " Also test with the last char of a screen line concealed.
+ setlocal number signcolumn=yes
+ call assert_equal([
+ \ ' 1 conceal click here conceal ',
+ \ ' click here conceal click h ',
+ \ ' ere ',
+ \ ], ScreenLines([1, 3], 40))
+ call Ntest_setmouse(1, 34)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 32, 0, 32], getcurpos())
+ call Ntest_setmouse(2, 7)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 37, 0, 37], getcurpos())
+ " Click on boguscols puts cursor on the last char of a screen line.
+ for col in range(35, 40)
+ call Ntest_setmouse(1, col)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 34, 0, 34], getcurpos())
+ call Ntest_setmouse(2, col)
+ call feedkeys("\<LeftMouse>", "tx")
+ call assert_equal([0, 1, 68, 0, 68], getcurpos())
+ endfor
+ setlocal number& signcolumn&
+ endfor
+
+ call CloseWindow()
+ set mouse&
endfunc
" Test that cursor is drawn at the correct column when it is after end of the