aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/options.txt18
-rw-r--r--src/nvim/buffer.c28
-rw-r--r--src/nvim/normal.c60
-rw-r--r--src/nvim/option_defs.h4
-rw-r--r--src/nvim/screen.c8
-rw-r--r--src/nvim/screen.h14
6 files changed, 100 insertions, 32 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index a5211b4d50..4326f770d4 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -6016,10 +6016,20 @@ A jump table for the options with a short description can be found at |Q_op|.
X N For 'tabline': start of close tab N label. Use %X or %T to end
the label, e.g.: %3Xclose%X. Use %999X for a "close current
tab" mark. This information is used for mouse clicks.
- [ - For 'tabline': start of execute command label. Use %X or %T to
- end the label, e.g.: %[buffer 10]foo.c%X. This information is
- used for mouse clicks: in the example when clicking on "foo.c"
- "buffer 10" command will be run.
+ @ N For 'tabline': start of execute function label. Use %X or %T to
+ end the label, e.g.: %10@SwitchBuffer@foo.c%X. This information
+ is used for mouse clicks: 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: minwid field value, number of
+ mouse clicks (to detect double clicks), mouse button used: "l"
+ or "r" for left and right button respectively, 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 and
+ specific order of modifiers: use |stridx()| to test whether some
+ modifier is present.
< - Where to truncate line if too long. Default is at the start.
No width fields allowed.
= - Separation point between left and right aligned items.
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index f8413c32fa..34e24712cd 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -2846,7 +2846,7 @@ int build_stl_str_hl(
struct stl_item {
// Where the item starts in the status line output buffer
char_u *start;
- // Command to run for ClickCmd items.
+ // Function to run for ClickFunc items.
char *cmd;
// The minimum width of the item
int minwid;
@@ -2859,7 +2859,7 @@ int build_stl_str_hl(
Middle,
Highlight,
TabPage,
- ClickCmd,
+ ClickFunc,
Trunc
} type;
} item[STL_MAX_ITEM];
@@ -3167,17 +3167,19 @@ int build_stl_str_hl(
continue;
}
- if (*fmt_p == STL_CLICK_CMD) {
+ if (*fmt_p == STL_CLICK_FUNC) {
+ fmt_p++;
char *t = (char *) fmt_p;
- while (*fmt_p != ']' && *fmt_p) {
+ while (*fmt_p != STL_CLICK_FUNC && *fmt_p) {
fmt_p++;
}
- if (*fmt_p != ']') {
+ if (*fmt_p != STL_CLICK_FUNC) {
break;
}
- item[curitem].type = ClickCmd;
+ item[curitem].type = ClickFunc;
item[curitem].start = out_p;
- item[curitem].cmd = xmemdupz(t + 1, (size_t) (((char *) fmt_p - t) - 1));
+ item[curitem].cmd = xmemdupz(t, (size_t) (((char *) fmt_p - t)));
+ item[curitem].minwid = minwid;
fmt_p++;
curitem++;
continue;
@@ -3858,20 +3860,20 @@ int build_stl_str_hl(
}
cur_tab_rec->def.tabnr = tabnr;
}
- cur_tab_rec->def.cmd = NULL;
+ cur_tab_rec->def.func = NULL;
cur_tab_rec++;
- } else if (item[l].type == ClickCmd) {
+ } else if (item[l].type == ClickFunc) {
cur_tab_rec->start = (char *) item[l].start;
- cur_tab_rec->def.type = kStlClickCmd;
- cur_tab_rec->def.tabnr = 0;
- cur_tab_rec->def.cmd = item[l].cmd;
+ 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++;
}
}
cur_tab_rec->start = NULL;
cur_tab_rec->def.type = kStlClickDisabled;
cur_tab_rec->def.tabnr = 0;
- cur_tab_rec->def.cmd = NULL;
+ cur_tab_rec->def.func = NULL;
}
return width;
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index e083085376..9a9cf50e48 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -2400,8 +2400,64 @@ do_mouse (
}
break;
}
- case kStlClickCmd: {
- do_cmdline_cmd(tab_page_click_defs[mouse_col].cmd);
+ 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;
}
}
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 90f35b5546..11b5e31f77 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -247,7 +247,7 @@ enum {
STL_HIGHLIGHT = '#', ///< Highlight name.
STL_TABPAGENR = 'T', ///< Tab page label nr.
STL_TABCLOSENR = 'X', ///< Tab page close nr.
- STL_CLICK_CMD = '[', ///< Click region start.
+ STL_CLICK_FUNC = '@', ///< Click region start.
};
/// C string containing all 'statusline' option flags
#define STL_ALL ((char_u[]) { \
@@ -258,7 +258,7 @@ enum {
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_CMD, \
+ STL_TABPAGENR, STL_TABCLOSENR, STL_CLICK_FUNC, \
0, \
})
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 2ed9321df0..be8307e8b3 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -6218,8 +6218,8 @@ void clear_tab_page_click_defs(StlClickDefinition *const tpcd,
{
if (tpcd != NULL) {
for (long i = 0; i < tpcd_size; i++) {
- if (i == 0 || tpcd[i].cmd != tpcd[i - 1].cmd) {
- xfree(tpcd[i].cmd);
+ if (i == 0 || tpcd[i].func != tpcd[i - 1].func) {
+ xfree(tpcd[i].func);
}
}
}
@@ -6938,7 +6938,7 @@ static void draw_tabline(void)
tab_page_click_defs[scol++] = (StlClickDefinition) {
.type = kStlClickTabSwitch,
.tabnr = tabcount,
- .cmd = NULL,
+ .func = NULL,
};
}
}
@@ -6955,7 +6955,7 @@ static void draw_tabline(void)
tab_page_click_defs[Columns - 1] = (StlClickDefinition) {
.type = kStlClickTabClose,
.tabnr = 999,
- .cmd = NULL,
+ .func = NULL,
};
}
}
diff --git a/src/nvim/screen.h b/src/nvim/screen.h
index 18a99713c0..81a8b9ed4c 100644
--- a/src/nvim/screen.h
+++ b/src/nvim/screen.h
@@ -19,13 +19,13 @@
/// 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.
- kStlClickCmd, ///< Run VimL command.
- } type; ///< Type of the click.
- int tabnr; ///< Tab page number.
- char *cmd; ///< Command to execute.
+ 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