Skip to content

Commit

Permalink
patch 9.0.2032: cannot get mouse click pos for tab or virt text
Browse files Browse the repository at this point in the history
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: #13335

Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
  • Loading branch information
zeertzjq authored and chrisbra committed Oct 15, 2023
1 parent 3c81f47 commit f5a94d5
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 14 deletions.
2 changes: 2 additions & 0 deletions runtime/doc/builtin.txt
Expand Up @@ -3928,6 +3928,8 @@ getmousepos() *getmousepos()*
wincol column inside "winid"
line text line inside "winid"
column text column inside "winid"
coladd offset (in screen columns) from the
start of the clicked char
All numbers are 1-based.

If not over a window, e.g. when in the command line, then only
Expand Down
2 changes: 1 addition & 1 deletion src/beval.c
Expand Up @@ -74,7 +74,7 @@ find_word_under_cursor(
}
}

col = vcol2col(wp, lnum, col);
col = vcol2col(wp, lnum, col, NULL);
scol = col;

if (VIsual_active
Expand Down
12 changes: 7 additions & 5 deletions src/mouse.c
Expand Up @@ -172,9 +172,7 @@ get_fpos_of_mouse(pos_T *mpos)
if (mouse_comp_pos(curwin, &row, &col, &mpos->lnum, NULL))
return IN_STATUS_LINE; // past bottom

mpos->col = vcol2col(wp, mpos->lnum, col);

mpos->coladd = 0;
mpos->col = vcol2col(wp, mpos->lnum, col, &mpos->coladd);
return IN_BUFFER;
}
#endif
Expand Down Expand Up @@ -3204,7 +3202,7 @@ mouse_find_win(int *rowp, int *colp, mouse_find_T popup UNUSED)
* The first column is zero.
*/
int
vcol2col(win_T *wp, linenr_T lnum, int vcol)
vcol2col(win_T *wp, linenr_T lnum, int vcol, colnr_T *coladdp)
{
char_u *line;
chartabsize_T cts;
Expand All @@ -3222,6 +3220,8 @@ vcol2col(win_T *wp, linenr_T lnum, int vcol)
}
clear_chartabsize_arg(&cts);

if (coladdp != NULL)
*coladdp = vcol - cts.cts_vcol;
return (int)(cts.cts_ptr - line);
}
#endif
Expand All @@ -3242,6 +3242,7 @@ f_getmousepos(typval_T *argvars UNUSED, typval_T *rettv)
varnumber_T wincol = 0;
linenr_T lnum = 0;
varnumber_T column = 0;
colnr_T coladd = 0;

if (rettv_dict_alloc(rettv) == FAIL)
return;
Expand Down Expand Up @@ -3275,7 +3276,7 @@ f_getmousepos(typval_T *argvars UNUSED, typval_T *rettv)
if (row >= 0 && row < wp->w_height && col >= 0 && col < wp->w_width)
{
(void)mouse_comp_pos(wp, &row, &col, &lnum, NULL);
col = vcol2col(wp, lnum, col);
col = vcol2col(wp, lnum, col, &coladd);
column = col + 1;
}
}
Expand All @@ -3285,5 +3286,6 @@ f_getmousepos(typval_T *argvars UNUSED, typval_T *rettv)
dict_add_number(d, "wincol", wincol);
dict_add_number(d, "line", (varnumber_T)lnum);
dict_add_number(d, "column", column);
dict_add_number(d, "coladd", coladd);
}
#endif
2 changes: 1 addition & 1 deletion src/move.c
Expand Up @@ -1547,7 +1547,7 @@ f_screenpos(typval_T *argvars UNUSED, typval_T *rettv)
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_u *line = ml_get_buf(wp->w_buffer, lnum, FALSE);
char_u *p = line + offset;

Expand Down
2 changes: 1 addition & 1 deletion src/proto/mouse.pro
Expand Up @@ -21,6 +21,6 @@ void reset_held_button(void);
int check_termcode_mouse(char_u *tp, int *slen, char_u *key_name, char_u *modifiers_start, int idx, int *modifiers);
int mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump, int *plines_cache);
win_T *mouse_find_win(int *rowp, int *colp, mouse_find_T popup);
int vcol2col(win_T *wp, linenr_T lnum, int vcol);
int vcol2col(win_T *wp, linenr_T lnum, int vcol, colnr_T *coladdp);
void f_getmousepos(typval_T *argvars, typval_T *rettv);
/* vim: set ft=c : */
31 changes: 31 additions & 0 deletions src/testdir/test_functions.vim
Expand Up @@ -3365,6 +3365,7 @@ func Test_getmousepos()
\ wincol: 1,
\ line: 1,
\ column: 1,
\ coladd: 0,
\ }, getmousepos())
call test_setmouse(1, 2)
call assert_equal(#{
Expand All @@ -3375,6 +3376,7 @@ func Test_getmousepos()
\ wincol: 2,
\ line: 1,
\ column: 1,
\ coladd: 1,
\ }, getmousepos())
call test_setmouse(1, 8)
call assert_equal(#{
Expand All @@ -3385,6 +3387,7 @@ func Test_getmousepos()
\ wincol: 8,
\ line: 1,
\ column: 1,
\ coladd: 7,
\ }, getmousepos())
call test_setmouse(1, 9)
call assert_equal(#{
Expand All @@ -3395,6 +3398,7 @@ func Test_getmousepos()
\ wincol: 9,
\ line: 1,
\ column: 2,
\ coladd: 0,
\ }, getmousepos())
call test_setmouse(1, 12)
call assert_equal(#{
Expand All @@ -3405,6 +3409,7 @@ func Test_getmousepos()
\ wincol: 12,
\ line: 1,
\ column: 2,
\ coladd: 3,
\ }, getmousepos())
call test_setmouse(1, 25)
call assert_equal(#{
Expand All @@ -3415,6 +3420,29 @@ func Test_getmousepos()
\ wincol: 25,
\ line: 1,
\ column: 4,
\ coladd: 0,
\ }, getmousepos())
call test_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 test_setmouse(1, 29)
call assert_equal(#{
\ screenrow: 1,
\ screencol: 29,
\ winid: win_getid(),
\ winrow: 1,
\ wincol: 29,
\ line: 1,
\ column: 8,
\ coladd: 0,
\ }, getmousepos())
call test_setmouse(1, 50)
call assert_equal(#{
Expand All @@ -3425,6 +3453,7 @@ func Test_getmousepos()
\ wincol: 50,
\ line: 1,
\ column: 8,
\ coladd: 21,
\ }, getmousepos())

" If the mouse is positioned past the last buffer line, "line" and "column"
Expand All @@ -3438,6 +3467,7 @@ func Test_getmousepos()
\ wincol: 25,
\ line: 1,
\ column: 4,
\ coladd: 0,
\ }, getmousepos())
call test_setmouse(2, 50)
call assert_equal(#{
Expand All @@ -3448,6 +3478,7 @@ func Test_getmousepos()
\ wincol: 50,
\ line: 1,
\ column: 8,
\ coladd: 21,
\ }, getmousepos())
bwipe!
endfunc
Expand Down
12 changes: 6 additions & 6 deletions src/testdir/test_popupwin.vim
Expand Up @@ -2671,21 +2671,21 @@ func Test_popupwin_filter_mouse()
eval a:tests->add(#{clickrow: a:row, clickcol: a:col, result: #{
\ screenrow: a:row, screencol: a:col,
\ winid: win_getid(), winrow: a:row, wincol: a:col,
\ line: a:row, column: a:col,
\ line: a:row, column: a:col, coladd: 0,
\ }})
endfunc
func AddItemInPopupBorder(tests, winid, row, col)
eval a:tests->add(#{clickrow: a:row, clickcol: a:col, result: #{
\ screenrow: a:row, screencol: a:col,
\ winid: a:winid, winrow: a:row - 1, wincol: a:col - 3,
\ line: 0, column: 0,
\ line: 0, column: 0, coladd: 0,
\ }})
endfunc
func AddItemInPopupText(tests, winid, row, col, textline, textcol)
func AddItemInPopupText(tests, winid, row, col, textline, textcol, coladd = 0)
eval a:tests->add(#{clickrow: a:row, clickcol: a:col, result: #{
\ screenrow: a:row, screencol: a:col,
\ winid: a:winid, winrow: a:row - 1, wincol: a:col - 3,
\ line: a:textline, column: a:textcol,
\ line: a:textline, column: a:textcol, coladd: a:coladd,
\ }})
endfunc

Expand Down Expand Up @@ -2717,7 +2717,7 @@ func Test_popupwin_filter_mouse()
call AddItemInPopupText(tests, winid, 4, 6, 1, 1)
call AddItemInPopupText(tests, winid, 4, 10, 1, 5)
call AddItemInPopupText(tests, winid, 4, 11, 1, 6)
call AddItemInPopupText(tests, winid, 4, 17, 1, 6)
call AddItemInPopupText(tests, winid, 4, 17, 1, 6, 6)
" text "long line th"
call AddItemInPopupText(tests, winid, 5, 6, 2, 1)
call AddItemInPopupText(tests, winid, 5, 10, 2, 5)
Expand All @@ -2730,7 +2730,7 @@ func Test_popupwin_filter_mouse()
call AddItemInPopupText(tests, winid, 7, 6, 3, 1)
call AddItemInPopupText(tests, winid, 7, 10, 3, 5)
call AddItemInPopupText(tests, winid, 7, 11, 3, 6)
call AddItemInPopupText(tests, winid, 7, 17, 3, 6)
call AddItemInPopupText(tests, winid, 7, 17, 3, 6, 6)

for item in tests
call test_setmouse(item.clickrow, item.clickcol)
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -704,6 +704,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2032,
/**/
2031,
/**/
Expand Down

0 comments on commit f5a94d5

Please sign in to comment.