Cy[cle]bu[ffer].nvim provides two modes. The first is essentially a wrapper around :bnext
& :bprevious
, which adds a customizable notification window, that shows the buffer in focus and its neighbors, to provide context when cycling the buffer list with the provided plugin commands / key bindings.
The second mode adds the same customizable window providing context, but the list of buffers is ordered by last used. It is more akin to the [Ctrl] + [Tab]
functionality a web browser might provide.
See :help cybu.nvim for the docs.
use({
"ghillb/cybu.nvim",
branch = "main", -- timely updates
-- branch = "v1.x", -- won't receive breaking changes
requires = { "nvim-tree/nvim-web-devicons", "nvim-lua/plenary.nvim"}, -- optional for icon support
config = function()
local ok, cybu = pcall(require, "cybu")
if not ok then
return
end
cybu.setup()
vim.keymap.set("n", "K", "<Plug>(CybuPrev)")
vim.keymap.set("n", "J", "<Plug>(CybuNext)")
vim.keymap.set({"n", "v"}, "<c-s-tab>", "<plug>(CybuLastusedPrev)")
vim.keymap.set({"n", "v"}, "<c-tab>", "<plug>(CybuLastusedNext)")
end,
})
After installing, cycle buffers and display the context window by using the exemplary key bindings defined above.
If you use another plugin manager, install "ghillb/cybu.nvim"
and optionally "nvim-tree/nvim-web-devicons"
with it, like you would with any other plugin.
Setup up Cybu by calling its setup function and placing the respective key bindings, somewhere into your init.lua
.
require("cybu").setup()
vim.keymap.set("n", "[b", "<Plug>(CybuPrev)")
vim.keymap.set("n", "]b", "<Plug>(CybuNext)")
vim.keymap.set("n", "<s-tab>", "<plug>(CybuLastusedPrev)")
vim.keymap.set("n", "<tab>", "<plug>(CybuLastusedNext)")
Hint: If you use the <tab>
key, map vim.keymap.set( "n", "<c-i>", "<c-i>")
to keep it separate from <c-i>
(See: neovim/pull/17932).
If you want to customize the appearance and behaviour of Cybu, you can do it by adapting the configuration table.
require("cybu").setup({
position = {
relative_to = "win", -- win, editor, cursor
anchor = "topcenter", -- topleft, topcenter, topright,
-- centerleft, center, centerright,
-- bottomleft, bottomcenter, bottomright
vertical_offset = 10, -- vertical offset from anchor in lines
horizontal_offset = 0, -- vertical offset from anchor in columns
max_win_height = 5, -- height of cybu window in lines
max_win_width = 0.5, -- integer for absolute in columns
-- float for relative to win/editor width
},
style = {
path = "relative", -- absolute, relative, tail (filename only),
-- tail_dir (filename & parent dir)
path_abbreviation = "none", -- none, shortened
border = "rounded", -- single, double, rounded, none
separator = " ", -- string used as separator
prefix = "…", -- string used as prefix for truncated paths
padding = 1, -- left & right padding in number of spaces
hide_buffer_id = true, -- hide buffer IDs in window
devicons = {
enabled = true, -- enable or disable web dev icons
colored = true, -- enable color for web dev icons
truncate = true, -- truncate wide icons to one char width
},
highlights = { -- see highlights via :highlight
current_buffer = "CybuFocus", -- current / selected buffer
adjacent_buffers = "CybuAdjacent", -- buffers not in focus
background = "CybuBackground", -- window background
border = "CybuBorder", -- border of the window
},
},
behavior = { -- set behavior for different modes
mode = {
default = {
switch = "immediate", -- immediate, on_close
view = "rolling", -- paging, rolling
},
last_used = {
switch = "on_close", -- immediate, on_close
view = "paging", -- paging, rolling
update_on = "buf_enter", -- buf_enter, cursor_moved
},
auto = {
view = "rolling", -- paging, rolling
},
},
show_on_autocmd = false, -- event to trigger cybu (eg. "BufEnter")
},
display_time = 750, -- time the cybu window is displayed
exclude = { -- filetypes, cybu will not be active
"neo-tree",
"fugitive",
"qf",
},
filter = {
unlisted = true, -- filter & fallback for unlisted buffers
},
fallback = function() end, -- arbitrary fallback function
-- used in excluded filetypes
})
:buffers
list or cycle last used buffersCybuOpen
& CybuClose
The update_on
option in last_used
mode controls when buffers are moved to the most recently used position:
"buf_enter"
(default): Updates MRU order on every buffer switch"cursor_moved"
: Only updates MRU when cursor moves in the buffer"text_changed"
: Only updates MRU when text is actually editedrequire("cybu").setup({
behavior = {
mode = {
last_used = {
update_on = "text_changed",
}
}
}
})
⚠️ Experimental Feature: This feature is experimental and the API may change in future versions. Use with caution in production environments.
You can integrate cybu with other buffer management plugins like grapple.nvim or harpoon.nvim by providing a custom buffer provider function:
require("cybu").setup({
experimental = {
buffer_provider = function()
-- Return table of buffer objects: {{bufnr=1, filename="file.lua"}, ...}
-- Logic to fetch buffers from your preferred source
return custom_buffer_list
end
}
})
See examples/buffer_providers.lua
for working examples with grapple.nvim, harpoon.nvim, and advanced usage patterns.
If breaking changes (will be kept to a minimum) are of no concern to you, use the main
branch. Otherwise you can use the version pinned branches, e.g. v1.x
. These branches will only receive bug fixes and other non-breaking changes.
Run tests with
make tests