Awesome
Table of Contents
- Features
- Installation
- lazy.nvim
- Requirements
- Configuration
- Usage
- Switching to an other buffer
- Saving buffers
- Closing buffers
- Force closing buffers
- Saving all unsaved buffers
- Closing all saved buffers
- Closing multiple buffers
- Force closing multiple buffers
- Saving multiple buffers
- Toggle or show relative path
- Adding custom keymaps
- Closing buffer list window
- User commands
- General notes
- Highlight groops
- Feedback
Features
- Manage buffers (list, switch, save, close, multi-(save,close))
- Super lightweight (all the code is in a single file)
- Super fast, (since the code base is very small)
- Super easy to use, (you can list, switch and manage buffers with as few key strokes as possible)
- Highlights the buffer lines as you write them in the prompt
- Custom keymaps
- Save all unsaved
- Close all saved
- Show or toggle relative path
- Buffer unsaved icon
- Support for diagnostics
- Responsive height
- Not gluted with unnecessary features. (BufferList comes only with features that you would use)
Installation
Install the plugin with your preferred package manager:
lazy.nvim
{
"EL-MASTOR/bufferlist.nvim",
lazy = true,
keys = { { "<Leader>b", ':BufferList<CR>', desc = "Open bufferlist" } },
dependencies = "nvim-tree/nvim-web-devicons",
cmd = "BufferList",
opts = {
-- your configuration comes here
-- or leave it empty to use the default settings
-- refer to the configuration section below
},
}
Requirements
nvim-tree/nvim-web-devicons" for filetype icons.
(recommended) realpath for better relative paths generating.
Configuration
Bufferlist comes with the following defaults:
{
keymap = {
close_buf_prefix = "c",
force_close_buf_prefix = "f",
save_buf = "s",
multi_close_buf = "m",
multi_save_buf = "w",
save_all_unsaved = "a",
close_all_saved = "d0",
toggle_path = "p",
close_bufferlist = "q"
},
win_keymaps = {}, -- add keymaps to the BufferList window
bufs_keymaps = {}, -- add keymaps to each line number in the BufferList window
width = 40,
prompt = "", -- for multi_{close,save}_buf prompt
save_prompt = " ",
top_prompt = true, -- set this to false if you want the prompt to be at the bottom of the window instead of on top of it.
show_path = false, -- show the relative paths the first time BufferList window is opened
}
Usage
❗️The following key maps are buffer local key maps, they work only inside the bufferlist floating window.
❗️📑📒 Note:
<line_number>
represents the line number of the buffer name
Switching to an other buffer
press the <line_number>
of the buffer name you want to switch to (very simple, isn't this the easiest)
when the loaded buffers are 10 or more, you have to press the numbers quickly to get to the buffer who has 2 digits in
<line_number>
. For example, if you have 15 loaded buffers that are displayed in the bufferlist window, and you want to get to the buffer whose<line_number>
is 12, you need to press 1 and quickly press 2, if you're wait after pressing 1 you will go to the buffer in<line_number>
1 instead
Saving buffers
If the buffer is not saved, a circle icon is shown before the buffer name, to save it press s<line_number>
Closing buffers
Press c<line_number>
. (doesn't work when the buffer has unsaved changes)
Force closing buffers
Pressing f<line_number>
will close the buffer even if it contains unsaved changes
Saving all unsaved buffers
Press keymap.save_all_unsaved
Closing all saved buffers
Press keymap.close_all_saved
Closing multiple buffers
Press keymap.multi_close_buf
to show a prompt, and then enter the <line_number>
s of all the buffers you want to close, seperated by a seperator. The seperator should be any non-digit character, and there is no limit to the length or the kind of characters used in the seperator as long as they are not digits.
❗️Make sure that the first character isn't
!
.
❗️If you specified an unsaved buffer, it is ignored.
If a
<line_number>
you specified doesn't exist in the bufferlist window line numbers, it is ignored.
Force closing multiple buffers
Press keymap.multi_close_buf
and then enter !
at the very beginning of the prompt, and then carry on with the rest of the steps already described in Closing multiple buffers
❗️Make sure that
!
is the very first character in the prompt, it shouldn't be preceded by anything, otherwise it would behave just like Closing multiple buffers
Saving multiple buffers
Press keymap.multi_save_buf
and then enter all the <line_number>
s of the buffers you want to save seperated by a seperator. The seperator has the same characteristics described in Closing multiple buffers
Toggle or show relative path
❗️This uses the output captured from realpath if it exists
❗️If realpath doesn't exist, it uses vim's builtin
expand("#"..buffer..":~:.:h")
to do neovim's best to determine the relative path. Prefer installing realpath over this.
Toggle relative path
press keymap.toggle_path
to toggle the relative path to each buffer from the neovim cwd :pwd
.
Show relative path
set show_path
to true
to show the relative path the first time you open the BufferList window.
Adding custom keymaps
You can add custom keymaps for BufferList window via win_keymaps
option, and keymaps for buffers via bufs_keymaps
option
For BufferList window
You can assign custom keymaps to the BufferList window with win_keymaps
option.
win_keymaps
takes a table of {key, func, keymap_opts}
items.
key
: (string) Left-hand side {lhs} of the mapping.func
: (function) Right-hand side {rhs} of the mapping.- Receives one argument, a table with the following keys:
winid
: (number) the window id of the BufferList window.bl_buf
: (number) the bufferlist window scratch buffer.buffers
: (table) the listed buffers ids.open_bufferlist
: (function) function to open the BufferList window. _(useful for refreshing the BufferList window. But you will have to delete the BufferList scratch buffer first. withbwipeout
for example. As shown in the example below).
- Receives one argument, a table with the following keys:
opts
: (table) Same opts passed tovim.keymap.set()
. (Thebuffer
field is not necessary).desc
option, if not set, will be automatically set to "BufferList: custom user defined keymap". see the example bellow
This example shows how to set a custom keymap for switching buffers with the enter key, and a usless one for an unnecessary refresh:
win_keymaps = {
{
"<cr>",
function(opts)
local curpos = vim.fn.line(".")
vim.cmd("bwipeout | buffer " .. opts.buffers[curpos])
end,
{ desc = "BufferList: my description" },
},
{
"r", -- refresh the bufferlist window
function(opts)
vim.cmd('bwipeout')
opts.open_bufferlist()
end,
{} -- `desc` here isn't set. So it will be automatically set to "BufferList: custom user defined keymap"
}
},
❗️📑📒 Note: All of these keymaps are local to the BufferList. Everything will all be removed when you close the BufferList window.
Note: Using the
<cr>
keymap is not recommended, because it will slow you down since it uses more key strokes.
For buffers
You can also add keymaps to line numners in the BufferList window with bufs_keymaps
option.
bufs_keymaps
takes a table of {key, func, keymap_opts}
items.
key
: (string) Left-hand side {lhs} of the mapping. Will be suffixed with the<line_number>s
.func
: (function) Right-hand side {rhs} of the mapping.- Receives one argument, a table with the following keys:
line_number
: (number)<line_number>
pressed afterkey
bl_buf
: (number) the bufferlist window scratch buffer.buffers
: (table) the listed buffers ids.open_bufferlist
: (function) function to open the BufferList window. _(useful for refreshing the BufferList window. But you will have to delete the BufferList scratch buffer first. withbwipeout
for example. As shown in the example above).
- Receives one argument, a table with the following keys:
opts
: (table) Same opts passed tovim.keymap.set()
. (Thebuffer
field is not necessary).desc
option (if specified) will be suffixed with the icon and the bufname in the corresponding line number. Otherwise it will be "BufferList: custom user defined buffers keymap for", suffixed by the icon and the bufname. see the examples bellow.
Here is an example of adding keymaps to show the buffer in a new split window. As well as again some uselessness.
bufs_keymaps = {
{
"vs",
function(opts)
vim.cmd("bwipeout | vs " .. vim.fn.bufname(opts.buffers[opts.line_number]))
end,
{ desc = "BufferList: show buffer in a split window" }, -- `desc` (if present) will be suffixed with the contents of each line in the BufferList window. for example: "BufferList: show in a split window example.lua".
},
{
"h",
function(opts)
vim.cmd(":echo 'line_number is: " .. tostring(opts.line_number) .. ", bl_buf is: " .. tostring(opts.bl_buf) .. "'")
end,
{}, -- `desc` option is not present here, so it will automatically be set to a pre-set description with the contentsbof each line in the BufferList window. for example: "BufferList: custom user defined buffers keymap for example.lua"
},
},
Now you can press vs5
to show the buffer at line 5 in a new vertical split window. And press h3
to print a useless message.
❗️📑📒 Note: All of these keymaps are local to the BufferList. Everything will all be removed when you close the BufferList window.
Closing buffer list window
Press keymap.close_bufferlist
or just leave the bufferlist window
User commands
BufferList
General notes
❗️📑📒 Note: timeout between
<perfix>
and<line_number>
is controlled by the vim global option timeoutlen (which by default is set to 1000ms).
❗️You have to quickly press
<line_number>
before timeoutlen. Otherwise vim will enter operator pending mode and these keymaps will not work. This happens because there are global defined key maps starting one of with the keyss
,c
orf
. If you wait until timeoutlen has passed, vim will execute the global mapping instead. Therefore you have to pressEsc
and try again quicker. However it is still recommended to not remap them usingctrl
,alt
,shift
and<leader>
keys since that will add more key strokes for you.
❗️📑📒 Note: Terminal buffers are ignored in closing or multi-closing. To close them, you have to force-close them, or force-multi-close them.
💡 Tip: Does not provide keymappings for commands, or maps already builtin in nvim, (such as
:bnext
,:bufdo
,<Ctrl_6>
, ...). If you want additional mappings for buffer management and navigations, you can check out:h buffer-list
,:h editing
,:h windows
, etc... .
❗️📑📒 Note: The buffers are listed in the same order as the buffer-list (
:buffers
).
❗️📑📒 Note: Empty buffers are ignored while saving. (empty buffers usually occur when they are in the
argument-list
but not yet loaded).
📑📒 Note: Bufferlist will show icons in the virt text. If you have diagnostic icons defined (for example with
sign_defign
), bufferlist will show the latter instead.
Highlight groops
BufferListCurrentBuffer
BufferListModifiedIcon
BufferListLine
BufferListPromptSeperator
BufferListPromptForce
BufferListPromptMultiSelected
BufferListPath
Feedback
- If you've got an issue or come up with an awesome idea, don't hesitate to open an issue in github. I appreciate every suggestion.
- If you think this plugin is useful or cool, consider rewarding it with a ⭐.