mirror of
https://github.com/neovim/neovim.git
synced 2025-12-11 17:12:40 +00:00
Merge pull request #3871 from ZyX-I/tabline-clicks
Allow running random code on tabline clicks
This commit is contained in:
@@ -7063,6 +7063,7 @@ statusline Compiled with support for 'statusline', 'rulerformat'
|
|||||||
syntax Compiled with syntax highlighting support |syntax|.
|
syntax Compiled with syntax highlighting support |syntax|.
|
||||||
syntax_items There are active syntax highlighting items for the
|
syntax_items There are active syntax highlighting items for the
|
||||||
current buffer.
|
current buffer.
|
||||||
|
tablineat 'tabline' option accepts %@Func@ items.
|
||||||
tag_binary Compiled with binary searching in tags files
|
tag_binary Compiled with binary searching in tags files
|
||||||
|tag-binary-search|.
|
|tag-binary-search|.
|
||||||
tag_old_static Compiled with support for old static tags
|
tag_old_static Compiled with support for old static tags
|
||||||
|
|||||||
@@ -6011,11 +6011,39 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
( - Start of item group. Can be used for setting the width and
|
( - Start of item group. Can be used for setting the width and
|
||||||
alignment of a section. Must be followed by %) somewhere.
|
alignment of a section. Must be followed by %) somewhere.
|
||||||
) - End of item group. No width fields allowed.
|
) - End of item group. No width fields allowed.
|
||||||
T N For 'tabline': start of tab page N label. Use %T after the last
|
T N For 'tabline': start of tab page N label. Use %T or %X to end
|
||||||
label. This information is used for mouse clicks.
|
the label. Clicking this label with left mouse button switches
|
||||||
X N For 'tabline': start of close tab N label. Use %X after the
|
to the specified tab page.
|
||||||
label, e.g.: %3Xclose%X. Use %999X for a "close current tab"
|
X N For 'tabline': start of close tab N label. Use %X or %T to end
|
||||||
mark. This information is used for mouse clicks.
|
the label, e.g.: %3Xclose%X. Use %999X for a "close current
|
||||||
|
tab" label. Clicking this label with left mouse button closes
|
||||||
|
specified tab page.
|
||||||
|
@ N For 'tabline': start of execute function label. Use %X or %T to
|
||||||
|
end the label, e.g.: %10@SwitchBuffer@foo.c%X. Clicking this
|
||||||
|
label runs specified function: in the example when clicking once
|
||||||
|
using left mouse button on "foo.c" "SwitchBuffer(10, 1, 'l',
|
||||||
|
' ')" expression will be run. Function receives the
|
||||||
|
following arguments in order:
|
||||||
|
1. minwid field value or zero if no N was specified
|
||||||
|
2. number of mouse clicks to detect multiple clicks
|
||||||
|
3. mouse button used: "l", "r" or "m" for left, right or middle
|
||||||
|
button respectively; one should not rely on third argument
|
||||||
|
being only "l", "r" or "m": any other non-empty string value
|
||||||
|
that contains only ASCII lower case letters may be expected
|
||||||
|
for other mouse buttons
|
||||||
|
4. modifiers pressed: string which contains "s" if shift
|
||||||
|
modifier was pressed, "c" for control, "a" for alt and "m"
|
||||||
|
for meta; currently if modifier is not pressed string
|
||||||
|
contains space instead, but one should not rely on presence
|
||||||
|
of spaces or specific order of modifiers: use |stridx()| to
|
||||||
|
test whether some modifier is present; string is guaranteed
|
||||||
|
to contain only ASCII letters and spaces, one letter per
|
||||||
|
modifier; "?" modifier may also be present, but its presence
|
||||||
|
is a bug that denotes that new mouse button recognition was
|
||||||
|
added without modifying code that reacts on mouse clicks on
|
||||||
|
this label.
|
||||||
|
Note: to test whether your version of Neovim contains this
|
||||||
|
feature use `has('tablineat')`.
|
||||||
< - Where to truncate line if too long. Default is at the start.
|
< - Where to truncate line if too long. Default is at the start.
|
||||||
No width fields allowed.
|
No width fields allowed.
|
||||||
= - Separation point between left and right aligned items.
|
= - Separation point between left and right aligned items.
|
||||||
|
|||||||
@@ -363,6 +363,7 @@ N *+startuptime* |--startuptime| argument
|
|||||||
N *+statusline* Options 'statusline', 'rulerformat' and special
|
N *+statusline* Options 'statusline', 'rulerformat' and special
|
||||||
formats of 'titlestring' and 'iconstring'
|
formats of 'titlestring' and 'iconstring'
|
||||||
N *+syntax* Syntax highlighting |syntax|
|
N *+syntax* Syntax highlighting |syntax|
|
||||||
|
N *+tablineat* 'tabline' option recognizing %@Func@ items.
|
||||||
N *+tag_binary* binary searching in tags file |tag-binary-search|
|
N *+tag_binary* binary searching in tags file |tag-binary-search|
|
||||||
N *+tag_old_static* old method for static tags |tag-old-static|
|
N *+tag_old_static* old method for static tags |tag-old-static|
|
||||||
m *+tag_any_white* any white space allowed in tags file |tag-any-white|
|
m *+tag_any_white* any white space allowed in tags file |tag-any-white|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "nvim/api/private/handle.h"
|
#include "nvim/api/private/handle.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
|
#include "nvim/assert.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
#include "nvim/buffer.h"
|
#include "nvim/buffer.h"
|
||||||
#include "nvim/charset.h"
|
#include "nvim/charset.h"
|
||||||
@@ -2826,7 +2827,7 @@ typedef enum {
|
|||||||
/// @param fillchar Character to use when filling empty space in the statusline
|
/// @param fillchar Character to use when filling empty space in the statusline
|
||||||
/// @param maxwidth The maximum width to make the statusline
|
/// @param maxwidth The maximum width to make the statusline
|
||||||
/// @param hltab HL attributes (can be NULL)
|
/// @param hltab HL attributes (can be NULL)
|
||||||
/// @param tabtab tab page nrs (can be NULL)
|
/// @param tabtab Tab clicks definition (can be NULL).
|
||||||
///
|
///
|
||||||
/// @return The final width of the statusline
|
/// @return The final width of the statusline
|
||||||
int build_stl_str_hl(
|
int build_stl_str_hl(
|
||||||
@@ -2838,13 +2839,15 @@ int build_stl_str_hl(
|
|||||||
int fillchar,
|
int fillchar,
|
||||||
int maxwidth,
|
int maxwidth,
|
||||||
struct stl_hlrec *hltab,
|
struct stl_hlrec *hltab,
|
||||||
struct stl_hlrec *tabtab
|
StlClickRecord *tabtab
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int groupitem[STL_MAX_ITEM];
|
int groupitem[STL_MAX_ITEM];
|
||||||
struct stl_item {
|
struct stl_item {
|
||||||
// Where the item starts in the status line output buffer
|
// Where the item starts in the status line output buffer
|
||||||
char_u *start;
|
char_u *start;
|
||||||
|
// Function to run for ClickFunc items.
|
||||||
|
char *cmd;
|
||||||
// The minimum width of the item
|
// The minimum width of the item
|
||||||
int minwid;
|
int minwid;
|
||||||
// The maximum width of the item
|
// The maximum width of the item
|
||||||
@@ -2856,10 +2859,10 @@ int build_stl_str_hl(
|
|||||||
Middle,
|
Middle,
|
||||||
Highlight,
|
Highlight,
|
||||||
TabPage,
|
TabPage,
|
||||||
|
ClickFunc,
|
||||||
Trunc
|
Trunc
|
||||||
} type;
|
} type;
|
||||||
} item[STL_MAX_ITEM];
|
} item[STL_MAX_ITEM];
|
||||||
|
|
||||||
#define TMPLEN 70
|
#define TMPLEN 70
|
||||||
char_u tmp[TMPLEN];
|
char_u tmp[TMPLEN];
|
||||||
char_u *usefmt = fmt;
|
char_u *usefmt = fmt;
|
||||||
@@ -3164,6 +3167,24 @@ int build_stl_str_hl(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*fmt_p == STL_CLICK_FUNC) {
|
||||||
|
fmt_p++;
|
||||||
|
char *t = (char *) fmt_p;
|
||||||
|
while (*fmt_p != STL_CLICK_FUNC && *fmt_p) {
|
||||||
|
fmt_p++;
|
||||||
|
}
|
||||||
|
if (*fmt_p != STL_CLICK_FUNC) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
item[curitem].type = ClickFunc;
|
||||||
|
item[curitem].start = out_p;
|
||||||
|
item[curitem].cmd = xmemdupz(t, (size_t) (((char *) fmt_p - t)));
|
||||||
|
item[curitem].minwid = minwid;
|
||||||
|
fmt_p++;
|
||||||
|
curitem++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Denotes the end of the minwid
|
// Denotes the end of the minwid
|
||||||
// the maxwid may follow immediately after
|
// the maxwid may follow immediately after
|
||||||
if (*fmt_p == '.') {
|
if (*fmt_p == '.') {
|
||||||
@@ -3281,6 +3302,7 @@ int build_stl_str_hl(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case STL_LINE:
|
case STL_LINE:
|
||||||
num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY)
|
num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY)
|
||||||
? 0L : (long)(wp->w_cursor.lnum);
|
? 0L : (long)(wp->w_cursor.lnum);
|
||||||
@@ -3821,16 +3843,37 @@ int build_stl_str_hl(
|
|||||||
|
|
||||||
// Store the info about tab pages labels.
|
// Store the info about tab pages labels.
|
||||||
if (tabtab != NULL) {
|
if (tabtab != NULL) {
|
||||||
struct stl_hlrec *sp = tabtab;
|
StlClickRecord *cur_tab_rec = tabtab;
|
||||||
for (long l = 0; l < itemcnt; l++) {
|
for (long l = 0; l < itemcnt; l++) {
|
||||||
if (item[l].type == TabPage) {
|
if (item[l].type == TabPage) {
|
||||||
sp->start = item[l].start;
|
cur_tab_rec->start = (char *) item[l].start;
|
||||||
sp->userhl = item[l].minwid;
|
if (item[l].minwid == 0) {
|
||||||
sp++;
|
cur_tab_rec->def.type = kStlClickDisabled;
|
||||||
|
cur_tab_rec->def.tabnr = 0;
|
||||||
|
} else {
|
||||||
|
int tabnr = item[l].minwid;
|
||||||
|
if (item[l].minwid > 0) {
|
||||||
|
cur_tab_rec->def.type = kStlClickTabSwitch;
|
||||||
|
} else {
|
||||||
|
cur_tab_rec->def.type = kStlClickTabClose;
|
||||||
|
tabnr = -tabnr;
|
||||||
|
}
|
||||||
|
cur_tab_rec->def.tabnr = tabnr;
|
||||||
|
}
|
||||||
|
cur_tab_rec->def.func = NULL;
|
||||||
|
cur_tab_rec++;
|
||||||
|
} else if (item[l].type == ClickFunc) {
|
||||||
|
cur_tab_rec->start = (char *) item[l].start;
|
||||||
|
cur_tab_rec->def.type = kStlClickFuncRun;
|
||||||
|
cur_tab_rec->def.tabnr = item[l].minwid;
|
||||||
|
cur_tab_rec->def.func = item[l].cmd;
|
||||||
|
cur_tab_rec++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sp->start = NULL;
|
cur_tab_rec->start = NULL;
|
||||||
sp->userhl = 0;
|
cur_tab_rec->def.type = kStlClickDisabled;
|
||||||
|
cur_tab_rec->def.tabnr = 0;
|
||||||
|
cur_tab_rec->def.func = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "nvim/window.h"
|
#include "nvim/window.h"
|
||||||
#include "nvim/pos.h" // for linenr_T
|
#include "nvim/pos.h" // for linenr_T
|
||||||
#include "nvim/ex_cmds_defs.h" // for exarg_T
|
#include "nvim/ex_cmds_defs.h" // for exarg_T
|
||||||
|
#include "nvim/screen.h" // for StlClickRecord
|
||||||
|
|
||||||
// Values for buflist_getfile()
|
// Values for buflist_getfile()
|
||||||
enum getf_values {
|
enum getf_values {
|
||||||
|
|||||||
@@ -10930,6 +10930,7 @@ static void f_has(typval_T *argvars, typval_T *rettv)
|
|||||||
#if !defined(UNIX)
|
#if !defined(UNIX)
|
||||||
"system", // TODO(SplinterOfChaos): This IS defined for UNIX!
|
"system", // TODO(SplinterOfChaos): This IS defined for UNIX!
|
||||||
#endif
|
#endif
|
||||||
|
"tablineat",
|
||||||
"tag_binary",
|
"tag_binary",
|
||||||
"tag_old_static",
|
"tag_old_static",
|
||||||
"termresponse",
|
"termresponse",
|
||||||
|
|||||||
@@ -159,15 +159,6 @@ EXTERN int Screen_mco INIT(= 0); /* value of p_mco used when
|
|||||||
* These are single-width. */
|
* These are single-width. */
|
||||||
EXTERN schar_T *ScreenLines2 INIT(= NULL);
|
EXTERN schar_T *ScreenLines2 INIT(= NULL);
|
||||||
|
|
||||||
/*
|
|
||||||
* Indexes for tab page line:
|
|
||||||
* N > 0 for label of tab page N
|
|
||||||
* N == 0 for no label
|
|
||||||
* N < 0 for closing tab page -N
|
|
||||||
* N == -999 for closing current tab page
|
|
||||||
*/
|
|
||||||
EXTERN short *TabPageIdxs INIT(= NULL);
|
|
||||||
|
|
||||||
EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */
|
EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */
|
||||||
EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */
|
EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */
|
||||||
|
|
||||||
|
|||||||
@@ -2347,8 +2347,9 @@ do_mouse (
|
|||||||
if (mouse_row == 0 && firstwin->w_winrow > 0) {
|
if (mouse_row == 0 && firstwin->w_winrow > 0) {
|
||||||
if (is_drag) {
|
if (is_drag) {
|
||||||
if (in_tab_line) {
|
if (in_tab_line) {
|
||||||
c1 = TabPageIdxs[mouse_col];
|
tabpage_move(tab_page_click_defs[mouse_col].type == kStlClickTabClose
|
||||||
tabpage_move(c1 <= 0 ? 9999 : c1 - 1);
|
? 9999
|
||||||
|
: tab_page_click_defs[mouse_col].tabnr - 1);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2358,41 +2359,114 @@ do_mouse (
|
|||||||
&& cmdwin_type == 0
|
&& cmdwin_type == 0
|
||||||
&& mouse_col < Columns) {
|
&& mouse_col < Columns) {
|
||||||
in_tab_line = true;
|
in_tab_line = true;
|
||||||
c1 = TabPageIdxs[mouse_col];
|
c1 = tab_page_click_defs[mouse_col].tabnr;
|
||||||
if (c1 >= 0) {
|
switch (tab_page_click_defs[mouse_col].type) {
|
||||||
if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) {
|
case kStlClickDisabled: {
|
||||||
/* double click opens new page */
|
break;
|
||||||
end_visual_mode();
|
|
||||||
tabpage_new();
|
|
||||||
tabpage_move(c1 == 0 ? 9999 : c1 - 1);
|
|
||||||
} else {
|
|
||||||
/* Go to specified tab page, or next one if not clicking
|
|
||||||
* on a label. */
|
|
||||||
goto_tabpage(c1);
|
|
||||||
|
|
||||||
/* It's like clicking on the status line of a window. */
|
|
||||||
if (curwin != old_curwin)
|
|
||||||
end_visual_mode();
|
|
||||||
}
|
}
|
||||||
} else if (c1 < 0) {
|
case kStlClickTabClose: {
|
||||||
tabpage_T *tp;
|
tabpage_T *tp;
|
||||||
|
|
||||||
/* Close the current or specified tab page. */
|
// Close the current or specified tab page.
|
||||||
if (c1 == -999)
|
if (c1 == 999) {
|
||||||
tp = curtab;
|
tp = curtab;
|
||||||
else
|
} else {
|
||||||
tp = find_tabpage(-c1);
|
tp = find_tabpage(c1);
|
||||||
if (tp == curtab) {
|
}
|
||||||
if (first_tabpage->tp_next != NULL)
|
if (tp == curtab) {
|
||||||
tabpage_close(false);
|
if (first_tabpage->tp_next != NULL) {
|
||||||
} else if (tp != NULL)
|
tabpage_close(false);
|
||||||
tabpage_close_other(tp, false);
|
}
|
||||||
|
} else if (tp != NULL) {
|
||||||
|
tabpage_close_other(tp, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kStlClickTabSwitch: {
|
||||||
|
if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) {
|
||||||
|
// double click opens new page
|
||||||
|
end_visual_mode();
|
||||||
|
tabpage_new();
|
||||||
|
tabpage_move(c1 == 0 ? 9999 : c1 - 1);
|
||||||
|
} else {
|
||||||
|
// Go to specified tab page, or next one if not clicking
|
||||||
|
// on a label.
|
||||||
|
goto_tabpage(c1);
|
||||||
|
|
||||||
|
// It's like clicking on the status line of a window.
|
||||||
|
if (curwin != old_curwin) {
|
||||||
|
end_visual_mode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 = (char_u *) (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_u[]) {
|
||||||
|
(char_u) (mod_mask & MOD_MASK_SHIFT ? 's' : ' '),
|
||||||
|
(char_u) (mod_mask & MOD_MASK_CTRL ? 'c' : ' '),
|
||||||
|
(char_u) (mod_mask & MOD_MASK_ALT ? 'a' : ' '),
|
||||||
|
(char_u) (mod_mask & MOD_MASK_META ? 'm' : ' '),
|
||||||
|
NUL
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
typval_T rettv;
|
||||||
|
int doesrange;
|
||||||
|
(void) call_func((char_u *) tab_page_click_defs[mouse_col].func,
|
||||||
|
(int) strlen(tab_page_click_defs[mouse_col].func),
|
||||||
|
&rettv, ARRAY_SIZE(argv), argv,
|
||||||
|
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
|
||||||
|
&doesrange, true, NULL);
|
||||||
|
clear_tv(&rettv);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (is_drag && in_tab_line) {
|
} else if (is_drag && in_tab_line) {
|
||||||
c1 = TabPageIdxs[mouse_col];
|
tabpage_move(tab_page_click_defs[mouse_col].type == kStlClickTabClose
|
||||||
tabpage_move(c1 <= 0 ? 9999 : c1 - 1);
|
? 9999
|
||||||
|
: tab_page_click_defs[mouse_col].tabnr - 1);
|
||||||
in_tab_line = false;
|
in_tab_line = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,44 +209,58 @@
|
|||||||
#define COM_ALL "nbsmexflrO" /* all flags for 'comments' option */
|
#define COM_ALL "nbsmexflrO" /* all flags for 'comments' option */
|
||||||
#define COM_MAX_LEN 50 /* maximum length of a part */
|
#define COM_MAX_LEN 50 /* maximum length of a part */
|
||||||
|
|
||||||
/* flags for 'statusline' option */
|
/// 'statusline' option flags
|
||||||
#define STL_FILEPATH 'f' /* path of file in buffer */
|
enum {
|
||||||
#define STL_FULLPATH 'F' /* full path of file in buffer */
|
STL_FILEPATH = 'f', ///< Path of file in buffer.
|
||||||
#define STL_FILENAME 't' /* last part (tail) of file path */
|
STL_FULLPATH = 'F', ///< Full path of file in buffer.
|
||||||
#define STL_COLUMN 'c' /* column og cursor*/
|
STL_FILENAME = 't', ///< Last part (tail) of file path.
|
||||||
#define STL_VIRTCOL 'v' /* virtual column */
|
STL_COLUMN = 'c', ///< Column og cursor.
|
||||||
#define STL_VIRTCOL_ALT 'V' /* - with 'if different' display */
|
STL_VIRTCOL = 'v', ///< Virtual column.
|
||||||
#define STL_LINE 'l' /* line number of cursor */
|
STL_VIRTCOL_ALT = 'V', ///< - with 'if different' display.
|
||||||
#define STL_NUMLINES 'L' /* number of lines in buffer */
|
STL_LINE = 'l', ///< Line number of cursor.
|
||||||
#define STL_BUFNO 'n' /* current buffer number */
|
STL_NUMLINES = 'L', ///< Number of lines in buffer.
|
||||||
#define STL_KEYMAP 'k' /* 'keymap' when active */
|
STL_BUFNO = 'n', ///< Current buffer number.
|
||||||
#define STL_OFFSET 'o' /* offset of character under cursor*/
|
STL_KEYMAP = 'k', ///< 'keymap' when active.
|
||||||
#define STL_OFFSET_X 'O' /* - in hexadecimal */
|
STL_OFFSET = 'o', ///< Offset of character under cursor.
|
||||||
#define STL_BYTEVAL 'b' /* byte value of character */
|
STL_OFFSET_X = 'O', ///< - in hexadecimal.
|
||||||
#define STL_BYTEVAL_X 'B' /* - in hexadecimal */
|
STL_BYTEVAL = 'b', ///< Byte value of character.
|
||||||
#define STL_ROFLAG 'r' /* readonly flag */
|
STL_BYTEVAL_X = 'B', ///< - in hexadecimal.
|
||||||
#define STL_ROFLAG_ALT 'R' /* - other display */
|
STL_ROFLAG = 'r', ///< Readonly flag.
|
||||||
#define STL_HELPFLAG 'h' /* window is showing a help file */
|
STL_ROFLAG_ALT = 'R', ///< - other display.
|
||||||
#define STL_HELPFLAG_ALT 'H' /* - other display */
|
STL_HELPFLAG = 'h', ///< Window is showing a help file.
|
||||||
#define STL_FILETYPE 'y' /* 'filetype' */
|
STL_HELPFLAG_ALT = 'H', ///< - other display.
|
||||||
#define STL_FILETYPE_ALT 'Y' /* - other display */
|
STL_FILETYPE = 'y', ///< 'filetype'.
|
||||||
#define STL_PREVIEWFLAG 'w' /* window is showing the preview buf */
|
STL_FILETYPE_ALT = 'Y', ///< - other display.
|
||||||
#define STL_PREVIEWFLAG_ALT 'W' /* - other display */
|
STL_PREVIEWFLAG = 'w', ///< Window is showing the preview buf.
|
||||||
#define STL_MODIFIED 'm' /* modified flag */
|
STL_PREVIEWFLAG_ALT = 'W', ///< - other display.
|
||||||
#define STL_MODIFIED_ALT 'M' /* - other display */
|
STL_MODIFIED = 'm', ///< Modified flag.
|
||||||
#define STL_QUICKFIX 'q' /* quickfix window description */
|
STL_MODIFIED_ALT = 'M', ///< - other display.
|
||||||
#define STL_PERCENTAGE 'p' /* percentage through file */
|
STL_QUICKFIX = 'q', ///< Quickfix window description.
|
||||||
#define STL_ALTPERCENT 'P' /* percentage as TOP BOT ALL or NN% */
|
STL_PERCENTAGE = 'p', ///< Percentage through file.
|
||||||
#define STL_ARGLISTSTAT 'a' /* argument list status as (x of y) */
|
STL_ALTPERCENT = 'P', ///< Percentage as TOP BOT ALL or NN%.
|
||||||
#define STL_PAGENUM 'N' /* page number (when printing)*/
|
STL_ARGLISTSTAT = 'a', ///< Argument list status as (x of y).
|
||||||
#define STL_VIM_EXPR '{' /* start of expression to substitute */
|
STL_PAGENUM = 'N', ///< Page number (when printing).
|
||||||
#define STL_MIDDLEMARK '=' /* separation between left and right */
|
STL_VIM_EXPR = '{', ///< Start of expression to substitute.
|
||||||
#define STL_TRUNCMARK '<' /* truncation mark if line is too long*/
|
STL_MIDDLEMARK = '=', ///< Separation between left and right.
|
||||||
#define STL_USER_HL '*' /* highlight from (User)1..9 or 0 */
|
STL_TRUNCMARK = '<', ///< Truncation mark if line is too long.
|
||||||
#define STL_HIGHLIGHT '#' /* highlight name */
|
STL_USER_HL = '*', ///< Highlight from (User)1..9 or 0.
|
||||||
#define STL_TABPAGENR 'T' /* tab page label nr */
|
STL_HIGHLIGHT = '#', ///< Highlight name.
|
||||||
#define STL_TABCLOSENR 'X' /* tab page close nr */
|
STL_TABPAGENR = 'T', ///< Tab page label nr.
|
||||||
#define STL_ALL ((char_u *) "fFtcvVlLknoObBrRhHmYyWwMqpPaN{#")
|
STL_TABCLOSENR = 'X', ///< Tab page close nr.
|
||||||
|
STL_CLICK_FUNC = '@', ///< Click region start.
|
||||||
|
};
|
||||||
|
/// C string containing all 'statusline' option flags
|
||||||
|
#define STL_ALL ((char_u[]) { \
|
||||||
|
STL_FILEPATH, STL_FULLPATH, STL_FILENAME, STL_COLUMN, STL_VIRTCOL, \
|
||||||
|
STL_VIRTCOL_ALT, STL_LINE, STL_NUMLINES, STL_BUFNO, STL_KEYMAP, STL_OFFSET, \
|
||||||
|
STL_OFFSET_X, STL_BYTEVAL, STL_BYTEVAL_X, STL_ROFLAG, STL_ROFLAG_ALT, \
|
||||||
|
STL_HELPFLAG, STL_HELPFLAG_ALT, STL_FILETYPE, STL_FILETYPE_ALT, \
|
||||||
|
STL_PREVIEWFLAG, STL_PREVIEWFLAG_ALT, STL_MODIFIED, STL_MODIFIED_ALT, \
|
||||||
|
STL_QUICKFIX, STL_PERCENTAGE, STL_ALTPERCENT, STL_ARGLISTSTAT, STL_PAGENUM, \
|
||||||
|
STL_VIM_EXPR, STL_MIDDLEMARK, STL_TRUNCMARK, STL_USER_HL, STL_HIGHLIGHT, \
|
||||||
|
STL_TABPAGENR, STL_TABCLOSENR, STL_CLICK_FUNC, \
|
||||||
|
0, \
|
||||||
|
})
|
||||||
|
|
||||||
/* flags used for parsed 'wildmode' */
|
/* flags used for parsed 'wildmode' */
|
||||||
#define WIM_FULL 1
|
#define WIM_FULL 1
|
||||||
|
|||||||
@@ -147,6 +147,9 @@ static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */
|
|||||||
*/
|
*/
|
||||||
static schar_T *current_ScreenLine;
|
static schar_T *current_ScreenLine;
|
||||||
|
|
||||||
|
StlClickDefinition *tab_page_click_defs = NULL;
|
||||||
|
long tab_page_click_defs_size = 0;
|
||||||
|
|
||||||
# define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c), (rl))
|
# define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c), (rl))
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "screen.c.generated.h"
|
# include "screen.c.generated.h"
|
||||||
@@ -5009,8 +5012,8 @@ win_redr_custom (
|
|||||||
char_u *stl;
|
char_u *stl;
|
||||||
char_u *p;
|
char_u *p;
|
||||||
struct stl_hlrec hltab[STL_MAX_ITEM];
|
struct stl_hlrec hltab[STL_MAX_ITEM];
|
||||||
struct stl_hlrec tabtab[STL_MAX_ITEM];
|
StlClickRecord tabtab[STL_MAX_ITEM];
|
||||||
int use_sandbox = FALSE;
|
int use_sandbox = false;
|
||||||
win_T *ewp;
|
win_T *ewp;
|
||||||
int p_crb_save;
|
int p_crb_save;
|
||||||
|
|
||||||
@@ -5126,20 +5129,24 @@ win_redr_custom (
|
|||||||
screen_puts(p >= buf + len ? (char_u *)"" : p, row, col, curattr);
|
screen_puts(p >= buf + len ? (char_u *)"" : p, row, col, curattr);
|
||||||
|
|
||||||
if (wp == NULL) {
|
if (wp == NULL) {
|
||||||
/* Fill the TabPageIdxs[] array for clicking in the tab pagesline. */
|
// Fill the tab_page_click_defs array for clicking in the tab pages line.
|
||||||
col = 0;
|
col = 0;
|
||||||
len = 0;
|
len = 0;
|
||||||
p = buf;
|
p = buf;
|
||||||
fillchar = 0;
|
StlClickDefinition cur_click_def = {
|
||||||
|
.type = kStlClickDisabled,
|
||||||
|
};
|
||||||
for (n = 0; tabtab[n].start != NULL; n++) {
|
for (n = 0; tabtab[n].start != NULL; n++) {
|
||||||
len += vim_strnsize(p, (int)(tabtab[n].start - p));
|
len += vim_strnsize(p, (int)(tabtab[n].start - (char *) p));
|
||||||
while (col < len)
|
while (col < len) {
|
||||||
TabPageIdxs[col++] = fillchar;
|
tab_page_click_defs[col++] = cur_click_def;
|
||||||
p = tabtab[n].start;
|
}
|
||||||
fillchar = tabtab[n].userhl;
|
p = (char_u *) tabtab[n].start;
|
||||||
|
cur_click_def = tabtab[n].def;
|
||||||
|
}
|
||||||
|
while (col < Columns) {
|
||||||
|
tab_page_click_defs[col++] = cur_click_def;
|
||||||
}
|
}
|
||||||
while (col < Columns)
|
|
||||||
TabPageIdxs[col++] = fillchar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
theend:
|
theend:
|
||||||
@@ -5958,9 +5965,9 @@ void screenalloc(bool doclear)
|
|||||||
sattr_T *new_ScreenAttrs;
|
sattr_T *new_ScreenAttrs;
|
||||||
unsigned *new_LineOffset;
|
unsigned *new_LineOffset;
|
||||||
char_u *new_LineWraps;
|
char_u *new_LineWraps;
|
||||||
short *new_TabPageIdxs;
|
StlClickDefinition *new_tab_page_click_defs;
|
||||||
static int entered = FALSE; /* avoid recursiveness */
|
static bool entered = false; // avoid recursiveness
|
||||||
static int done_outofmem_msg = FALSE; /* did outofmem message */
|
static bool done_outofmem_msg = false;
|
||||||
int retry_count = 0;
|
int retry_count = 0;
|
||||||
const bool l_enc_utf8 = enc_utf8;
|
const bool l_enc_utf8 = enc_utf8;
|
||||||
const int l_enc_dbcs = enc_dbcs;
|
const int l_enc_dbcs = enc_dbcs;
|
||||||
@@ -6033,7 +6040,8 @@ retry:
|
|||||||
new_ScreenAttrs = xmalloc((size_t)((Rows + 1) * Columns * sizeof(sattr_T)));
|
new_ScreenAttrs = xmalloc((size_t)((Rows + 1) * Columns * sizeof(sattr_T)));
|
||||||
new_LineOffset = xmalloc((size_t)(Rows * sizeof(unsigned)));
|
new_LineOffset = xmalloc((size_t)(Rows * sizeof(unsigned)));
|
||||||
new_LineWraps = xmalloc((size_t)(Rows * sizeof(char_u)));
|
new_LineWraps = xmalloc((size_t)(Rows * sizeof(char_u)));
|
||||||
new_TabPageIdxs = xmalloc((size_t)(Columns * sizeof(short)));
|
new_tab_page_click_defs = xcalloc(
|
||||||
|
(size_t) Columns, sizeof(*new_tab_page_click_defs));
|
||||||
|
|
||||||
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||||
win_alloc_lines(wp);
|
win_alloc_lines(wp);
|
||||||
@@ -6051,7 +6059,7 @@ retry:
|
|||||||
|| new_ScreenAttrs == NULL
|
|| new_ScreenAttrs == NULL
|
||||||
|| new_LineOffset == NULL
|
|| new_LineOffset == NULL
|
||||||
|| new_LineWraps == NULL
|
|| new_LineWraps == NULL
|
||||||
|| new_TabPageIdxs == NULL
|
|| new_tab_page_click_defs == NULL
|
||||||
|| outofmem) {
|
|| outofmem) {
|
||||||
if (ScreenLines != NULL || !done_outofmem_msg) {
|
if (ScreenLines != NULL || !done_outofmem_msg) {
|
||||||
/* guess the size */
|
/* guess the size */
|
||||||
@@ -6077,8 +6085,8 @@ retry:
|
|||||||
new_LineOffset = NULL;
|
new_LineOffset = NULL;
|
||||||
xfree(new_LineWraps);
|
xfree(new_LineWraps);
|
||||||
new_LineWraps = NULL;
|
new_LineWraps = NULL;
|
||||||
xfree(new_TabPageIdxs);
|
xfree(new_tab_page_click_defs);
|
||||||
new_TabPageIdxs = NULL;
|
new_tab_page_click_defs = NULL;
|
||||||
} else {
|
} else {
|
||||||
done_outofmem_msg = FALSE;
|
done_outofmem_msg = FALSE;
|
||||||
|
|
||||||
@@ -6157,7 +6165,8 @@ retry:
|
|||||||
ScreenAttrs = new_ScreenAttrs;
|
ScreenAttrs = new_ScreenAttrs;
|
||||||
LineOffset = new_LineOffset;
|
LineOffset = new_LineOffset;
|
||||||
LineWraps = new_LineWraps;
|
LineWraps = new_LineWraps;
|
||||||
TabPageIdxs = new_TabPageIdxs;
|
tab_page_click_defs = new_tab_page_click_defs;
|
||||||
|
tab_page_click_defs_size = Columns;
|
||||||
|
|
||||||
/* It's important that screen_Rows and screen_Columns reflect the actual
|
/* It's important that screen_Rows and screen_Columns reflect the actual
|
||||||
* size of ScreenLines[]. Set them before calling anything. */
|
* size of ScreenLines[]. Set them before calling anything. */
|
||||||
@@ -6196,7 +6205,25 @@ void free_screenlines(void)
|
|||||||
xfree(ScreenAttrs);
|
xfree(ScreenAttrs);
|
||||||
xfree(LineOffset);
|
xfree(LineOffset);
|
||||||
xfree(LineWraps);
|
xfree(LineWraps);
|
||||||
xfree(TabPageIdxs);
|
clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size);
|
||||||
|
xfree(tab_page_click_defs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clear tab_page_click_defs table
|
||||||
|
///
|
||||||
|
/// @param[out] tpcd Table to clear.
|
||||||
|
/// @param[in] tpcd_size Size of the table.
|
||||||
|
void clear_tab_page_click_defs(StlClickDefinition *const tpcd,
|
||||||
|
const long tpcd_size)
|
||||||
|
{
|
||||||
|
if (tpcd != NULL) {
|
||||||
|
for (long i = 0; i < tpcd_size; i++) {
|
||||||
|
if (i == 0 || tpcd[i].func != tpcd[i - 1].func) {
|
||||||
|
xfree(tpcd[i].func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memset(tpcd, 0, (size_t) tpcd_size * sizeof(tpcd[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void screenclear(void)
|
void screenclear(void)
|
||||||
@@ -6804,9 +6831,9 @@ static void draw_tabline(void)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
/* Init TabPageIdxs[] to zero: Clicking outside of tabs has no effect. */
|
// Init TabPageIdxs[] to zero: Clicking outside of tabs has no effect.
|
||||||
for (scol = 0; scol < Columns; ++scol)
|
assert(Columns == tab_page_click_defs_size);
|
||||||
TabPageIdxs[scol] = 0;
|
clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size);
|
||||||
|
|
||||||
/* Use the 'tabline' option if it's set. */
|
/* Use the 'tabline' option if it's set. */
|
||||||
if (*p_tal != NUL) {
|
if (*p_tal != NUL) {
|
||||||
@@ -6904,11 +6931,16 @@ static void draw_tabline(void)
|
|||||||
}
|
}
|
||||||
screen_putchar(' ', 0, col++, attr);
|
screen_putchar(' ', 0, col++, attr);
|
||||||
|
|
||||||
/* Store the tab page number in TabPageIdxs[], so that
|
// Store the tab page number in tab_page_click_defs[], so that
|
||||||
* jump_to_mouse() knows where each one is. */
|
// jump_to_mouse() knows where each one is.
|
||||||
++tabcount;
|
tabcount++;
|
||||||
while (scol < col)
|
while (scol < col) {
|
||||||
TabPageIdxs[scol++] = tabcount;
|
tab_page_click_defs[scol++] = (StlClickDefinition) {
|
||||||
|
.type = kStlClickTabSwitch,
|
||||||
|
.tabnr = tabcount,
|
||||||
|
.func = NULL,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_sep_chars)
|
if (use_sep_chars)
|
||||||
@@ -6920,7 +6952,11 @@ static void draw_tabline(void)
|
|||||||
/* Put an "X" for closing the current tab if there are several. */
|
/* Put an "X" for closing the current tab if there are several. */
|
||||||
if (first_tabpage->tp_next != NULL) {
|
if (first_tabpage->tp_next != NULL) {
|
||||||
screen_putchar('X', 0, (int)Columns - 1, attr_nosel);
|
screen_putchar('X', 0, (int)Columns - 1, attr_nosel);
|
||||||
TabPageIdxs[Columns - 1] = -999;
|
tab_page_click_defs[Columns - 1] = (StlClickDefinition) {
|
||||||
|
.type = kStlClickTabClose,
|
||||||
|
.tabnr = 999,
|
||||||
|
.func = NULL,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,29 @@
|
|||||||
#define NOT_VALID 40 /* buffer needs complete redraw */
|
#define NOT_VALID 40 /* buffer needs complete redraw */
|
||||||
#define CLEAR 50 /* screen messed up, clear it */
|
#define CLEAR 50 /* screen messed up, clear it */
|
||||||
|
|
||||||
|
/// Status line click definition
|
||||||
|
typedef struct {
|
||||||
|
enum {
|
||||||
|
kStlClickDisabled = 0, ///< Clicks to this area are ignored.
|
||||||
|
kStlClickTabSwitch, ///< Switch to the given tab.
|
||||||
|
kStlClickTabClose, ///< Close given tab.
|
||||||
|
kStlClickFuncRun, ///< Run user function.
|
||||||
|
} type; ///< Type of the click.
|
||||||
|
int tabnr; ///< Tab page number.
|
||||||
|
char *func; ///< Function to run.
|
||||||
|
} StlClickDefinition;
|
||||||
|
|
||||||
|
/// Used for tabline clicks
|
||||||
|
typedef struct {
|
||||||
|
StlClickDefinition def; ///< Click definition.
|
||||||
|
const char *start; ///< Location where region starts.
|
||||||
|
} StlClickRecord;
|
||||||
|
|
||||||
|
/// Array defining what should be done when tabline is clicked
|
||||||
|
extern StlClickDefinition *tab_page_click_defs;
|
||||||
|
|
||||||
|
/// Size of the tab_page_click_defs array
|
||||||
|
extern long tab_page_click_defs_size;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "screen.h.generated.h"
|
# include "screen.h.generated.h"
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
local helpers = require('test.functional.helpers')
|
local helpers = require('test.functional.helpers')
|
||||||
local Screen = require('test.functional.ui.screen')
|
local Screen = require('test.functional.ui.screen')
|
||||||
local clear, feed, nvim = helpers.clear, helpers.feed, helpers.nvim
|
local clear, feed, meths = helpers.clear, helpers.feed, helpers.meths
|
||||||
local insert, execute = helpers.insert, helpers.execute
|
local insert, execute = helpers.insert, helpers.execute
|
||||||
|
local eq, funcs = helpers.eq, helpers.funcs
|
||||||
|
|
||||||
describe('Mouse input', function()
|
describe('Mouse input', function()
|
||||||
local screen
|
local screen
|
||||||
@@ -13,11 +14,11 @@ describe('Mouse input', function()
|
|||||||
|
|
||||||
before_each(function()
|
before_each(function()
|
||||||
clear()
|
clear()
|
||||||
nvim('set_option', 'mouse', 'a')
|
meths.set_option('mouse', 'a')
|
||||||
nvim('set_option', 'listchars', 'eol:$')
|
meths.set_option('listchars', 'eol:$')
|
||||||
-- set mouset to very high value to ensure that even in valgrind/travis,
|
-- set mouset to very high value to ensure that even in valgrind/travis,
|
||||||
-- nvim will still pick multiple clicks
|
-- nvim will still pick multiple clicks
|
||||||
nvim('set_option', 'mouset', 5000)
|
meths.set_option('mouset', 5000)
|
||||||
screen = Screen.new(25, 5)
|
screen = Screen.new(25, 5)
|
||||||
screen:attach()
|
screen:attach()
|
||||||
screen:set_default_attr_ids({
|
screen:set_default_attr_ids({
|
||||||
@@ -58,31 +59,149 @@ describe('Mouse input', function()
|
|||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('left click in tabline switches to tab', function()
|
describe('tabline', function()
|
||||||
local tab_attrs = {
|
local tab_attrs = {
|
||||||
tab = { background=Screen.colors.LightGrey, underline=true },
|
tab = { background=Screen.colors.LightGrey, underline=true },
|
||||||
sel = { bold=true },
|
sel = { bold=true },
|
||||||
fill = { reverse=true }
|
fill = { reverse=true }
|
||||||
}
|
}
|
||||||
execute('%delete')
|
|
||||||
insert('this is foo')
|
it('left click in default tabline (position 4) switches to tab', function()
|
||||||
execute('silent file foo | tabnew | file bar')
|
execute('%delete')
|
||||||
insert('this is bar')
|
insert('this is foo')
|
||||||
screen:expect([[
|
execute('silent file foo | tabnew | file bar')
|
||||||
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
insert('this is bar')
|
||||||
this is ba^r |
|
screen:expect([[
|
||||||
~ |
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
||||||
~ |
|
this is ba^r |
|
||||||
|
|
~ |
|
||||||
]], tab_attrs)
|
~ |
|
||||||
feed('<LeftMouse><4,0>')
|
|
|
||||||
screen:expect([[
|
]], tab_attrs)
|
||||||
{sel: + foo }{tab: + bar }{fill: }{tab:X}|
|
feed('<LeftMouse><4,0>')
|
||||||
this is fo^o |
|
screen:expect([[
|
||||||
~ |
|
{sel: + foo }{tab: + bar }{fill: }{tab:X}|
|
||||||
~ |
|
this is fo^o |
|
||||||
|
|
~ |
|
||||||
]], tab_attrs)
|
~ |
|
||||||
|
|
|
||||||
|
]], tab_attrs)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('left click in default tabline (position 24) closes tab', function()
|
||||||
|
meths.set_option('hidden', true)
|
||||||
|
execute('%delete')
|
||||||
|
insert('this is foo')
|
||||||
|
execute('silent file foo | tabnew | file bar')
|
||||||
|
insert('this is bar')
|
||||||
|
screen:expect([[
|
||||||
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
||||||
|
this is ba^r |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
|
|
||||||
|
]], tab_attrs)
|
||||||
|
feed('<LeftMouse><24,0>')
|
||||||
|
screen:expect([[
|
||||||
|
this is fo^o |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
|
|
||||||
|
]], tab_attrs)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('double click in default tabline (position 4) opens new tab', function()
|
||||||
|
meths.set_option('hidden', true)
|
||||||
|
execute('%delete')
|
||||||
|
insert('this is foo')
|
||||||
|
execute('silent file foo | tabnew | file bar')
|
||||||
|
insert('this is bar')
|
||||||
|
screen:expect([[
|
||||||
|
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
|
||||||
|
this is ba^r |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
|
|
||||||
|
]], tab_attrs)
|
||||||
|
feed('<2-LeftMouse><4,0>')
|
||||||
|
screen:expect([[
|
||||||
|
{sel: Name] }{tab: + foo + bar }{fill: }{tab:X}|
|
||||||
|
^ |
|
||||||
|
~ |
|
||||||
|
~ |
|
||||||
|
|
|
||||||
|
]], tab_attrs)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe('%@ label', function()
|
||||||
|
before_each(function()
|
||||||
|
execute([[
|
||||||
|
function Test(...)
|
||||||
|
let g:reply = a:000
|
||||||
|
return copy(a:000) " Check for memory leaks: return should be freed
|
||||||
|
endfunction
|
||||||
|
]])
|
||||||
|
execute([[
|
||||||
|
function Test2(...)
|
||||||
|
return call('Test', a:000 + [2])
|
||||||
|
endfunction
|
||||||
|
]])
|
||||||
|
meths.set_option('tabline', '%@Test@test%X-%5@Test2@test2')
|
||||||
|
meths.set_option('showtabline', 2)
|
||||||
|
screen:expect([[
|
||||||
|
{fill:test-test2 }|
|
||||||
|
mouse |
|
||||||
|
support and selectio^n |
|
||||||
|
~ |
|
||||||
|
|
|
||||||
|
]], tab_attrs)
|
||||||
|
meths.set_var('reply', {})
|
||||||
|
end)
|
||||||
|
|
||||||
|
local check_reply = function(expected)
|
||||||
|
eq(expected, meths.get_var('reply'))
|
||||||
|
meths.set_var('reply', {})
|
||||||
|
end
|
||||||
|
|
||||||
|
local test_click = function(name, click_str, click_num, mouse_button,
|
||||||
|
modifiers)
|
||||||
|
it(name .. ' works', function()
|
||||||
|
eq(1, funcs.has('tablineat'))
|
||||||
|
feed(click_str .. '<3,0>')
|
||||||
|
check_reply({0, click_num, mouse_button, modifiers})
|
||||||
|
feed(click_str .. '<4,0>')
|
||||||
|
check_reply({})
|
||||||
|
feed(click_str .. '<6,0>')
|
||||||
|
check_reply({5, click_num, mouse_button, modifiers, 2})
|
||||||
|
feed(click_str .. '<13,0>')
|
||||||
|
check_reply({5, click_num, mouse_button, modifiers, 2})
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
test_click('single left click', '<LeftMouse>', 1, 'l', ' ')
|
||||||
|
test_click('shifted single left click', '<S-LeftMouse>', 1, 'l', 's ')
|
||||||
|
test_click('shifted single left click with alt modifier',
|
||||||
|
'<S-A-LeftMouse>', 1, 'l', 's a ')
|
||||||
|
test_click('shifted single left click with alt and ctrl modifiers',
|
||||||
|
'<S-C-A-LeftMouse>', 1, 'l', 'sca ')
|
||||||
|
-- <C-RightMouse> does not work
|
||||||
|
test_click('shifted single right click with alt modifier',
|
||||||
|
'<S-A-RightMouse>', 1, 'r', 's a ')
|
||||||
|
-- Modifiers do not work with MiddleMouse
|
||||||
|
test_click('shifted single middle click with alt and ctrl modifiers',
|
||||||
|
'<MiddleMouse>', 1, 'm', ' ')
|
||||||
|
-- Modifiers do not work with N-*Mouse
|
||||||
|
test_click('double left click', '<2-LeftMouse>', 2, 'l', ' ')
|
||||||
|
test_click('triple left click', '<3-LeftMouse>', 3, 'l', ' ')
|
||||||
|
test_click('quadruple left click', '<4-LeftMouse>', 4, 'l', ' ')
|
||||||
|
test_click('double right click', '<2-RightMouse>', 2, 'r', ' ')
|
||||||
|
test_click('triple right click', '<3-RightMouse>', 3, 'r', ' ')
|
||||||
|
test_click('quadruple right click', '<4-RightMouse>', 4, 'r', ' ')
|
||||||
|
test_click('double middle click', '<2-MiddleMouse>', 2, 'm', ' ')
|
||||||
|
test_click('triple middle click', '<3-MiddleMouse>', 3, 'm', ' ')
|
||||||
|
test_click('quadruple middle click', '<4-MiddleMouse>', 4, 'm', ' ')
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('left drag changes visual selection', function()
|
it('left drag changes visual selection', function()
|
||||||
@@ -211,7 +330,7 @@ describe('Mouse input', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
it('ctrl + left click will search for a tag', function()
|
it('ctrl + left click will search for a tag', function()
|
||||||
nvim('set_option', 'tags', './non-existent-tags-file')
|
meths.set_option('tags', './non-existent-tags-file')
|
||||||
feed('<C-LeftMouse><0,0>')
|
feed('<C-LeftMouse><0,0>')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
E433: No tags file |
|
E433: No tags file |
|
||||||
|
|||||||
Reference in New Issue
Block a user