tabby.nvim
A minimal, configurable, neovim style tabline. Use your nvim tabs as workspace multiplexer!
Feature
tabby.nvim is not buffers' list
Tabby.nvim focuses on a vim-style tab instead of buffers list, so tabby only displays the buffers in tabpage(although you can use low-level API to write a bufferline). On the other hand, If you use some plugin such as "fzf" or "telescope," you will find the bufferline unnecessary. In that case, you may want to use the tab as its original feature: be a windows layout multiplexer. That might be the reason why you choose tabby.nvim.
highly configurable and easy to start
With tabby.nvim, you can config your own tabline from scratch. And won't worry the complexy, you can start from presets and example. As tabby.nvim have complete type annotations (powered by EmmyLua), so you can write config with the help of lua-language-server.
Quick start
Use your plugin manager to installing:
"kyazdani42/nvim-web-devicons",
"nanozuki/tabby.nvim",
The nvim-web-devicons
provide the icon support, you may like to use a nerdfonts-patched font. If your config dont use icons, you have no need to install that.
And setup tabby in your config file:
require"tabby".setup()
If you use packer:
use {
"nanozuki/tabby.nvim",
requires = "kyazdani42/nvim-web-devicons",
config = function() require("tabby").setup() end,
}
Use presets
Built-in presets only use the highlight group Tabline
, TablineSel
, TablineFill
and Normal
, to support most colorschemes. To use presets:
require("tabby").setup({
tabline = require("tabby.presets").tab_with_top_win,
})
There are three presets for now:
- active_wins_at_tail [default]
Put all windows' labels in active tabpage at end of whold tabline.
- active_wins_at_end
Put all windows' labels in active tabpage after all tags label. In-active tabpage's window won't display.
- tab_with_top_win
Each tab lab with a top window label followed. The top window
is the focus window when you enter a tabpage.
- active_tab_with_wins
Active tabpage's windows' labels is displayed after the active tabpage's label.
- tab_only
No windows label, only tab. and use focus window to name tab
Key mapping
Tabby use native nvim tab, so you can directly use nvim tab operation. Maybe you can mapping some operation. For example:
vim.api.nvim_set_keymap("n", "<leader>ta", ":$tabnew<CR>", { noremap = true })
vim.api.nvim_set_keymap("n", "<leader>tc", ":tabclose<CR>", { noremap = true })
vim.api.nvim_set_keymap("n", "<leader>to", ":tabonly<CR>", { noremap = true })
vim.api.nvim_set_keymap("n", "<leader>tn", ":tabn<CR>", { noremap = true })
vim.api.nvim_set_keymap("n", "<leader>tp", ":tabp<CR>", { noremap = true })
-- move current tab to preview position
vim.api.nvim_set_keymap("n", "<leader>tmp", ":-tabmove<CR>", { noremap = true })
-- move current tab to next position
vim.api.nvim_set_keymap("n", "<leader>tmn", ":+tabmove<CR>", { noremap = true })
Customize
Customize tabby with tabby.setup(opt)
, the opt definiation is:
--[email protected] TabbyOption
--[email protected] tabline? TabbyTablineOpt high-level api
--[email protected] components? fun():TabbyComponent[] low-level api
Base object for text
The basic config unit in tabby is TabbyText
. It's a set of text content, highlight group and layout setting. You may use it in many places. The type definiation is:
--[email protected] TabbyText
--[email protected] [1] string|fun():string text content or a function to return context
--[email protected] hl nil|string|TabbyHighlight
--[email protected] lo nil|TabbyLayout
--[email protected] TabbyHighlight
--[email protected] fg string hex color for foreground
--[email protected] bg string hex color for background
--[email protected] style string Highlight gui style
--[email protected] name string highlight group name
--[email protected] TabbyLayout
--[email protected] max_width number
--[email protected] min_width number
--[email protected] justify "left"|"right" default is left
For example:
local text1 = { "Tab 1" }
local text2 = {
"Tab 2",
hl = "TablineSel",
}
local text3 = {
"Tab 3",
hl = { fg = my_hl.fg, bg = my_hl.bg, style = "bold" },
lo = { min_width = 20, justify = "right" },
}
local cwd = {
function()
return " " .. vim.fn.fnamemodify(vim.fn.getcwd(), ":t") .. " "
end
hl = "TablineSel",
}
There is a util for extract values from highlight:
local hl_normal = util.extract_nvim_hl("Normal")
local labal = {
" " .. tabid .. " ",
hl = { fg = hl_normal.fg, bg = hl_normal.bg, style = "bold" },
}
Customize with high level apis
Through setting the TabbyOption.tabline
to use the high-level api to customize tabby. You can edit one of the three built-in layouts. (Corresponding to the three preset values)
--[email protected] TabbyTablineOpt
--[email protected] layout TabbyTablineLayout
--[email protected] hl TabbyHighlight background highlight
--[email protected] head? TabbyText[] display at start of tabline
--[email protected] active_tab TabbyTabLabelOpt
--[email protected] inactive_tab TabbyTabLabelOpt
--[email protected] win TabbyWinLabelOpt
--[email protected] active_win? WinLabelOpt need by "tab_with_top_win", fallback to win if this is nil
--[email protected] top_win? TabbyWinLabelOpt need by "active_tab_with_wins" and "active_wins_at_end", fallback to win if this is nil
--[email protected] tail? TabbyText[] display at end of tabline
--[email protected] TabbyTablineLayout
---| "active_tab_with_wins" # windows label follow active tab
---| "active_wins_at_end" # windows in active tab will be display at end of all tab labels
---| "tab_with_top_win" # the top window display after each tab.
--[email protected] TabbyTabLabelOpt
--[email protected] label string|TabbyText|fun(tabid:number):TabbyText
--[email protected] left_sep string|TabbyText
--[email protected] right_sep string|TabbyText
--[email protected] TabbyWinLabelOpt
--[email protected] label string|TabbyText|fun(winid:number):TabbyText
--[email protected] left_sep string|TabbyText
--[email protected] inner_sep string|TabbyText won't works in "tab_with_top_win" layout
--[email protected] right_sep string|TabbyText
You can find three presets config for example.
Customize with low level apis
If built-in layouts do not satisfy you, you can also use the low-level API to define the tabline from scratch by setting TabbyOption.components
.
TabbyOption.components
is a function which return an array of TabbyComponent
. The TabbyComponent
is object like:
{
"type": "<component type>",
-- "... config ..."
}
This are all TabbyComponents:
- TabbyComTab
TabbyComTab can receive a tabid to render a tab label.
--[email protected] TabbyComTab
--[email protected] type "tab"
--[email protected] tabid number
--[email protected] label string|TabbyText
--[email protected] left_sep TabbyText
--[email protected] right_sep TabbyText
- TabbyComWin
TabbyComWin can receive a winid to render a window label.
--[email protected] TabbyComWin
--[email protected] type "win"
--[email protected] winid number
--[email protected] label TabbyText
--[email protected] left_sep TabbyText
--[email protected] right_sep TabbyText
- TabbyComText
TabbyComText for rendering static text.
--[email protected] TabbyComText
--[email protected] type "text"
--[email protected] text TabbyText
- TabbyComSpring
TabbyComSpring mark a separation point. Each separation point will be print as equal number of spaces.
--[email protected] TabbyComSpring
--[email protected] type "spring"
Example
For example, we can use low-level api to define the presets active_wins_at_end
:
TODO
- Rename tab
- Unique short name for window label
- Button for close tab and add tab
- Custom click handler
- Telescope support