NOTE: Main development is now on the branch snipe2
, try it out and let me know what
you think! To switch to the branch just add branch = "snipe2"
in your lazy plugin spec.
Efficient targetted menu built for fast buffer navigation
Snipe.nvim
is selection menu that can accept any list of items
and present a user interface with quick minimal character navigation
hints to select exactly what you want. It is not flashy it is just
fast !
If you ever find yourself in a tangle of buffers scrabbling to find your way back to where you came from, this plugin can help ! Maybe you use harpoon, this is great for project files, but what if you want a fast fallback for when you're in someone else's project. Maybe you use telescope, but that can feel inconsistent and visually distracting. This is why I made this, because I wanted a Vimium-like way of hopping around a large amount of buffers
For lazy.nvim
:
{
"leath-dub/snipe.nvim",
keys = {
{"gb", function () require("snipe").open_buffer_menu() end, desc = "Open Snipe buffer menu"}
},
opts = {}
}
For packadd
(builtin package manager), clone the repo into $HOME/.config/nvim/pack/snipe/opt/snipe.nvim
and add this to your configuration:
vim.cmd.packadd "snipe.nvim"
local snipe = require("snipe")
snipe.setup()
vim.keymap.set("n", "gb", snipe.open_buffer_menu)
You can pass in a table of options to the setup
function, here are the default options:
Snipe.config = {
ui = {
max_width = -1, -- -1 means dynamic width
-- Where to place the ui window
-- Can be any of "topleft", "bottomleft", "topright", "bottomright", "center", "cursor" (sets under the current cursor pos)
position = "topleft",
-- Override options passed to `nvim_open_win`
-- Be careful with this as snipe will not validate
-- anything you override here. See `:h nvim_open_win`
-- for config options
open_win_override = {
-- title = "My Window Title",
border = "single", -- use "rounded" for rounded border
},
},
hints = {
-- Charaters to use for hints (NOTE: make sure they don't collide with the navigation keymaps)
dictionary = "sadflewcmpghio",
},
navigate = {
-- When the list is too long it is split into pages
-- `[next|prev]_page` options allow you to navigate
-- this list
next_page = "J",
prev_page = "K",
-- You can also just use normal navigation to go to the item you want
-- this option just sets the keybind for selecting the item under the
-- cursor
under_cursor = "<cr>",
-- In case you changed your mind, provide a keybind that lets you
-- cancel the snipe and close the window.
cancel_snipe = "<esc>",
-- Close the buffer under the cursor
-- Remove "j" and "k" from your dictionary to navigate easier to delete
-- NOTE: Make sure you don't use the character below on your dictionary
close_buffer = "D",
},
-- The default sort used for the buffers
-- Can be any of "last", (sort buffers by last accessed) "default" (sort buffers by its number)
sort = "default"
}
You can also pass options to create_buffer_menu_toggler
:
{
-- Limit the width of path buffer names
-- /my/long/path/is/really/annoying will be is/really/annoying (max of 3)
max_path_width = 3
}
The following User
events can be hooked into:
SnipeCreateBuffer
- event is triggered after tag and default mappings are set. The following code allows you to hook into this:
vim.api.nvim_create_autocmd("User", {
pattern = "SnipeCreateBuffer",
callback = function (args)
-- | Format of `args`:
--
-- args = {
-- data = {
-- menu = {
-- close = <function>,
-- open = <function>,
-- is_open = <function>,
-- }
-- buf = <menu bufnr>,
-- }
-- }
-- Do something with args
end,
})
A producer is just a function that returns two lists (tables), the first is a user/meta-data
table, this is will
later be passed into a callback allowing you to give context to the selections (e.g. for buffer producer the meta-data
is the list of buffer-id's). The second table is the list of actual strings you want to list as selections.
Below is an example of a file producer:
local function file_menu_toggler()
local function file_producer()
local uv = (vim.loop or vim.uv)
local items = {}
for name, type in vim.fs.dir(uv.cwd()) do
table.insert(items, { type, name })
end
local items_display = vim.tbl_map(function (ent)
return string.format("%s %s", (ent[1] == "file" and "F" or "D"), ent[2])
end, items)
return items, items_display
end
return snipe.create_menu_toggler(file_producer, function (meta, _) vim.cmd.edit(meta[2]) end)
end
vim.keymap.set("n", "<leader>f", file_menu_toggler())
This lets you navigate files in the current directory with <leader>f