mirror of
https://github.com/LazyVim/LazyVim.git
synced 2025-07-06 23:44:41 +02:00
feat(keymaps): dynamic which-key icons/descriptions for toggles
This commit is contained in:
parent
6911327a5e
commit
82a3ccc4d6
5 changed files with 192 additions and 115 deletions
|
@ -115,20 +115,19 @@ map("n", "[w", diagnostic_goto(false, "WARN"), { desc = "Prev Warning" })
|
|||
-- stylua: ignore start
|
||||
|
||||
-- toggle options
|
||||
map("n", "<leader>uf", function() LazyVim.format.toggle() end, { desc = "Toggle Auto Format (Global)" })
|
||||
map("n", "<leader>uF", function() LazyVim.format.toggle(true) end, { desc = "Toggle Auto Format (Buffer)" })
|
||||
map("n", "<leader>us", function() LazyVim.toggle("spell") end, { desc = "Toggle Spelling" })
|
||||
map("n", "<leader>uw", function() LazyVim.toggle("wrap") end, { desc = "Toggle Word Wrap" })
|
||||
map("n", "<leader>uL", function() LazyVim.toggle("relativenumber") end, { desc = "Toggle Relative Line Numbers" })
|
||||
map("n", "<leader>ul", function() LazyVim.toggle.number() end, { desc = "Toggle Line Numbers" })
|
||||
map("n", "<leader>ud", function() LazyVim.toggle.diagnostics() end, { desc = "Toggle Diagnostics" })
|
||||
local conceallevel = vim.o.conceallevel > 0 and vim.o.conceallevel or 3
|
||||
map("n", "<leader>uc", function() LazyVim.toggle("conceallevel", false, {0, conceallevel}) end, { desc = "Toggle Conceal" })
|
||||
if vim.lsp.buf.inlay_hint or vim.lsp.inlay_hint then
|
||||
map( "n", "<leader>uh", function() LazyVim.toggle.inlay_hints() end, { desc = "Toggle Inlay Hints" })
|
||||
LazyVim.toggle.map("<leader>uf", LazyVim.toggle.format())
|
||||
LazyVim.toggle.map("<leader>uF", LazyVim.toggle.format(true))
|
||||
LazyVim.toggle.map("<leader>us", LazyVim.toggle("spell"))
|
||||
LazyVim.toggle.map("<leader>uw", LazyVim.toggle("wrap"))
|
||||
LazyVim.toggle.map("<leader>uL", LazyVim.toggle("relativenumber"))
|
||||
LazyVim.toggle.map("<leader>ud", LazyVim.toggle.diagnostics)
|
||||
LazyVim.toggle.map("<leader>ul", LazyVim.toggle.number)
|
||||
LazyVim.toggle.map("<leader>uc", LazyVim.toggle("conceallevel", {0, vim.o.conceallevel > 0 and vim.o.conceallevel or 3}))
|
||||
LazyVim.toggle.map("<leader>uT", LazyVim.toggle.treesitter)
|
||||
LazyVim.toggle.map("<leader>ub", LazyVim.toggle("background", false, {"light", "dark"}))
|
||||
if vim.lsp.inlay_hint then
|
||||
LazyVim.toggle.map("<leader>uh", LazyVim.toggle.inlay_hints)
|
||||
end
|
||||
map("n", "<leader>uT", function() if vim.b.ts_highlight then vim.treesitter.stop() else vim.treesitter.start() end end, { desc = "Toggle Treesitter Highlight" })
|
||||
map("n", "<leader>ub", function() LazyVim.toggle("background", false, {"light", "dark"}) end, { desc = "Toggle Background" })
|
||||
|
||||
-- lazygit
|
||||
map("n", "<leader>gg", function() LazyVim.lazygit( { cwd = LazyVim.root.git() }) end, { desc = "Lazygit (Root Dir)" })
|
||||
|
@ -181,7 +180,7 @@ map("n", "<leader>w-", "<C-W>s", { desc = "Split Window Below", remap = true })
|
|||
map("n", "<leader>w|", "<C-W>v", { desc = "Split Window Right", remap = true })
|
||||
map("n", "<leader>-", "<C-W>s", { desc = "Split Window Below", remap = true })
|
||||
map("n", "<leader>|", "<C-W>v", { desc = "Split Window Right", remap = true })
|
||||
map("n", "<leader>wm", function() LazyVim.toggle.maximize() end, { desc = "Maximize Toggle" })
|
||||
LazyVim.toggle.map("<leader>wm", LazyVim.toggle.maximize)
|
||||
|
||||
-- tabs
|
||||
map("n", "<leader><tab>l", "<cmd>tablast<cr>", { desc = "Last Tab" })
|
||||
|
|
|
@ -193,7 +193,7 @@ return {
|
|||
function()
|
||||
require("which-key").show({ global = false })
|
||||
end,
|
||||
desc = "Buffer Local Keymaps (which-key)",
|
||||
desc = "Buffer Keymaps (which-key)",
|
||||
},
|
||||
},
|
||||
config = function(_, opts)
|
||||
|
|
|
@ -150,7 +150,7 @@ return {
|
|||
and vim.bo[buffer].buftype == ""
|
||||
and not vim.tbl_contains(opts.inlay_hints.exclude, vim.bo[buffer].filetype)
|
||||
then
|
||||
LazyVim.toggle.inlay_hints(buffer, true)
|
||||
vim.lsp.inlay_hint.enable(true, { bufnr = buffer })
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
|
|
@ -97,10 +97,19 @@ end
|
|||
|
||||
---@param buf? boolean
|
||||
function M.toggle(buf)
|
||||
M.enable(not M.enabled(), buf)
|
||||
end
|
||||
|
||||
---@param enable? boolean
|
||||
---@param buf? boolean
|
||||
function M.enable(enable, buf)
|
||||
if enable == nil then
|
||||
enable = true
|
||||
end
|
||||
if buf then
|
||||
vim.b.autoformat = not M.enabled()
|
||||
vim.b.autoformat = enable
|
||||
else
|
||||
vim.g.autoformat = not M.enabled()
|
||||
vim.g.autoformat = enable
|
||||
vim.b.autoformat = nil
|
||||
end
|
||||
M.info()
|
||||
|
|
|
@ -1,114 +1,183 @@
|
|||
---@class lazyvim.util.toggle
|
||||
local M = {}
|
||||
|
||||
---@param silent boolean?
|
||||
---@class lazyvim.Toggle
|
||||
---@field name string
|
||||
---@field get fun():boolean
|
||||
---@field set fun(state:boolean)
|
||||
---@overload fun()
|
||||
local T = {}
|
||||
T.__index = T
|
||||
|
||||
---@param lhs string
|
||||
---@param toggle lazyvim.Toggle
|
||||
function M.map(lhs, toggle)
|
||||
LazyVim.safe_keymap_set("n", lhs, function()
|
||||
local state = not toggle.get()
|
||||
toggle.set(state)
|
||||
if state then
|
||||
LazyVim.info("Enabled " .. toggle.name, { title = toggle.name })
|
||||
else
|
||||
LazyVim.warn("Disabled " .. toggle.name, { title = toggle.name })
|
||||
end
|
||||
end, { desc = "Toggle" .. toggle.name })
|
||||
require("which-key").add({
|
||||
{
|
||||
lhs,
|
||||
icon = function()
|
||||
return toggle.get() and { icon = " ", color = "green" } or { icon = " ", color = "yellow" }
|
||||
end,
|
||||
desc = function()
|
||||
return (toggle.get() and "Disable " or "Enable ") .. toggle.name
|
||||
end,
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
---@type lazyvim.Toggle
|
||||
M.treesitter = {
|
||||
name = "Treesitter Highlight",
|
||||
get = function()
|
||||
return vim.b.ts_highlight
|
||||
end,
|
||||
set = function(state)
|
||||
if state then
|
||||
vim.treesitter.start()
|
||||
else
|
||||
vim.treesitter.stop()
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
---@param buf? boolean
|
||||
function M.format(buf)
|
||||
---@type lazyvim.Toggle
|
||||
local ret = {
|
||||
name = "Auto Format (" .. (buf and "Buffer" or "Global") .. ")",
|
||||
get = function()
|
||||
if not buf then
|
||||
return vim.g.autoformat == nil or vim.g.autoformat
|
||||
end
|
||||
return LazyVim.format.enabled()
|
||||
end,
|
||||
set = function(state)
|
||||
LazyVim.format.enable(state, buf)
|
||||
end,
|
||||
}
|
||||
return ret
|
||||
end
|
||||
|
||||
---@param values? {[1]:any, [2]:any}
|
||||
function M.option(option, silent, values)
|
||||
if values then
|
||||
if vim.opt_local[option]:get() == values[1] then
|
||||
---@diagnostic disable-next-line: no-unknown
|
||||
vim.opt_local[option] = values[2]
|
||||
else
|
||||
---@diagnostic disable-next-line: no-unknown
|
||||
vim.opt_local[option] = values[1]
|
||||
end
|
||||
return LazyVim.info("Set " .. option .. " to " .. vim.opt_local[option]:get(), { title = "Option" })
|
||||
end
|
||||
---@diagnostic disable-next-line: no-unknown
|
||||
vim.opt_local[option] = not vim.opt_local[option]:get()
|
||||
if not silent then
|
||||
if vim.opt_local[option]:get() then
|
||||
LazyVim.info("Enabled " .. option, { title = "Option" })
|
||||
else
|
||||
LazyVim.warn("Disabled " .. option, { title = "Option" })
|
||||
end
|
||||
end
|
||||
function M.option(option, values)
|
||||
---@type lazyvim.Toggle
|
||||
local ret = {
|
||||
name = option,
|
||||
get = function()
|
||||
if values then
|
||||
return vim.opt_local[option]:get() == values[2]
|
||||
end
|
||||
return vim.opt_local[option]:get()
|
||||
end,
|
||||
set = function(state)
|
||||
if values then
|
||||
if state then
|
||||
vim.opt_local[option] = values[1]
|
||||
else
|
||||
vim.opt_local[option] = values[2]
|
||||
end
|
||||
else
|
||||
---@diagnostic disable-next-line: no-unknown
|
||||
vim.opt_local[option] = state
|
||||
end
|
||||
end,
|
||||
}
|
||||
return ret
|
||||
end
|
||||
|
||||
local nu = { number = true, relativenumber = true }
|
||||
function M.number()
|
||||
if vim.opt_local.number:get() or vim.opt_local.relativenumber:get() then
|
||||
nu = { number = vim.opt_local.number:get(), relativenumber = vim.opt_local.relativenumber:get() }
|
||||
vim.opt_local.number = false
|
||||
vim.opt_local.relativenumber = false
|
||||
LazyVim.warn("Disabled line numbers", { title = "Option" })
|
||||
else
|
||||
vim.opt_local.number = nu.number
|
||||
vim.opt_local.relativenumber = nu.relativenumber
|
||||
LazyVim.info("Enabled line numbers", { title = "Option" })
|
||||
end
|
||||
end
|
||||
---@type lazyvim.Toggle
|
||||
M.number = {
|
||||
name = "Line Numbers",
|
||||
get = function()
|
||||
return vim.opt_local.number:get() or vim.opt_local.relativenumber:get()
|
||||
end,
|
||||
set = function(state)
|
||||
if state then
|
||||
vim.opt_local.number = nu.number
|
||||
vim.opt_local.relativenumber = nu.relativenumber
|
||||
else
|
||||
nu = { number = vim.opt_local.number:get(), relativenumber = vim.opt_local.relativenumber:get() }
|
||||
vim.opt_local.number = false
|
||||
vim.opt_local.relativenumber = false
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
local enabled = true
|
||||
function M.diagnostics()
|
||||
-- if this Neovim version supports checking if diagnostics are enabled
|
||||
-- then use that for the current state
|
||||
if vim.diagnostic.is_enabled then
|
||||
enabled = vim.diagnostic.is_enabled()
|
||||
elseif vim.diagnostic.is_disabled then
|
||||
enabled = not vim.diagnostic.is_disabled()
|
||||
end
|
||||
enabled = not enabled
|
||||
|
||||
if enabled then
|
||||
vim.diagnostic.enable()
|
||||
LazyVim.info("Enabled diagnostics", { title = "Diagnostics" })
|
||||
else
|
||||
vim.diagnostic.disable()
|
||||
LazyVim.warn("Disabled diagnostics", { title = "Diagnostics" })
|
||||
end
|
||||
end
|
||||
|
||||
---@param buf? number
|
||||
---@param value? boolean
|
||||
function M.inlay_hints(buf, value)
|
||||
local ih = vim.lsp.buf.inlay_hint or vim.lsp.inlay_hint
|
||||
if type(ih) == "function" then
|
||||
ih(buf, value)
|
||||
elseif type(ih) == "table" and ih.enable then
|
||||
if value == nil then
|
||||
value = not ih.is_enabled({ bufnr = buf or 0 })
|
||||
---@type lazyvim.Toggle
|
||||
M.diagnostics = {
|
||||
name = "Diagnostics",
|
||||
get = function()
|
||||
if vim.diagnostic.is_enabled then
|
||||
enabled = vim.diagnostic.is_enabled()
|
||||
elseif vim.diagnostic.is_disabled then
|
||||
enabled = not vim.diagnostic.is_disabled()
|
||||
end
|
||||
ih.enable(value, { bufnr = buf })
|
||||
end
|
||||
end
|
||||
return enabled
|
||||
end,
|
||||
set = vim.diagnostic.enable,
|
||||
}
|
||||
|
||||
---@type lazyvim.Toggle
|
||||
M.inlay_hints = {
|
||||
name = "Inlay Hints",
|
||||
get = function()
|
||||
return vim.lsp.inlay_hint.is_enabled({ bufnr = 0 })
|
||||
end,
|
||||
set = function(state)
|
||||
vim.lsp.inlay_hint.enable(state, { bufnr = 0 })
|
||||
end,
|
||||
}
|
||||
|
||||
---@type {k:string, v:any}[]
|
||||
M._maximized = nil
|
||||
---@param state boolean?
|
||||
function M.maximize(state)
|
||||
if state == (M._maximized ~= nil) then
|
||||
return
|
||||
end
|
||||
if M._maximized then
|
||||
for _, opt in ipairs(M._maximized) do
|
||||
vim.o[opt.k] = opt.v
|
||||
---@type lazyvim.Toggle
|
||||
M.maximize = {
|
||||
name = "Maximize",
|
||||
get = function()
|
||||
return M._maximized ~= nil
|
||||
end,
|
||||
set = function(state)
|
||||
if state then
|
||||
M._maximized = {}
|
||||
local function set(k, v)
|
||||
table.insert(M._maximized, 1, { k = k, v = vim.o[k] })
|
||||
vim.o[k] = v
|
||||
end
|
||||
set("winwidth", 999)
|
||||
set("winheight", 999)
|
||||
set("winminwidth", 10)
|
||||
set("winminheight", 4)
|
||||
vim.cmd("wincmd =")
|
||||
-- `QuitPre` seems to be executed even if we quit a normal window, so we don't want that
|
||||
-- `VimLeavePre` might be another consideration? Not sure about differences between the 2
|
||||
vim.api.nvim_create_autocmd("ExitPre", {
|
||||
once = true,
|
||||
group = vim.api.nvim_create_augroup("lazyvim_restore_max_exit_pre", { clear = true }),
|
||||
desc = "Restore width/height when close Neovim while maximized",
|
||||
callback = function()
|
||||
M.maximize.set(false)
|
||||
end,
|
||||
})
|
||||
else
|
||||
for _, opt in ipairs(M._maximized) do
|
||||
vim.o[opt.k] = opt.v
|
||||
end
|
||||
M._maximized = nil
|
||||
vim.cmd("wincmd =")
|
||||
end
|
||||
M._maximized = nil
|
||||
vim.cmd("wincmd =")
|
||||
else
|
||||
M._maximized = {}
|
||||
local function set(k, v)
|
||||
table.insert(M._maximized, 1, { k = k, v = vim.o[k] })
|
||||
vim.o[k] = v
|
||||
end
|
||||
set("winwidth", 999)
|
||||
set("winheight", 999)
|
||||
set("winminwidth", 10)
|
||||
set("winminheight", 4)
|
||||
vim.cmd("wincmd =")
|
||||
end
|
||||
-- `QuitPre` seems to be executed even if we quit a normal window, so we don't want that
|
||||
-- `VimLeavePre` might be another consideration? Not sure about differences between the 2
|
||||
vim.api.nvim_create_autocmd("ExitPre", {
|
||||
once = true,
|
||||
group = vim.api.nvim_create_augroup("lazyvim_restore_max_exit_pre", { clear = true }),
|
||||
desc = "Restore width/height when close Neovim while maximized",
|
||||
callback = function()
|
||||
M.maximize(false)
|
||||
end,
|
||||
})
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
setmetatable(M, {
|
||||
__call = function(m, ...)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue