vim-patch:8.1.2304: cannot get the mouse position when getting a mouse click

Problem:    Cannot get the mouse position when getting a mouse click.
Solution:   Add getmousepos().
db3a205147
This commit is contained in:
Daniel Steinberg 2021-06-29 17:55:54 -04:00
parent ec4731d982
commit 3b9e75b366
4 changed files with 83 additions and 1 deletions

View File

@ -2431,6 +2431,7 @@ getloclist({nr}) List list of location list items
getloclist({nr}, {what}) Dict get specific location list properties
getmarklist([{buf}]) List list of global/local marks
getmatches([{win}]) List list of current matches
getmousepos() Dict last known mouse position
getpid() Number process ID of Vim
getpos({expr}) List position of cursor, mark, etc.
getqflist() List list of quickfix items
@ -4709,7 +4710,8 @@ getchar([expr]) *getchar()*
When the user clicks a mouse button, the mouse event will be
returned. The position can then be found in |v:mouse_col|,
|v:mouse_lnum|, |v:mouse_winid| and |v:mouse_win|.
Mouse move events will be ignored.
|getmousepos()| can also be used. Mouse move events will be
ignored.
This example positions the mouse as it would normally happen: >
let c = getchar()
if c == "\<LeftMouse>" && v:mouse_win > 0
@ -5099,6 +5101,36 @@ getmatches([{win}]) *getmatches()*
'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
:unlet m
<
getmousepos() *getmousepos()*
Returns a Dictionary with the last known position of the
mouse. This can be used in a mapping for a mouse click. The
items are:
screenrow screen row
screencol screen column
winid Window ID of the click
winrow row inside "winid"
wincol column inside "winid"
line text line inside "winid"
column text column inside "winid"
All numbers are 1-based.
If not over a window, e.g. when in the command line, then only
"screenrow" and "screencol" are valid, the others are zero.
When on the status line below a window or the vertical
separater right of a window, the "line" and "column" values
are zero.
When the position is after the text then "column" is the
length of the text in bytes.
If the mouse is over a focusable floating window then that
window is used.
When using |getchar()| the Vim variables |v:mouse_lnum|,
|v:mouse_col| and |v:mouse_winid| also provide these values.
*getpid()*
getpid() Return a Number which is the process ID of the Vim process.
This is a unique number, until Vim exits.

View File

@ -162,6 +162,7 @@ return {
getloclist={args={1, 2}},
getmarklist={args={0, 1}},
getmatches={args={0, 1}},
getmousepos={},
getpid={},
getpos={args=1},
getqflist={args={0, 1}},

View File

@ -3750,6 +3750,48 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
// "getmousepos()" function
void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_T *d;
win_T *wp;
int row = mouse_row;
int col = mouse_col;
int grid = mouse_grid;
varnumber_T winid = 0;
varnumber_T winrow = 0;
varnumber_T wincol = 0;
varnumber_T line = 0;
varnumber_T column = 0;
tv_dict_alloc_ret(rettv);
d = rettv->vval.v_dict;
tv_dict_add_nr(d, S_LEN("screenrow"), (varnumber_T)mouse_row + 1);
tv_dict_add_nr(d, S_LEN("screencol"), (varnumber_T)mouse_col + 1);
wp = mouse_find_win(&grid, &row, &col);
if (wp != NULL) {
int height = wp->w_height + wp->w_status_height;
// The height is adjusted by 1 when there is a bottom border. This is not
// necessary for a top border since `row` starts at -1 in that case.
if (row < height + wp->w_border_adj[2]) {
winid = wp->handle;
winrow = row + 1 + wp->w_border_adj[0]; // Adjust by 1 for top border
wincol = col + 1 + wp->w_border_adj[3]; // Adjust by 1 for left border
if (row >= 0 && row < wp->w_height && col >= 0 && col < wp->w_width) {
mouse_comp_pos(wp, &row, &col, &line);
column = col + 1;
}
}
}
tv_dict_add_nr(d, S_LEN("winid"), winid);
tv_dict_add_nr(d, S_LEN("winrow"), winrow);
tv_dict_add_nr(d, S_LEN("wincol"), wincol);
tv_dict_add_nr(d, S_LEN("line"), line);
tv_dict_add_nr(d, S_LEN("column"), column);
}
/*
* "getpid()" function
*/

View File

@ -363,6 +363,7 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump)
bool retval = false;
int off;
int count;
char_u *p;
if (win->w_p_rl) {
col = win->w_width_inner - 1 - col;
@ -407,6 +408,12 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump)
col += row * (win->w_width_inner - off);
// add skip column (for long wrapping line)
col += win->w_skipcol;
// limit to text length plus one
p = ml_get_buf(win->w_buffer, lnum, false);
count = STRLEN(p);
if (col > count) {
col = count;
}
}
if (!win->w_p_wrap) {