mirror of
https://github.com/neovim/neovim.git
synced 2024-09-17 20:58:20 -04:00
vim-patch:9.1.0572: cannot specify tab page closing behaviour (#29682)
Problem: cannot specify tab page closing behaviour
(Gianluca Pacchiella)
Solution: Add the 'tabclose' option (LemonBoy).
fixes: vim/vim#5967
closes: vim/vim#15204
5247b0b92e
Co-authored-by: LemonBoy <thatlemon@gmail.com>
This commit is contained in:
parent
10256bb760
commit
b1aa8f5eb8
@ -141,6 +141,7 @@ LUA
|
||||
OPTIONS
|
||||
|
||||
• 'completeopt' flag "fuzzy" enables |fuzzy-matching| during |ins-completion|.
|
||||
• 'tabclose' controls which tab page to focus when closing a tab page.
|
||||
|
||||
PERFORMANCE
|
||||
|
||||
|
@ -6343,6 +6343,19 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
'S' flag in 'cpoptions'.
|
||||
Only normal file name characters can be used, `/\*?[|<>` are illegal.
|
||||
|
||||
*'tabclose'* *'tcl'*
|
||||
'tabclose' 'tcl' string (default "")
|
||||
global
|
||||
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.
|
||||
|
||||
*'tabline'* *'tal'*
|
||||
'tabline' 'tal' string (default "")
|
||||
global
|
||||
|
@ -886,6 +886,7 @@ Short explanation of each option: *option-list*
|
||||
'switchbuf' 'swb' sets behavior when switching to another buffer
|
||||
'synmaxcol' 'smc' maximum column to find syntax items
|
||||
'syntax' 'syn' syntax to be loaded for current buffer
|
||||
'tabclose' 'tcl' which tab page to focus when closing a tab
|
||||
'tabline' 'tal' custom format for the console tab pages line
|
||||
'tabpagemax' 'tpm' maximum number of tab pages for |-p| and "tab all"
|
||||
'tabstop' 'ts' number of spaces that <Tab> in file uses
|
||||
|
@ -135,7 +135,8 @@ something else.
|
||||
:tabclose $ " close the last tab page
|
||||
:tabclose # " close the last accessed tab page
|
||||
|
||||
When a tab is closed the next tab page will become the current one.
|
||||
When a tab is closed the next tab page will become the current one. This
|
||||
behaviour can be customized using the 'tabclose' option.
|
||||
|
||||
*:tabo* *:tabonly*
|
||||
:tabo[nly][!] Close all other tab pages.
|
||||
|
16
runtime/lua/vim/_meta/options.lua
generated
16
runtime/lua/vim/_meta/options.lua
generated
@ -6837,6 +6837,22 @@ vim.o.syn = vim.o.syntax
|
||||
vim.bo.syntax = vim.o.syntax
|
||||
vim.bo.syn = vim.bo.syntax
|
||||
|
||||
--- 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.
|
||||
---
|
||||
--- @type string
|
||||
vim.o.tabclose = ""
|
||||
vim.o.tcl = vim.o.tabclose
|
||||
vim.go.tabclose = vim.o.tabclose
|
||||
vim.go.tcl = vim.go.tabclose
|
||||
|
||||
--- When non-empty, this option determines the content of the tab pages
|
||||
--- line at the top of the Vim window. When empty Vim will use a default
|
||||
--- tab pages line. See `setting-tabline` for more info.
|
||||
|
@ -1,7 +1,7 @@
|
||||
" These commands create the option window.
|
||||
"
|
||||
" Maintainer: The Vim Project <https://github.com/vim/vim>
|
||||
" Last Change: 2024 Jun 05
|
||||
" Last Change: 2024 Jul 12
|
||||
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
|
||||
" If there already is an option window, jump to that one.
|
||||
@ -507,6 +507,8 @@ endif
|
||||
call <SID>Header(gettext("multiple tab pages"))
|
||||
call <SID>AddOption("showtabline", gettext("0, 1 or 2; when to use a tab pages line"))
|
||||
call append("$", " \tset stal=" . &stal)
|
||||
call <SID>AddOption("tabclose", gettext("behaviour when closing tab pages: left, uselast or empty"))
|
||||
call append("$", " \tset tcl=" . &tcl)
|
||||
call <SID>AddOption("tabpagemax", gettext("maximum number of tab pages to open for -p and \"tab all\""))
|
||||
call append("$", " \tset tpm=" . &tpm)
|
||||
call <SID>AddOption("tabline", gettext("custom tab pages line"))
|
||||
|
@ -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'
|
||||
|
@ -8506,6 +8506,30 @@ return {
|
||||
type = 'string',
|
||||
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',
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -558,6 +558,9 @@ func Test_set_completion_string_values()
|
||||
" call assert_equal('sync', getcompletion('set swapsync=', 'cmdline')[1])
|
||||
call assert_equal('usetab', getcompletion('set switchbuf=', 'cmdline')[1])
|
||||
call assert_equal('ignore', getcompletion('set tagcase=', 'cmdline')[1])
|
||||
if exists('+tabclose')
|
||||
call assert_equal('left uselast', join(sort(getcompletion('set tabclose=', 'cmdline'))), ' ')
|
||||
endif
|
||||
if exists('+termwintype')
|
||||
call assert_equal('conpty', getcompletion('set termwintype=', 'cmdline')[1])
|
||||
endif
|
||||
@ -1377,9 +1380,10 @@ func Test_write()
|
||||
new
|
||||
call setline(1, ['L1'])
|
||||
set nowrite
|
||||
call assert_fails('write Xfile', 'E142:')
|
||||
call assert_fails('write Xwrfile', 'E142:')
|
||||
set write
|
||||
close!
|
||||
" close swapfile
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
" Test for 'buftype' option
|
||||
|
@ -967,6 +967,64 @@ func Test_tabpage_alloc_failure()
|
||||
call assert_equal(1, tabpagenr('$'))
|
||||
endfunc
|
||||
|
||||
func Test_tabpage_tabclose()
|
||||
" Default behaviour, move to the right.
|
||||
call s:reconstruct_tabpage_for_test(6)
|
||||
norm! 4gt
|
||||
setl tcl=
|
||||
tabclose
|
||||
call assert_equal("n3", bufname())
|
||||
|
||||
" Move to the left.
|
||||
call s:reconstruct_tabpage_for_test(6)
|
||||
norm! 4gt
|
||||
setl tcl=left
|
||||
tabclose
|
||||
call assert_equal("n1", bufname())
|
||||
|
||||
" Move to the last used tab page.
|
||||
call s:reconstruct_tabpage_for_test(6)
|
||||
norm! 5gt
|
||||
norm! 2gt
|
||||
setl tcl=uselast
|
||||
tabclose
|
||||
call assert_equal("n3", bufname())
|
||||
|
||||
" Same, but the last used tab page is invalid. Move to the right.
|
||||
call s:reconstruct_tabpage_for_test(6)
|
||||
norm! 5gt
|
||||
norm! 3gt
|
||||
setl tcl=uselast
|
||||
tabclose 5
|
||||
tabclose!
|
||||
call assert_equal("n2", bufname())
|
||||
|
||||
" Same, but the last used tab page is invalid. Move to the left.
|
||||
call s:reconstruct_tabpage_for_test(6)
|
||||
norm! 5gt
|
||||
norm! 3gt
|
||||
setl tcl=uselast,left
|
||||
tabclose 5
|
||||
tabclose!
|
||||
call assert_equal("n0", bufname())
|
||||
|
||||
" Move left when moving right is not possible.
|
||||
call s:reconstruct_tabpage_for_test(6)
|
||||
setl tcl=
|
||||
norm! 6gt
|
||||
tabclose
|
||||
call assert_equal("n3", bufname())
|
||||
|
||||
" Move right when moving left is not possible.
|
||||
call s:reconstruct_tabpage_for_test(6)
|
||||
setl tcl=left
|
||||
norm! 1gt
|
||||
tabclose
|
||||
call assert_equal("n0", bufname())
|
||||
|
||||
setl tcl&
|
||||
endfunc
|
||||
|
||||
" this was giving ml_get errors
|
||||
func Test_tabpage_last_line()
|
||||
enew
|
||||
|
Loading…
Reference in New Issue
Block a user