diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/buffer.c | 67 | ||||
-rw-r--r-- | src/nvim/buffer.h | 1 | ||||
-rw-r--r-- | src/nvim/eval.c | 1 | ||||
-rw-r--r-- | src/nvim/globals.h | 9 | ||||
-rw-r--r-- | src/nvim/normal.c | 136 | ||||
-rw-r--r-- | src/nvim/option_defs.h | 90 | ||||
-rw-r--r-- | src/nvim/screen.c | 94 | ||||
-rw-r--r-- | src/nvim/screen.h | 23 |
8 files changed, 302 insertions, 119 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index a6e3fedd3f..34e24712cd 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -22,6 +22,7 @@ #include "nvim/api/private/handle.h" #include "nvim/ascii.h" +#include "nvim/assert.h" #include "nvim/vim.h" #include "nvim/buffer.h" #include "nvim/charset.h" @@ -2826,7 +2827,7 @@ typedef enum { /// @param fillchar Character to use when filling empty space in the statusline /// @param maxwidth The maximum width to make the statusline /// @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 int build_stl_str_hl( @@ -2838,13 +2839,15 @@ int build_stl_str_hl( int fillchar, int maxwidth, struct stl_hlrec *hltab, - struct stl_hlrec *tabtab + StlClickRecord *tabtab ) { int groupitem[STL_MAX_ITEM]; struct stl_item { // 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 int minwid; // The maximum width of the item @@ -2856,10 +2859,10 @@ int build_stl_str_hl( Middle, Highlight, TabPage, + ClickFunc, Trunc - } type; - } item[STL_MAX_ITEM]; - + } type; + } item[STL_MAX_ITEM]; #define TMPLEN 70 char_u tmp[TMPLEN]; char_u *usefmt = fmt; @@ -3164,6 +3167,24 @@ int build_stl_str_hl( 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 // the maxwid may follow immediately after if (*fmt_p == '.') { @@ -3281,6 +3302,7 @@ int build_stl_str_hl( } break; } + case STL_LINE: num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) ? 0L : (long)(wp->w_cursor.lnum); @@ -3821,16 +3843,37 @@ int build_stl_str_hl( // Store the info about tab pages labels. if (tabtab != NULL) { - struct stl_hlrec *sp = tabtab; + StlClickRecord *cur_tab_rec = tabtab; for (long l = 0; l < itemcnt; l++) { if (item[l].type == TabPage) { - sp->start = item[l].start; - sp->userhl = item[l].minwid; - sp++; + cur_tab_rec->start = (char *) item[l].start; + if (item[l].minwid == 0) { + 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; - sp->userhl = 0; + cur_tab_rec->start = NULL; + cur_tab_rec->def.type = kStlClickDisabled; + cur_tab_rec->def.tabnr = 0; + cur_tab_rec->def.func = NULL; } return width; diff --git a/src/nvim/buffer.h b/src/nvim/buffer.h index 49025d3925..d51a2f7dae 100644 --- a/src/nvim/buffer.h +++ b/src/nvim/buffer.h @@ -4,6 +4,7 @@ #include "nvim/window.h" #include "nvim/pos.h" // for linenr_T #include "nvim/ex_cmds_defs.h" // for exarg_T +#include "nvim/screen.h" // for StlClickRecord // Values for buflist_getfile() enum getf_values { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index e4e7b63fe3..6c471ab770 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -10930,6 +10930,7 @@ static void f_has(typval_T *argvars, typval_T *rettv) #if !defined(UNIX) "system", // TODO(SplinterOfChaos): This IS defined for UNIX! #endif + "tablineat", "tag_binary", "tag_old_static", "termresponse", diff --git a/src/nvim/globals.h b/src/nvim/globals.h index b45f13de4c..697a4a765a 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -159,15 +159,6 @@ EXTERN int Screen_mco INIT(= 0); /* value of p_mco used when * These are single-width. */ 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_Columns INIT(= 0); /* actual size of ScreenLines[] */ diff --git a/src/nvim/normal.c b/src/nvim/normal.c index cb3fc98dfa..9a9cf50e48 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -2347,8 +2347,9 @@ do_mouse ( if (mouse_row == 0 && firstwin->w_winrow > 0) { if (is_drag) { if (in_tab_line) { - c1 = TabPageIdxs[mouse_col]; - tabpage_move(c1 <= 0 ? 9999 : c1 - 1); + tabpage_move(tab_page_click_defs[mouse_col].type == kStlClickTabClose + ? 9999 + : tab_page_click_defs[mouse_col].tabnr - 1); } return false; } @@ -2358,41 +2359,114 @@ do_mouse ( && cmdwin_type == 0 && mouse_col < Columns) { in_tab_line = true; - c1 = TabPageIdxs[mouse_col]; - if (c1 >= 0) { - 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) + c1 = tab_page_click_defs[mouse_col].tabnr; + switch (tab_page_click_defs[mouse_col].type) { + case kStlClickDisabled: { + break; + } + case kStlClickTabClose: { + tabpage_T *tp; + + // Close the current or specified tab page. + if (c1 == 999) { + tp = curtab; + } else { + tp = find_tabpage(c1); + } + if (tp == curtab) { + if (first_tabpage->tp_next != NULL) { + tabpage_close(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; } - } else if (c1 < 0) { - tabpage_T *tp; - - /* Close the current or specified tab page. */ - if (c1 == -999) - tp = curtab; - else - tp = find_tabpage(-c1); - if (tp == curtab) { - if (first_tabpage->tp_next != NULL) - tabpage_close(false); - } else if (tp != NULL) - tabpage_close_other(tp, false); } } return true; } else if (is_drag && in_tab_line) { - c1 = TabPageIdxs[mouse_col]; - tabpage_move(c1 <= 0 ? 9999 : c1 - 1); + tabpage_move(tab_page_click_defs[mouse_col].type == kStlClickTabClose + ? 9999 + : tab_page_click_defs[mouse_col].tabnr - 1); in_tab_line = false; return false; } diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 7a837de45c..11b5e31f77 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -209,44 +209,58 @@ #define COM_ALL "nbsmexflrO" /* all flags for 'comments' option */ #define COM_MAX_LEN 50 /* maximum length of a part */ -/* flags for 'statusline' option */ -#define STL_FILEPATH 'f' /* path of file in buffer */ -#define STL_FULLPATH 'F' /* full path of file in buffer */ -#define STL_FILENAME 't' /* last part (tail) of file path */ -#define STL_COLUMN 'c' /* column og cursor*/ -#define STL_VIRTCOL 'v' /* virtual column */ -#define STL_VIRTCOL_ALT 'V' /* - with 'if different' display */ -#define STL_LINE 'l' /* line number of cursor */ -#define STL_NUMLINES 'L' /* number of lines in buffer */ -#define STL_BUFNO 'n' /* current buffer number */ -#define STL_KEYMAP 'k' /* 'keymap' when active */ -#define STL_OFFSET 'o' /* offset of character under cursor*/ -#define STL_OFFSET_X 'O' /* - in hexadecimal */ -#define STL_BYTEVAL 'b' /* byte value of character */ -#define STL_BYTEVAL_X 'B' /* - in hexadecimal */ -#define STL_ROFLAG 'r' /* readonly flag */ -#define STL_ROFLAG_ALT 'R' /* - other display */ -#define STL_HELPFLAG 'h' /* window is showing a help file */ -#define STL_HELPFLAG_ALT 'H' /* - other display */ -#define STL_FILETYPE 'y' /* 'filetype' */ -#define STL_FILETYPE_ALT 'Y' /* - other display */ -#define STL_PREVIEWFLAG 'w' /* window is showing the preview buf */ -#define STL_PREVIEWFLAG_ALT 'W' /* - other display */ -#define STL_MODIFIED 'm' /* modified flag */ -#define STL_MODIFIED_ALT 'M' /* - other display */ -#define STL_QUICKFIX 'q' /* quickfix window description */ -#define STL_PERCENTAGE 'p' /* percentage through file */ -#define STL_ALTPERCENT 'P' /* percentage as TOP BOT ALL or NN% */ -#define STL_ARGLISTSTAT 'a' /* argument list status as (x of y) */ -#define STL_PAGENUM 'N' /* page number (when printing)*/ -#define STL_VIM_EXPR '{' /* start of expression to substitute */ -#define STL_MIDDLEMARK '=' /* separation between left and right */ -#define STL_TRUNCMARK '<' /* truncation mark if line is too long*/ -#define STL_USER_HL '*' /* highlight from (User)1..9 or 0 */ -#define STL_HIGHLIGHT '#' /* highlight name */ -#define STL_TABPAGENR 'T' /* tab page label nr */ -#define STL_TABCLOSENR 'X' /* tab page close nr */ -#define STL_ALL ((char_u *) "fFtcvVlLknoObBrRhHmYyWwMqpPaN{#") +/// 'statusline' option flags +enum { + STL_FILEPATH = 'f', ///< Path of file in buffer. + STL_FULLPATH = 'F', ///< Full path of file in buffer. + STL_FILENAME = 't', ///< Last part (tail) of file path. + STL_COLUMN = 'c', ///< Column og cursor. + STL_VIRTCOL = 'v', ///< Virtual column. + STL_VIRTCOL_ALT = 'V', ///< - with 'if different' display. + STL_LINE = 'l', ///< Line number of cursor. + STL_NUMLINES = 'L', ///< Number of lines in buffer. + STL_BUFNO = 'n', ///< Current buffer number. + STL_KEYMAP = 'k', ///< 'keymap' when active. + STL_OFFSET = 'o', ///< Offset of character under cursor. + STL_OFFSET_X = 'O', ///< - in hexadecimal. + STL_BYTEVAL = 'b', ///< Byte value of character. + STL_BYTEVAL_X = 'B', ///< - in hexadecimal. + STL_ROFLAG = 'r', ///< Readonly flag. + STL_ROFLAG_ALT = 'R', ///< - other display. + STL_HELPFLAG = 'h', ///< Window is showing a help file. + STL_HELPFLAG_ALT = 'H', ///< - other display. + STL_FILETYPE = 'y', ///< 'filetype'. + STL_FILETYPE_ALT = 'Y', ///< - other display. + STL_PREVIEWFLAG = 'w', ///< Window is showing the preview buf. + STL_PREVIEWFLAG_ALT = 'W', ///< - other display. + STL_MODIFIED = 'm', ///< Modified flag. + STL_MODIFIED_ALT = 'M', ///< - other display. + STL_QUICKFIX = 'q', ///< Quickfix window description. + STL_PERCENTAGE = 'p', ///< Percentage through file. + STL_ALTPERCENT = 'P', ///< Percentage as TOP BOT ALL or NN%. + STL_ARGLISTSTAT = 'a', ///< Argument list status as (x of y). + STL_PAGENUM = 'N', ///< Page number (when printing). + STL_VIM_EXPR = '{', ///< Start of expression to substitute. + STL_MIDDLEMARK = '=', ///< Separation between left and right. + STL_TRUNCMARK = '<', ///< Truncation mark if line is too long. + STL_USER_HL = '*', ///< Highlight from (User)1..9 or 0. + STL_HIGHLIGHT = '#', ///< Highlight name. + STL_TABPAGENR = 'T', ///< Tab page label nr. + 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' */ #define WIM_FULL 1 diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 43bc2c1f68..be8307e8b3 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -147,6 +147,9 @@ static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */ */ 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)) #ifdef INCLUDE_GENERATED_DECLARATIONS # include "screen.c.generated.h" @@ -5009,8 +5012,8 @@ win_redr_custom ( char_u *stl; char_u *p; struct stl_hlrec hltab[STL_MAX_ITEM]; - struct stl_hlrec tabtab[STL_MAX_ITEM]; - int use_sandbox = FALSE; + StlClickRecord tabtab[STL_MAX_ITEM]; + int use_sandbox = false; win_T *ewp; int p_crb_save; @@ -5126,20 +5129,24 @@ win_redr_custom ( screen_puts(p >= buf + len ? (char_u *)"" : p, row, col, curattr); 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; len = 0; p = buf; - fillchar = 0; + StlClickDefinition cur_click_def = { + .type = kStlClickDisabled, + }; for (n = 0; tabtab[n].start != NULL; n++) { - len += vim_strnsize(p, (int)(tabtab[n].start - p)); - while (col < len) - TabPageIdxs[col++] = fillchar; - p = tabtab[n].start; - fillchar = tabtab[n].userhl; + len += vim_strnsize(p, (int)(tabtab[n].start - (char *) p)); + while (col < len) { + tab_page_click_defs[col++] = cur_click_def; + } + 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: @@ -5958,9 +5965,9 @@ void screenalloc(bool doclear) sattr_T *new_ScreenAttrs; unsigned *new_LineOffset; char_u *new_LineWraps; - short *new_TabPageIdxs; - static int entered = FALSE; /* avoid recursiveness */ - static int done_outofmem_msg = FALSE; /* did outofmem message */ + StlClickDefinition *new_tab_page_click_defs; + static bool entered = false; // avoid recursiveness + static bool done_outofmem_msg = false; int retry_count = 0; const bool l_enc_utf8 = enc_utf8; const int l_enc_dbcs = enc_dbcs; @@ -6033,7 +6040,8 @@ retry: new_ScreenAttrs = xmalloc((size_t)((Rows + 1) * Columns * sizeof(sattr_T))); new_LineOffset = xmalloc((size_t)(Rows * sizeof(unsigned))); 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) { win_alloc_lines(wp); @@ -6051,7 +6059,7 @@ retry: || new_ScreenAttrs == NULL || new_LineOffset == NULL || new_LineWraps == NULL - || new_TabPageIdxs == NULL + || new_tab_page_click_defs == NULL || outofmem) { if (ScreenLines != NULL || !done_outofmem_msg) { /* guess the size */ @@ -6077,8 +6085,8 @@ retry: new_LineOffset = NULL; xfree(new_LineWraps); new_LineWraps = NULL; - xfree(new_TabPageIdxs); - new_TabPageIdxs = NULL; + xfree(new_tab_page_click_defs); + new_tab_page_click_defs = NULL; } else { done_outofmem_msg = FALSE; @@ -6157,7 +6165,8 @@ retry: ScreenAttrs = new_ScreenAttrs; LineOffset = new_LineOffset; 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 * size of ScreenLines[]. Set them before calling anything. */ @@ -6196,7 +6205,25 @@ void free_screenlines(void) xfree(ScreenAttrs); xfree(LineOffset); 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) @@ -6804,9 +6831,9 @@ static void draw_tabline(void) return; - /* Init TabPageIdxs[] to zero: Clicking outside of tabs has no effect. */ - for (scol = 0; scol < Columns; ++scol) - TabPageIdxs[scol] = 0; + // Init TabPageIdxs[] to zero: Clicking outside of tabs has no effect. + assert(Columns == tab_page_click_defs_size); + clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size); /* Use the 'tabline' option if it's set. */ if (*p_tal != NUL) { @@ -6904,11 +6931,16 @@ static void draw_tabline(void) } screen_putchar(' ', 0, col++, attr); - /* Store the tab page number in TabPageIdxs[], so that - * jump_to_mouse() knows where each one is. */ - ++tabcount; - while (scol < col) - TabPageIdxs[scol++] = tabcount; + // Store the tab page number in tab_page_click_defs[], so that + // jump_to_mouse() knows where each one is. + tabcount++; + while (scol < col) { + tab_page_click_defs[scol++] = (StlClickDefinition) { + .type = kStlClickTabSwitch, + .tabnr = tabcount, + .func = NULL, + }; + } } 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. */ if (first_tabpage->tp_next != NULL) { 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, + }; } } diff --git a/src/nvim/screen.h b/src/nvim/screen.h index debf86ae67..81a8b9ed4c 100644 --- a/src/nvim/screen.h +++ b/src/nvim/screen.h @@ -16,6 +16,29 @@ #define NOT_VALID 40 /* buffer needs complete redraw */ #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 # include "screen.h.generated.h" |