Skip to content

Latest commit

History

36 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

🦿 tabout.nvim

Supercharge your workflow and start tabbing out from parentheses, quotes, and similar contexts today.

intro

💡 examples

BeforeKeyAfterSetting
{ | }<Tab>{} | -
{ |"string" }<Tab>{ "string"| } ignore_beginning = true
{ |"string" }<Tab>{ ....|"string"}ignore_beginning = false, act_as_tab = true,
{ "string"| }<S-Tab>{ |"string" } -
|#[macro_use]<Tab>#[macro_use]| tabouts = {{open = '#', close = ']'}}

📦 requirements

  • nvim >= 0.5
  • A tree-sitter parser for each language you would like to use this plugin with. You can install parsers with nvim-treesitter

💾 installation

-- Luause {
'abecodes/tabout.nvim',
config=function()
require('tabout').setup {
tabkey='<Tab>', -- key to trigger tabout, set to an empty string to disablebackwards_tabkey='<S-Tab>', -- key to trigger backwards tabout, set to an empty string to disableact_as_tab=true, -- shift content if tab out is not possibleact_as_shift_tab=false, -- reverse shift content if tab out is not possible (if your keyboard/terminal supports <S-Tab>)default_tab='<C-t>', -- shift default action (only at the beginning of a line, otherwise <TAB> is used)default_shift_tab='<C-d>', -- reverse shift default action,enable_backwards=true, -- well ...completion=true, -- if the tabkey is used in a completion pumtabouts= {
{open="'", close="'"},
{open='"', close='"'},
{open='`', close='`'},
{open='(', close=')'},
{open='[', close=']'},
{open='{', close='}'}
},
ignore_beginning=true, --[[ if the cursor is at the beginning of a filled element it will rather tab out than shift the content ]]exclude= {} -- tabout will ignore these filetypes
}
end,
wants= {'nvim-treesitter'}, -- (optional) or require if not used so farafter= {'nvim-cmp'} -- if a completion plugin is using tabs load it before
}
-- Luareturn {
{
'abecodes/tabout.nvim',
lazy=false,
config=function()
require('tabout').setup {
tabkey='<Tab>', -- key to trigger tabout, set to an empty string to disablebackwards_tabkey='<S-Tab>', -- key to trigger backwards tabout, set to an empty string to disableact_as_tab=true, -- shift content if tab out is not possibleact_as_shift_tab=false, -- reverse shift content if tab out is not possible (if your keyboard/terminal supports <S-Tab>)default_tab='<C-t>', -- shift default action (only at the beginning of a line, otherwise <TAB> is used)default_shift_tab='<C-d>', -- reverse shift default action,enable_backwards=true, -- well ...completion=false, -- if the tabkey is used in a completion pumtabouts= {
{ open="'", close="'" },
{ open='"', close='"' },
{ open='`', close='`' },
{ open='(', close=')' },
{ open='[', close=']' },
{ open='{', close='}' }
},
ignore_beginning=true, --[[ if the cursor is at the beginning of a filled element it will rather tab out than shift the content ]]exclude= {} -- tabout will ignore these filetypes
}
end,
dependencies= { -- These are optional"nvim-treesitter/nvim-treesitter",
"L3MON4D3/LuaSnip",
"hrsh7th/nvim-cmp"
},
opt=true, -- Set this to true if the plugin is optionalevent='InsertCharPre', -- Set the event to 'InsertCharPre' for better compatibilitypriority=1000,
},
{
"L3MON4D3/LuaSnip",
keys=function()
-- Disable default tab keybinding in LuaSnipreturn {}
end,
},
}

If you use another plugin manager just make sure you call tabout.nvim's setup after any completion that already uses your tabkey.

🛠️ options

tabkey

Set the key you want to use to trigger tabout.

-- defaulttabkey='<Tab>'

backwards_tabkey

Set the key you want to use to trigger tabout backwards.

-- defaultbackwards_tabkey='<S-Tab>'

act_as_tab

If a tab out is not possible shift the content.

-- defaultact_as_tab=true

act_as_shift_tab

If a backwards tab out is not possible reverse shift the content. (Depends on keyboard/terminal if it will work)

-- defaultact_as_shift_tab=false

default_tab

If act_as_tab is set to true, a tab out is not possible, and the cursor is at the beginnig of a line, this keysignals are sent in insert mode.

-- defaultdefault_tab='<C-t>'

default_shift_tab

If act_as_shift_tab is set to true and a tab out is not possible, this keysignals are sent in insert mode.

-- defaultdefault_shift_tab='<C-d>'

enable_backwards

Disable if you just want to move forward

-- defaultenable_backwards=true

completion

Consider using the Plug API and setting this to false

If you use a completion pum that also uses the tab key for a smart scroll function. Setting this to true will disable tab out when the pum is open and execute the smart scroll function instead.

See here how to integrate tabout.vim into more complex completions with snippets.

-- defaultcompletion=true

tabouts

Here you can add more symbols you want to tab out from.

open an close can only contain one character for now

-- defaulttabouts= {
{open="'", close="'"},
{open='"', close='"'},
{open='`', close='`'},
{open='(', close=')'},
{open='[', close=']'},
{open='{', close='}'}
}

ignore_beginning

If set to true you can also tab out from the beginning of a string, object property, etc.

-- defaultignore_beginning=true

more complex keybindings

You can set tabkey and backwards_tabkey to empty strings and define more complex keybindings instead.

For example, to make <Tab> and <S-Tab> work with nvim-compe, vim-vsnip and this plugin:

require("tabout").setup({
tabkey="",
backwards_tabkey="",
})
localfunctionreplace_keycodes(str)
returnvim.api.nvim_replace_termcodes(str, true, true, false)
endfunction_G.tab_binding()
ifvim.fn.pumvisible() ~=0thenreturnreplace_keycodes("<C-n>")
elseifvim.fn["vsnip#available"](1) ~=0thenreturnreplace_keycodes("<Plug>(vsnip-expand-or-jump)")
elsereturnreplace_keycodes("<Plug>(Tabout)")
endendfunction_G.s_tab_binding()
ifvim.fn.pumvisible() ~=0thenreturnreplace_keycodes("<C-p>")
elseifvim.fn["vsnip#jumpable"](-1) ~=0thenreturnreplace_keycodes("<Plug>(vsnip-jump-prev)")
elsereturnreplace_keycodes("<Plug>(TaboutBack)")
endendvim.api.nvim_set_keymap("i", "<Tab>", "v:lua.tab_binding()", {expr=true})
vim.api.nvim_set_keymap("i", "<S-Tab>", "v:lua.s_tab_binding()", {expr=true})

Note that some other plugins that also use <Tab> and <S-Tab> might provide already handlers to avoid clashes with tabout.nvim.

For example nvim-cmp mappings can be created using a function that accepts a callback. When the fallback is called tabout.nvim is working out of the box and there is no need for special configurations.

The example below shows nvim-cmp with luasnip mappings using the fallback function:

['<Tab>'] =function(fallback)
ifcmp.visible() thencmp.select_next_item()
elseifluasnip.expand_or_jumpable() thenvim.fn.feedkeys(vim.api.nvim_replace_termcodes('<Plug>luasnip-expand-or-jump', true, true, false), '')
elsefallback()
endend,
['<S-Tab>'] =function(fallback)
ifcmp.visible() thencmp.select_prev_item()
elseifluasnip.jumpable(-1) thenvim.fn.feedkeys(vim.api.nvim_replace_termcodes('<Plug>luasnip-jump-prev', true, true, false), '')
elsefallback()
endend,

To make <Tab> and <S-Tab> work with vim-vsnip:

["<Tab>"] =function(fallback)
ifcmp.visible() then-- cmp.select_next_item()cmp.confirm(
{
behavior=cmp.ConfirmBehavior.Insert,
select=true
}
)
elseifvim.fn["vsnip#available"](1) ~=0thenvim.fn.feedkeys(vim.api.nvim_replace_termcodes("<Plug>(vsnip-expand-or-jump)", true, true, true), "")
elsefallback()
endend,
["<S-Tab>"] =function(fallback)
ifcmp.visible() thencmp.select_prev_item()
elseifvim.fn["vsnip#available"](1) ~=0thenvim.fn.feedkeys(vim.api.nvim_replace_termcodes("<Plug>(vsnip-jump-prev)", true, true, true), "")
elsefallback()
endend,

See here for more nvim-cmp examples.

🤖 plug api

Modeplugaction
i<Plug>(Tabout)tabout of current context (current line)
i<Plug>(TaboutMulti)tabout of current context (multiple lines)
i<Plug>(TaboutBack)tabout backwards of current context (current line)
i<Plug>(TaboutBackMulti)tabout backwards of current context (multiple lines)

multiline tabout

-- A multiline tabout setup could look like thisvim.api.nvim_set_keymap('i', '<A-x>', "<Plug>(TaboutMulti)", {silent=true})
vim.api.nvim_set_keymap('i', '<A-z>', "<Plug>(TaboutBackMulti)", {silent=true})

📋 commands

commandtriggers
Tabout🚨 DEPRECATED tries to tab out of current context
TaboutBack🚨 DEPRECATED tries to tab out backwards of current context
TaboutToggle(de)activates the plugin

🪝 hooks

hookemits
TaboutAfterEmitted after tabout was executed
TaboutBeforeEmitted before tabout is executed
-- Using hooksvim.api.nvim_create_autocmd("User", {
pattern="TaboutAfter",
callback=--[[ your function or command here ]],
})

⚠️ exceptions

tabout.nvim only works with languages for which you have a tree-sitter parser installed. See for example nvim-treesitter's supported filetypes.

About

tabout plugin for neovim

Topics

Resources

Stars

861 stars

Watchers

3 watching

Forks

Used by

Contributors

Languages