diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/getchar.c | 34 | ||||
| -rw-r--r-- | src/nvim/lua/executor.c | 5 | ||||
| -rw-r--r-- | src/nvim/option_vars.h | 6 | ||||
| -rw-r--r-- | src/nvim/options.lua | 24 | ||||
| -rw-r--r-- | src/nvim/optionstr.c | 20 | ||||
| -rw-r--r-- | src/nvim/window.c | 18 |
6 files changed, 81 insertions, 26 deletions
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index ce2c85f174..20c53703da 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -105,10 +105,10 @@ static buffheader_T readbuf1 = { { NULL, { NUL } }, NULL, 0, 0 }; static buffheader_T readbuf2 = { { NULL, { NUL } }, NULL, 0, 0 }; /// Buffer used to store typed characters for vim.on_key(). -static kvec_withinit_t(char, MAXMAPLEN) on_key_buf = KVI_INITIAL_VALUE(on_key_buf); +static kvec_withinit_t(char, MAXMAPLEN + 1) on_key_buf = KVI_INITIAL_VALUE(on_key_buf); /// Number of following bytes that should not be stored for vim.on_key(). -static size_t no_on_key_len = 0; +static size_t on_key_ignore_len = 0; static int typeahead_char = 0; ///< typeahead char that's not flushed @@ -1010,18 +1010,18 @@ int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent) /// Uses cmd_silent, KeyTyped and KeyNoremap to restore the flags belonging to /// the char. /// -/// @param no_on_key don't store these bytes for vim.on_key() +/// @param on_key_ignore don't store these bytes for vim.on_key() /// /// @return the length of what was inserted -int ins_char_typebuf(int c, int modifiers, bool no_on_key) +int ins_char_typebuf(int c, int modifiers, bool on_key_ignore) { char buf[MB_MAXBYTES * 3 + 4]; unsigned len = special_to_buf(c, modifiers, true, buf); assert(len < sizeof(buf)); buf[len] = NUL; ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent); - if (KeyTyped && no_on_key) { - no_on_key_len += len; + if (KeyTyped && on_key_ignore) { + on_key_ignore_len += len; } return (int)len; } @@ -1189,22 +1189,21 @@ static void gotchars(const uint8_t *chars, size_t len) updatescript(state.buf[i]); } - state.buf[state.buflen] = NUL; + if (state.buflen > on_key_ignore_len) { + kvi_concat_len(on_key_buf, (char *)state.buf + on_key_ignore_len, + state.buflen - on_key_ignore_len); + on_key_ignore_len = 0; + } else { + on_key_ignore_len -= state.buflen; + } if (reg_recording != 0) { + state.buf[state.buflen] = NUL; add_buff(&recordbuff, (char *)state.buf, (ptrdiff_t)state.buflen); // remember how many chars were last recorded last_recorded_len += state.buflen; } - if (state.buflen > no_on_key_len) { - vim_unescape_ks((char *)state.buf + no_on_key_len); - kvi_concat(on_key_buf, (char *)state.buf + no_on_key_len); - no_on_key_len = 0; - } else { - no_on_key_len -= state.buflen; - } - state.buflen = 0; } @@ -1222,7 +1221,7 @@ static void gotchars(const uint8_t *chars, size_t len) void gotchars_ignore(void) { uint8_t nop_buf[3] = { K_SPECIAL, KS_EXTRA, KE_IGNORE }; - no_on_key_len += 3; + on_key_ignore_len += 3; gotchars(nop_buf, 3); } @@ -1770,7 +1769,8 @@ int vgetc(void) may_garbage_collect = false; // Execute Lua on_key callbacks. - nlua_execute_on_key(c, on_key_buf.items, on_key_buf.size); + kvi_push(on_key_buf, NUL); + nlua_execute_on_key(c, on_key_buf.items); kvi_destroy(on_key_buf); kvi_init(on_key_buf); diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index c29e670c33..4d5b2c3698 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -2057,10 +2057,11 @@ char *nlua_register_table_as_callable(const typval_T *const arg) return name; } -void nlua_execute_on_key(int c, char *typed_buf, size_t typed_len) +void nlua_execute_on_key(int c, char *typed_buf) { char buf[MB_MAXBYTES * 3 + 4]; size_t buf_len = special_to_buf(c, mod_mask, false, buf); + vim_unescape_ks(typed_buf); lua_State *const lstate = global_lstate; @@ -2079,7 +2080,7 @@ void nlua_execute_on_key(int c, char *typed_buf, size_t typed_len) lua_pushlstring(lstate, buf, buf_len); // [ vim, vim._on_key, buf, typed_buf ] - lua_pushlstring(lstate, typed_buf, typed_len); + lua_pushstring(lstate, typed_buf); int save_got_int = got_int; got_int = false; // avoid interrupts when the key typed is Ctrl-C diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h index 3326c0879a..b6b307befb 100644 --- a/src/nvim/option_vars.h +++ b/src/nvim/option_vars.h @@ -694,7 +694,6 @@ EXTERN unsigned tpf_flags; ///< flags from 'termpastefilter' EXTERN char *p_tfu; ///< 'tagfunc' EXTERN char *p_spc; ///< 'spellcapcheck' EXTERN char *p_spf; ///< 'spellfile' -EXTERN char *p_spk; ///< 'splitkeep' EXTERN char *p_spl; ///< 'spelllang' EXTERN char *p_spo; ///< 'spelloptions' EXTERN unsigned spo_flags; @@ -711,7 +710,12 @@ EXTERN unsigned swb_flags; #define SWB_NEWTAB 0x008 #define SWB_VSPLIT 0x010 #define SWB_USELAST 0x020 +EXTERN char *p_spk; ///< 'splitkeep' EXTERN char *p_syn; ///< 'syntax' +EXTERN char *p_tcl; ///< 'tabclose' +EXTERN unsigned tcl_flags; ///< flags from 'tabclose' +#define TCL_LEFT 0x001 +#define TCL_USELAST 0x002 EXTERN OptInt p_ts; ///< 'tabstop' EXTERN int p_tbs; ///< 'tagbsearch' EXTERN char *p_tc; ///< 'tagcase' diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 6e317a426c..6345ef5ada 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -8507,6 +8507,30 @@ return { varname = 'p_syn', }, { + abbreviation = 'tcl', + cb = 'did_set_tabclose', + defaults = { if_true = '' }, + deny_duplicates = true, + desc = [=[ + This option controls the behavior when closing tab pages (e.g., using + |:tabclose|). When empty Vim goes to the next (right) tab page. + + Possible values (comma-separated list): + left If included, go to the previous tab page instead of + the next one. + uselast If included, go to the previously used tab page if + possible. This option takes precedence over the + others. + ]=], + expand_cb = 'expand_set_tabclose', + full_name = 'tabclose', + list = 'onecomma', + scope = { 'global' }, + short_desc = N_('which tab page to focus when closing a tab'), + type = 'string', + varname = 'p_tcl', + }, + { abbreviation = 'tal', cb = 'did_set_tabline', defaults = { if_true = '' }, diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 1a4c142fdd..8e853b6ee0 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -98,11 +98,13 @@ static char *(p_ssop_values[]) = { "buffers", "winpos", "resize", "winsize", "lo "options", "help", "blank", "globals", "slash", "unix", "sesdir", "curdir", "folds", "cursor", "tabpages", "terminal", "skiprtp", NULL }; -// Keep in sync with SWB_ flags in option_defs.h +// Keep in sync with SWB_ flags in option_vars.h static char *(p_swb_values[]) = { "useopen", "usetab", "split", "newtab", "vsplit", "uselast", NULL }; static char *(p_spk_values[]) = { "cursor", "screen", "topline", NULL }; static char *(p_tc_values[]) = { "followic", "ignore", "match", "followscs", "smart", NULL }; +// Keep in sync with TCL_ flags in option_vars.h +static char *(p_tcl_values[]) = { "left", "uselast", NULL }; static char *(p_ve_values[]) = { "block", "insert", "all", "onemore", "none", "NONE", NULL }; // Note: Keep this in sync with check_opt_wim() static char *(p_wim_values[]) = { "full", "longest", "list", "lastused", NULL }; @@ -169,6 +171,7 @@ void didset_string_options(void) opt_strings_flags(p_tpf, p_tpf_values, &tpf_flags, true); opt_strings_flags(p_ve, p_ve_values, &ve_flags, true); opt_strings_flags(p_swb, p_swb_values, &swb_flags, true); + opt_strings_flags(p_tcl, p_tcl_values, &tcl_flags, true); opt_strings_flags(p_wop, p_wop_values, &wop_flags, true); opt_strings_flags(p_cb, p_cb_values, &cb_flags, true); } @@ -2207,6 +2210,21 @@ int expand_set_switchbuf(optexpand_T *args, int *numMatches, char ***matches) matches); } +/// The 'tabclose' option is changed. +const char *did_set_tabclose(optset_T *args FUNC_ATTR_UNUSED) +{ + return did_set_opt_flags(p_tcl, p_tcl_values, &tcl_flags, true); +} + +int expand_set_tabclose(optexpand_T *args, int *numMatches, char ***matches) +{ + return expand_set_opt_string(args, + p_tcl_values, + ARRAY_SIZE(p_tcl_values) - 1, + numMatches, + matches); +} + /// The 'tabline' option is changed. const char *did_set_tabline(optset_T *args) { diff --git a/src/nvim/window.c b/src/nvim/window.c index 9203dd1bdb..132bf9ee60 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3456,14 +3456,22 @@ static frame_T *win_altframe(win_T *win, tabpage_T *tp) // Return the tabpage that will be used if the current one is closed. static tabpage_T *alt_tabpage(void) { - // Use the next tab page if possible. - if (curtab->tp_next != NULL) { - return curtab->tp_next; + // Use the last accessed tab page, if possible. + if ((tcl_flags & TCL_USELAST) && valid_tabpage(lastused_tabpage)) { + return lastused_tabpage; } - // Find the last but one tab page. + // Use the previous tab page, if possible. + bool forward = curtab->tp_next != NULL + && ((tcl_flags & TCL_LEFT) == 0 || curtab == first_tabpage); + tabpage_T *tp; - for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next) {} + if (forward) { + tp = curtab->tp_next; + } else { + for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next) {} + } + return tp; } |