vim-patch:9.0.2032: cannot get mouse click pos for tab or virt text (#25653)

Problem:  Cannot accurately get mouse clicking position when clicking on
          a TAB or with virtual text.
Solution: Add a "coladd" field to getmousepos() result.

closes: vim/vim#13335

f5a94d5165
This commit is contained in:
zeertzjq 2023-10-15 17:19:01 +08:00 committed by GitHub
parent a350fb2976
commit d974a3dcbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 59 additions and 10 deletions

View File

@ -2674,6 +2674,8 @@ getmousepos() *getmousepos()*
wincol column inside "winid" wincol column inside "winid"
line text line inside "winid" line text line inside "winid"
column text column inside "winid" column text column inside "winid"
coladd offset (in screen columns) from the
start of the clicked char
All numbers are 1-based. All numbers are 1-based.
If not over a window, e.g. when in the command line, then only If not over a window, e.g. when in the command line, then only

View File

@ -3242,6 +3242,8 @@ function vim.fn.getmatches(win) end
--- wincol column inside "winid" --- wincol column inside "winid"
--- line text line inside "winid" --- line text line inside "winid"
--- column text column inside "winid" --- column text column inside "winid"
--- coladd offset (in screen columns) from the
--- start of the clicked char
--- All numbers are 1-based. --- All numbers are 1-based.
--- ---
--- If not over a window, e.g. when in the command line, then only --- If not over a window, e.g. when in the command line, then only

View File

@ -4034,6 +4034,8 @@ M.funcs = {
wincol column inside "winid" wincol column inside "winid"
line text line inside "winid" line text line inside "winid"
column text column inside "winid" column text column inside "winid"
coladd offset (in screen columns) from the
start of the clicked char
All numbers are 1-based. All numbers are 1-based.
If not over a window, e.g. when in the command line, then only If not over a window, e.g. when in the command line, then only

View File

@ -243,9 +243,7 @@ static int get_fpos_of_mouse(pos_T *mpos)
return IN_UNKNOWN; return IN_UNKNOWN;
} }
mpos->col = vcol2col(wp, mpos->lnum, col); mpos->col = vcol2col(wp, mpos->lnum, col, &mpos->coladd);
mpos->coladd = 0;
return IN_BUFFER; return IN_BUFFER;
} }
@ -1755,8 +1753,8 @@ static win_T *mouse_find_grid_win(int *gridp, int *rowp, int *colp)
/// Convert a virtual (screen) column to a character column. /// Convert a virtual (screen) column to a character column.
/// The first column is zero. /// The first column is zero.
colnr_T vcol2col(win_T *const wp, const linenr_T lnum, const colnr_T vcol) colnr_T vcol2col(win_T *wp, linenr_T lnum, colnr_T vcol, colnr_T *coladdp)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
{ {
// try to advance to the specified column // try to advance to the specified column
char *line = ml_get_buf(wp->w_buffer, lnum); char *line = ml_get_buf(wp->w_buffer, lnum);
@ -1772,6 +1770,9 @@ colnr_T vcol2col(win_T *const wp, const linenr_T lnum, const colnr_T vcol)
} }
clear_chartabsize_arg(&cts); clear_chartabsize_arg(&cts);
if (coladdp != NULL) {
*coladdp = vcol - cts.cts_vcol;
}
return (colnr_T)(cts.cts_ptr - line); return (colnr_T)(cts.cts_ptr - line);
} }
@ -1927,6 +1928,7 @@ void f_getmousepos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
varnumber_T wincol = 0; varnumber_T wincol = 0;
linenr_T lnum = 0; linenr_T lnum = 0;
varnumber_T column = 0; varnumber_T column = 0;
colnr_T coladd = 0;
tv_dict_alloc_ret(rettv); tv_dict_alloc_ret(rettv);
dict_T *d = rettv->vval.v_dict; dict_T *d = rettv->vval.v_dict;
@ -1945,7 +1947,7 @@ void f_getmousepos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
wincol = col + 1 + wp->w_wincol_off; // Adjust by 1 for left border wincol = col + 1 + wp->w_wincol_off; // Adjust by 1 for left border
if (row >= 0 && row < wp->w_height && col >= 0 && col < wp->w_width) { if (row >= 0 && row < wp->w_height && col >= 0 && col < wp->w_width) {
(void)mouse_comp_pos(wp, &row, &col, &lnum); (void)mouse_comp_pos(wp, &row, &col, &lnum);
col = vcol2col(wp, lnum, col); col = vcol2col(wp, lnum, col, &coladd);
column = col + 1; column = col + 1;
} }
} }
@ -1955,4 +1957,5 @@ void f_getmousepos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
tv_dict_add_nr(d, S_LEN("wincol"), wincol); tv_dict_add_nr(d, S_LEN("wincol"), wincol);
tv_dict_add_nr(d, S_LEN("line"), (varnumber_T)lnum); tv_dict_add_nr(d, S_LEN("line"), (varnumber_T)lnum);
tv_dict_add_nr(d, S_LEN("column"), column); tv_dict_add_nr(d, S_LEN("column"), column);
tv_dict_add_nr(d, S_LEN("coladd"), coladd);
} }

View File

@ -1142,7 +1142,7 @@ void f_screenpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
/// returned. /// returned.
static int virtcol2col(win_T *wp, linenr_T lnum, int vcol) static int virtcol2col(win_T *wp, linenr_T lnum, int vcol)
{ {
int offset = vcol2col(wp, lnum, vcol - 1); int offset = vcol2col(wp, lnum, vcol - 1, NULL);
char *line = ml_get_buf(wp->w_buffer, lnum); char *line = ml_get_buf(wp->w_buffer, lnum);
char *p = line + offset; char *p = line + offset;

View File

@ -2155,13 +2155,14 @@ describe("folded lines", function()
meths.input_mouse('left', 'press', '', multigrid and 2 or 0, 4, 0) meths.input_mouse('left', 'press', '', multigrid and 2 or 0, 4, 0)
eq({ eq({
column = 1,
line = 3,
screencol = 1, screencol = 1,
screenrow = 5, screenrow = 5,
wincol = 1,
winid = 1000, winid = 1000,
wincol = 1,
winrow = 5, winrow = 5,
line = 3,
column = 1,
coladd = 0,
}, funcs.getmousepos()) }, funcs.getmousepos())
meths.buf_set_extmark(0, ns, 1, 0, { virt_lines = {{{"more virt_line below line 2", ""}}} }) meths.buf_set_extmark(0, ns, 1, 0, { virt_lines = {{{"more virt_line below line 2", ""}}} })

View File

@ -1717,6 +1717,7 @@ describe('ui/mouse/input', function()
eq(0, mousepos.wincol) eq(0, mousepos.wincol)
eq(0, mousepos.line) eq(0, mousepos.line)
eq(0, mousepos.column) eq(0, mousepos.column)
eq(0, mousepos.coladd)
end end
end end
end end
@ -1736,15 +1737,18 @@ describe('ui/mouse/input', function()
eq(win_col + 1, mousepos.wincol) eq(win_col + 1, mousepos.wincol)
local line = 0 local line = 0
local column = 0 local column = 0
local coladd = 0
if win_row > 0 and win_row < opts.height + 1 if win_row > 0 and win_row < opts.height + 1
and win_col > 0 and win_col < opts.width + 1 then and win_col > 0 and win_col < opts.width + 1 then
-- Because of border, win_row and win_col don't need to be -- Because of border, win_row and win_col don't need to be
-- incremented by 1. -- incremented by 1.
line = math.min(win_row, funcs.line('$')) line = math.min(win_row, funcs.line('$'))
column = math.min(win_col, #funcs.getline(line) + 1) column = math.min(win_col, #funcs.getline(line) + 1)
coladd = win_col - column
end end
eq(line, mousepos.line) eq(line, mousepos.line)
eq(column, mousepos.column) eq(column, mousepos.column)
eq(coladd, mousepos.coladd)
end end
end end
@ -1764,8 +1768,10 @@ describe('ui/mouse/input', function()
eq(win_col + 1, mousepos.wincol) eq(win_col + 1, mousepos.wincol)
local line = math.min(win_row + 1, funcs.line('$')) local line = math.min(win_row + 1, funcs.line('$'))
local column = math.min(win_col + 1, #funcs.getline(line) + 1) local column = math.min(win_col + 1, #funcs.getline(line) + 1)
local coladd = win_col + 1 - column
eq(line, mousepos.line) eq(line, mousepos.line)
eq(column, mousepos.column) eq(column, mousepos.column)
eq(coladd, mousepos.coladd)
end end
end end
@ -1788,8 +1794,10 @@ describe('ui/mouse/input', function()
eq(win_col + 1, mousepos.wincol) eq(win_col + 1, mousepos.wincol)
local line = math.min(win_row + 1, funcs.line('$')) local line = math.min(win_row + 1, funcs.line('$'))
local column = math.min(win_col + 1, #funcs.getline(line) + 1) local column = math.min(win_col + 1, #funcs.getline(line) + 1)
local coladd = win_col + 1 - column
eq(line, mousepos.line) eq(line, mousepos.line)
eq(column, mousepos.column) eq(column, mousepos.column)
eq(coladd, mousepos.coladd)
end end
end end
end end

View File

@ -3068,6 +3068,7 @@ func Test_getmousepos()
\ wincol: 1, \ wincol: 1,
\ line: 1, \ line: 1,
\ column: 1, \ column: 1,
\ coladd: 0,
\ }, getmousepos()) \ }, getmousepos())
call Ntest_setmouse(1, 2) call Ntest_setmouse(1, 2)
call assert_equal(#{ call assert_equal(#{
@ -3078,6 +3079,7 @@ func Test_getmousepos()
\ wincol: 2, \ wincol: 2,
\ line: 1, \ line: 1,
\ column: 1, \ column: 1,
\ coladd: 1,
\ }, getmousepos()) \ }, getmousepos())
call Ntest_setmouse(1, 8) call Ntest_setmouse(1, 8)
call assert_equal(#{ call assert_equal(#{
@ -3088,6 +3090,7 @@ func Test_getmousepos()
\ wincol: 8, \ wincol: 8,
\ line: 1, \ line: 1,
\ column: 1, \ column: 1,
\ coladd: 7,
\ }, getmousepos()) \ }, getmousepos())
call Ntest_setmouse(1, 9) call Ntest_setmouse(1, 9)
call assert_equal(#{ call assert_equal(#{
@ -3098,6 +3101,7 @@ func Test_getmousepos()
\ wincol: 9, \ wincol: 9,
\ line: 1, \ line: 1,
\ column: 2, \ column: 2,
\ coladd: 0,
\ }, getmousepos()) \ }, getmousepos())
call Ntest_setmouse(1, 12) call Ntest_setmouse(1, 12)
call assert_equal(#{ call assert_equal(#{
@ -3108,6 +3112,7 @@ func Test_getmousepos()
\ wincol: 12, \ wincol: 12,
\ line: 1, \ line: 1,
\ column: 2, \ column: 2,
\ coladd: 3,
\ }, getmousepos()) \ }, getmousepos())
call Ntest_setmouse(1, 25) call Ntest_setmouse(1, 25)
call assert_equal(#{ call assert_equal(#{
@ -3118,6 +3123,29 @@ func Test_getmousepos()
\ wincol: 25, \ wincol: 25,
\ line: 1, \ line: 1,
\ column: 4, \ column: 4,
\ coladd: 0,
\ }, getmousepos())
call Ntest_setmouse(1, 28)
call assert_equal(#{
\ screenrow: 1,
\ screencol: 28,
\ winid: win_getid(),
\ winrow: 1,
\ wincol: 28,
\ line: 1,
\ column: 7,
\ coladd: 0,
\ }, getmousepos())
call Ntest_setmouse(1, 29)
call assert_equal(#{
\ screenrow: 1,
\ screencol: 29,
\ winid: win_getid(),
\ winrow: 1,
\ wincol: 29,
\ line: 1,
\ column: 8,
\ coladd: 0,
\ }, getmousepos()) \ }, getmousepos())
call Ntest_setmouse(1, 50) call Ntest_setmouse(1, 50)
call assert_equal(#{ call assert_equal(#{
@ -3128,6 +3156,7 @@ func Test_getmousepos()
\ wincol: 50, \ wincol: 50,
\ line: 1, \ line: 1,
\ column: 8, \ column: 8,
\ coladd: 21,
\ }, getmousepos()) \ }, getmousepos())
" If the mouse is positioned past the last buffer line, "line" and "column" " If the mouse is positioned past the last buffer line, "line" and "column"
@ -3141,6 +3170,7 @@ func Test_getmousepos()
\ wincol: 25, \ wincol: 25,
\ line: 1, \ line: 1,
\ column: 4, \ column: 4,
\ coladd: 0,
\ }, getmousepos()) \ }, getmousepos())
call Ntest_setmouse(2, 50) call Ntest_setmouse(2, 50)
call assert_equal(#{ call assert_equal(#{
@ -3151,6 +3181,7 @@ func Test_getmousepos()
\ wincol: 50, \ wincol: 50,
\ line: 1, \ line: 1,
\ column: 8, \ column: 8,
\ coladd: 21,
\ }, getmousepos()) \ }, getmousepos())
bwipe! bwipe!
endfunc endfunc