diff options
author | ZyX <kp-pav@yandex.ru> | 2015-12-20 09:00:37 +0300 |
---|---|---|
committer | ZyX <kp-pav@yandex.ru> | 2016-02-01 21:40:06 +0300 |
commit | 64038bf4e26c57c156db921f60f3cb7bf41ac1fa (patch) | |
tree | 55af52b21e620423af3254a37e01c8afb361faeb | |
parent | ef662498b1ea1aca430624e3fc0d304494282c72 (diff) | |
download | rneovim-64038bf4e26c57c156db921f60f3cb7bf41ac1fa.tar.gz rneovim-64038bf4e26c57c156db921f60f3cb7bf41ac1fa.tar.bz2 rneovim-64038bf4e26c57c156db921f60f3cb7bf41ac1fa.zip |
tabline: Switch to functions, handle different click types
-rw-r--r-- | runtime/doc/options.txt | 18 | ||||
-rw-r--r-- | src/nvim/buffer.c | 28 | ||||
-rw-r--r-- | src/nvim/normal.c | 60 | ||||
-rw-r--r-- | src/nvim/option_defs.h | 4 | ||||
-rw-r--r-- | src/nvim/screen.c | 8 | ||||
-rw-r--r-- | src/nvim/screen.h | 14 |
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 |