github github
stars 305
issues 5
subscribers 3
forks 4



last year


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.


  • Neovim >= 0.7.0


Quickstart with packer

  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
    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)")

After installing, cycle buffers and display the context window by using the exemplary key bindings defined above.

Setup with other plugin managers

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.

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.

  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)
    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
      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
  filter = {
    unlisted = true,              -- filter & fallback for unlisted buffers
  fallback = function() end,      -- arbitrary fallback function
                                    -- used in excluded filetypes


  • Two modes: cycle :buffers list or cycle last used buffers
  • Adaptive size of the Cybu window
  • Various styling & positioning options
  • Exclude filetypes and define fallback
  • Autocmd events CybuOpen & CybuClose
  • Trigger context window on arbitrary autocommand events

Breaking changes

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.


  • Add possibility to further customize the entry layout
  • Offer additional modes to cycle buffers

Testing via plenary.nvim

Run tests with

make tests