Update 20240329: This repository is archived.
lazyvim-menu-addon is an add-on for LazyVim.
LazyVim is a Neovim setup powered by lazy.nvim to make it easy to customize and extend your config.
Use-case:
The user wishes to change a top-level leader menu supplied by LazyVim, in order to use the corresponding leader key for something else.
The effort required to do so manually can be considerable.
For example, when changing leader c
into leader C
,
each individual leader c
key
needs to be taken into consideration.
This addon will perform the changes automatically.
lazyvim-menu-addon.mp4
Leader keys will be changed when defined in:
- plugin definitions
- which-key menu descriptions
- lazyvim.config.keymaps
- nvim-lspconfig
Leader mappings defined by the user will not be modified.
The addon is designed to change a leader key into an available new leader key.
A decline in performance is not expected.
{ -- insert before LazyVim!
"abeldekat/lazyvim-menu-addon",
version = "*",
import = "lazyvim_menu_addon.hook",
opts = { leaders_to_change = { f = "F", w = "W" } } -- for example...
},
-- add LazyVim and import its plugins
{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
Note:
The addon must be inserted before the line that adds LazyVim in the starter template.
{
"abeldekat/lazyvim-menu-addon",
import = "lazyvim_menu_addon.hook",
opts = { leaders_to_change = { f = "F" } }
},
-- add LazyVim and import its plugins
{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
{
name = "ThePrimeagen/harpoon.nvim",
keys = {
{
"<leader>f",
function() vim.print("Harpoon UI") end,
desc = "Harpoon UI on leader f" }
},
},
Map keys for leader q
to quit and leader w
to write.
{
"abeldekat/lazyvim-menu-addon",
import = "lazyvim_menu_addon.hook",
opts = { leaders_to_change = { q = "Q", w = "W" } }
},
-- add LazyVim and import its plugins
{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
--
-- In your keymaps.lua, using a simple map function for vim.keymap.set:
--
-- leader q now available:
-- map("n", "<leader>q", "<cmd>q<cr>", { desc = "[Q]uit" })
-- leader w now available:
-- map("n", "<leader>w", "<cmd>w<cr><esc>", { desc = "[W]rite" })
{
-- Select the leaders to change and the new value to use:
---@type table<string,string>
leaders_to_change = {
-- Examples:
--
-- ["<tab>"] = "T", -- tabs
-- b = "B", -- buffer
-- c = "C", -- code
-- f = "F", -- file/find
-- g = "G", -- git
-- q = "Q", -- quit/session
-- s = "S", -- search
-- u = "U", -- ui
-- w = "W", -- window
-- x = "X", -- diagnostics/quickfix
},
}
The algorithm changing keys for nvim-lspconfig
does not differentiate
between keys defined in LazyVim
's lsp keys and keys defined by the user.
Consequently, when changing leader c
,
any leader c
defined by the user
targeting nvim-lspconfig
will be changed as well.
The user can use leader c
for other actions.
Changing keys for the lsp is explained in the docs:
The vscode extra defines a key for leader s
that is not intercepted.
When using vscode, please do not change leader s
using this addon.
The java extra is the only extra in extras.lang
using which-key.register
to map actual keys.
That method is difficult to reliably intercept.
When using the java extra,
please do not change leader c
and leader t
using this addon.
This addon injects code into the following methods:
An overview of all <leader> c
occurrences in the current codebase.
ca
-"Code Action":nvim-lspconfig
inlazyvim.plugin.lsp.keymaps
cA
-"Source Action":nvim-lspconfig
inlazyvim.plugin.lsp.keymaps
cd
-"Line Diagnostics": generic key inlazyvim.config.keymaps
cf
-"Format": generic key inlazyvim.config.keymaps
cF
-"Format Injected Langs":conform.nvim
inlazyvim.plugins.format
cl
-"Lsp Info":nvim-lspconfig
inlazyvim.plugin.lsp.keymaps
cm
-"Mason":mason.nvim
inlazyvim.plugin.lsp
cr
-"Rename":mason.nvim
inlazyvim.plugin.lsp
{
defaults = {
-- key descriptions
["<leader>c"] = "+coding"
-- more key descriptions
}
}
For example: typescript
co
-"Organize Imports":nvim-lspconfig
inlazyvim.plugins.extras.lang.typescript
cR
-"Remove Unused Imports":nvim-lspconfig
inlazyvim.plugins.extras.lang.typescript
This is the current approach.
LazyVim provides a lot of flexibility when mapping individual keys.
However, when the user wants to change a top-level menu,
in order to use that leader key
for something else,
the number of changes to perform can be considerable.
Note:
I presume that the use-case this addon addresses is not that common.
See this feature request:
feature: configurable single source of truth for keymaps
The solution proposed in this request implicates a lot of changes to the codebase. Each key mapping would require a string operation on the leader part and the actual key.
-- Feature request, the suggested solution:
{
"PrefixCode" = "<leader>c",
"KeymapMason" = "%PrefixCode%m",
"KeymapFormatInjected" = "%PrefixCode%F",
...
}
-- Current codebase: mason.nvim in lazyvim.plugins.lsp:
{
"williamboman/mason.nvim",
-- spec
keys = { { "<leader>cm", "<cmd>Mason<cr>", desc = "Mason" } },
-- more of the spec
}
Opinion:
Pros:
All keys would be configurable from one central location.
Cons:
The keys in the current codebase are readable on first sight. No need to first find out what the prefix is mapped to. Also, having a definition file covering all keys reduces the independence of the modules in the codebase.
Purpose of the addon:
This addon provides an alternative approach to the proposed solution in the feature request.
The user is expected to change individual keys as usual. The knowledge gained by doing so is very valuable. After all, LazyVim is intended to customize and extend your config.
That said, this addon can be helpful when changing a top-level leader menu,
with the intent to use the corresponding leader
key for something else.
Note:
It would be possible to incorporate the code or ideas supplied by this addon into the codebase of LazyVim