mirror of
https://github.com/neovim/neovim.git
synced 2025-09-28 14:08:32 +00:00
feat: click support for 'statusline', 'winbar' #18650
The mouseclick item "%@" is now supported by 'statusline' and 'winbar'. Previously it was only supported by 'tabline'.
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include "nvim/fold.h"
|
||||
#include "nvim/getchar.h"
|
||||
#include "nvim/globals.h"
|
||||
#include "nvim/grid_defs.h"
|
||||
#include "nvim/indent.h"
|
||||
#include "nvim/keycodes.h"
|
||||
#include "nvim/log.h"
|
||||
@@ -1432,6 +1433,63 @@ static void move_tab_to_mouse(void)
|
||||
}
|
||||
}
|
||||
|
||||
/// Call click definition function for column "col" in the "click_defs" array for button
|
||||
/// "which_button".
|
||||
static void call_click_def_func(StlClickDefinition *click_defs, int col, int which_button)
|
||||
{
|
||||
typval_T argv[] = {
|
||||
{
|
||||
.v_lock = VAR_FIXED,
|
||||
.v_type = VAR_NUMBER,
|
||||
.vval = {
|
||||
.v_number = (varnumber_T)click_defs[col].tabnr
|
||||
},
|
||||
},
|
||||
{
|
||||
.v_lock = VAR_FIXED,
|
||||
.v_type = VAR_NUMBER,
|
||||
.vval = {
|
||||
.v_number = ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_4CLICK
|
||||
? 4
|
||||
: ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_3CLICK
|
||||
? 3
|
||||
: ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK
|
||||
? 2
|
||||
: 1)))
|
||||
},
|
||||
},
|
||||
{
|
||||
.v_lock = VAR_FIXED,
|
||||
.v_type = VAR_STRING,
|
||||
.vval = {
|
||||
.v_string = (which_button == MOUSE_LEFT
|
||||
? "l"
|
||||
: (which_button == MOUSE_RIGHT
|
||||
? "r"
|
||||
: (which_button == MOUSE_MIDDLE
|
||||
? "m"
|
||||
: "?")))
|
||||
},
|
||||
},
|
||||
{
|
||||
.v_lock = VAR_FIXED,
|
||||
.v_type = VAR_STRING,
|
||||
.vval = {
|
||||
.v_string = (char[]) {
|
||||
(char)(mod_mask & MOD_MASK_SHIFT ? 's' : ' '),
|
||||
(char)(mod_mask & MOD_MASK_CTRL ? 'c' : ' '),
|
||||
(char)(mod_mask & MOD_MASK_ALT ? 'a' : ' '),
|
||||
(char)(mod_mask & MOD_MASK_META ? 'm' : ' '),
|
||||
NUL
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
typval_T rettv;
|
||||
(void)call_vim_function(click_defs[col].func, ARRAY_SIZE(argv), argv, &rettv);
|
||||
tv_clear(&rettv);
|
||||
}
|
||||
|
||||
/// Do the appropriate action for the current mouse click in the current mode.
|
||||
/// Not used for Command-line mode.
|
||||
///
|
||||
@@ -1481,6 +1539,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent)
|
||||
int jump_flags = 0; // flags for jump_to_mouse()
|
||||
pos_T start_visual;
|
||||
bool moved; // Has cursor moved?
|
||||
bool in_winbar; // mouse in window bar
|
||||
bool in_status_line; // mouse in status line
|
||||
static bool in_tab_line = false; // mouse clicked in tab line
|
||||
bool in_sep_line; // mouse in vertical separator line
|
||||
@@ -1711,66 +1770,10 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kStlClickFuncRun: {
|
||||
typval_T argv[] = {
|
||||
{
|
||||
.v_lock = VAR_FIXED,
|
||||
.v_type = VAR_NUMBER,
|
||||
.vval = {
|
||||
.v_number = (varnumber_T)tab_page_click_defs[mouse_col].tabnr
|
||||
},
|
||||
},
|
||||
{
|
||||
.v_lock = VAR_FIXED,
|
||||
.v_type = VAR_NUMBER,
|
||||
.vval = {
|
||||
.v_number = ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_4CLICK
|
||||
? 4
|
||||
: ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_3CLICK
|
||||
? 3
|
||||
: ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK
|
||||
? 2
|
||||
: 1)))
|
||||
},
|
||||
},
|
||||
{
|
||||
.v_lock = VAR_FIXED,
|
||||
.v_type = VAR_STRING,
|
||||
.vval = {
|
||||
.v_string = (which_button == MOUSE_LEFT
|
||||
? "l"
|
||||
: (which_button == MOUSE_RIGHT
|
||||
? "r"
|
||||
: (which_button == MOUSE_MIDDLE
|
||||
? "m"
|
||||
: "?")))
|
||||
},
|
||||
},
|
||||
{
|
||||
.v_lock = VAR_FIXED,
|
||||
.v_type = VAR_STRING,
|
||||
.vval = {
|
||||
.v_string = (char[]) {
|
||||
(char)(mod_mask & MOD_MASK_SHIFT ? 's' : ' '),
|
||||
(char)(mod_mask & MOD_MASK_CTRL ? 'c' : ' '),
|
||||
(char)(mod_mask & MOD_MASK_ALT ? 'a' : ' '),
|
||||
(char)(mod_mask & MOD_MASK_META ? 'm' : ' '),
|
||||
NUL
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
typval_T rettv;
|
||||
funcexe_T funcexe = FUNCEXE_INIT;
|
||||
funcexe.firstline = curwin->w_cursor.lnum;
|
||||
funcexe.lastline = curwin->w_cursor.lnum;
|
||||
funcexe.evaluate = true;
|
||||
(void)call_func(tab_page_click_defs[mouse_col].func, -1,
|
||||
&rettv, ARRAY_SIZE(argv), argv, &funcexe);
|
||||
tv_clear(&rettv);
|
||||
case kStlClickFuncRun:
|
||||
call_click_def_func(tab_page_click_defs, mouse_col, which_button);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (is_drag && in_tab_line) {
|
||||
@@ -1840,15 +1843,39 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent)
|
||||
oap == NULL ? NULL : &(oap->inclusive),
|
||||
which_button);
|
||||
|
||||
// A click in the window bar has no side effects.
|
||||
if (jump_flags & MOUSE_WINBAR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
moved = (jump_flags & CURSOR_MOVED);
|
||||
in_winbar = (jump_flags & MOUSE_WINBAR);
|
||||
in_status_line = (jump_flags & IN_STATUS_LINE);
|
||||
in_sep_line = (jump_flags & IN_SEP_LINE);
|
||||
|
||||
if ((in_winbar || in_status_line) && is_click) {
|
||||
// Handle click event on window bar or status lin
|
||||
int click_grid = mouse_grid;
|
||||
int click_row = mouse_row;
|
||||
int click_col = mouse_col;
|
||||
win_T *wp = mouse_find_win(&click_grid, &click_row, &click_col);
|
||||
|
||||
StlClickDefinition *click_defs = in_status_line ? wp->w_status_click_defs
|
||||
: wp->w_winbar_click_defs;
|
||||
|
||||
if (click_defs != NULL) {
|
||||
switch (click_defs[click_col].type) {
|
||||
case kStlClickDisabled:
|
||||
break;
|
||||
case kStlClickFuncRun:
|
||||
call_click_def_func(click_defs, click_col, which_button);
|
||||
break;
|
||||
default:
|
||||
assert(false && "winbar and statusline only support %@ for clicks");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else if (in_winbar) {
|
||||
// A drag or release event in the window bar has no side effects.
|
||||
return false;
|
||||
}
|
||||
|
||||
// When jumping to another window, clear a pending operator. That's a bit
|
||||
// friendlier than beeping and not jumping to that window.
|
||||
|
Reference in New Issue
Block a user