Have you ever had trouble remembering keybinds, commands or functions for features you rarely use?
Have you ever wished you could make better use of the hundred of features that come with plugins like snacks.nvim? Wished you remembered keybinds for all pickers, menus and options...
In this gist, I'll show you how to create a simple and useful menu for your neovim configurations, using Snacks.nvim and (optional) which-key.nvim.
In 200 lines you will learn how to create menu that is searchable, displays keybinds and lets you easily find what you're looking for, without sifting through :h <option>.
Features:
- Fuzzy finder for options thanks to snacks picker
- Icons and tags to make categories easier to distinguish
- Automatic keybinds, when you require them
- Fully integrated with which-key.nvim, your options descriptions and icons will be visible in which-key
- Extensible at will
Put the menu.lua somwhere in your .config/nvim/lua
To use the menu, you must first initialize the module (e.g in your init.lua):
require("menu").setup()Then bind menu.show() to a key:
wk.add({ "<leader>e", function() require("menu").show() end, desc = "Menu" })Of course, you'll need to change require("menu") to the module path of the script.
I greatly encourage you to read, learn and modify the script as it's very short and easy to understand. It's simple to extend and add new features, as you require them.
Adding options is as simple as adding a new entry in the options table.
Menu options can be customized at will to perform any kind of actions when selected.
The script exposes these two functions to make your life easier:
MenuAction
This is for options that simply run a command or function when selected in the menu.
MenuAction {
-- Optional keybind for this action, accept an array of strings if you want to set multiple keybinds
key = "<leader>uC",
-- Description of the option
desc = "Colorschemes",
-- Optional icon, will use a default icon if unset
icon = " ",
-- Optional list of tags, to make searching and categorizing easier
tags = { "ui", "menu" },
-- Function called when this option is selected
callback = functiopn() Snacks.picker.colorschemes() end
},MenuToggle
This is for toggle-able actions.
MenuToggle {
-- Optional keybind for this action, accept an array of strings if you want to set multiple keybinds
key = "<leader>un",
-- Description of the option
desc = "Toggle line numbers",
-- Optional list of tags, to make searching and categorizing easier
tags = { "ui" },
-- Function to check if this option is enabled or disabled, must return a boolean
is_active = function()
return vim.api.nvim_get_option_value("number", { scope = "local" })
end,
-- Function called when this option is selected, capture argument `self`
callback = function(self)
if self:is_active() then
vim.opt.number = false
vim.opt.relativenumber = false
else
vim.opt.number = true
vim.opt.relativenumber = true
end
end,
},In all options, you can add a init field that must contain a function that will be called when setup() is called on the module. All functions are called with self as their first argument so you may use it for more complex options.
That's all, hope you enjoy building menus with this simple script.
