mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-04 02:38:46 +00:00
feat: added toggle
This commit is contained in:
parent
b6e08f3edf
commit
28c3029699
3 changed files with 206 additions and 7 deletions
17
README.md
17
README.md
|
@ -8,11 +8,13 @@ A collection of small QoL plugins for Neovim.
|
|||
## Todo
|
||||
|
||||
- [ ] docs :)
|
||||
- [ ] docgen
|
||||
- [ ] plugin
|
||||
- [ ] float => win
|
||||
- [ ] win views
|
||||
- [ ] log module
|
||||
- [x] float => win
|
||||
- [x] win views
|
||||
- [ ] cowboy
|
||||
- [x] docgen
|
||||
- [x] plugin
|
||||
- [x] notify module
|
||||
- [x] overload docgen
|
||||
- [x] bigfile `BufReadPre`
|
||||
- [x] bufdelete
|
||||
- [x] statuscolumn
|
||||
|
@ -24,13 +26,13 @@ A collection of small QoL plugins for Neovim.
|
|||
- [x] lazygit
|
||||
- [x] git
|
||||
- [x] gitbrowse
|
||||
- [x] toggle
|
||||
|
||||
### Maybe
|
||||
|
||||
- [ ] zen
|
||||
- [ ] lsp
|
||||
- [ ] root
|
||||
- [ ] toggle
|
||||
|
||||
## 📦 Snacks
|
||||
|
||||
|
@ -39,7 +41,6 @@ A collection of small QoL plugins for Neovim.
|
|||
| [bigfile](https://github.com/folke/snacks.nvim/blob/main/lua/snacks/bigfile.lua) | Deal with big files | [README](https://github.com/folke/snacks.nvim/blob/main/docs/bigfile.md) |
|
||||
| [bufdelete](https://github.com/folke/snacks.nvim/blob/main/lua/snacks/bufdelete.lua) | Delete buffers without disrupting window layout | [README](https://github.com/folke/snacks.nvim/blob/main/docs/bufdelete.md) |
|
||||
| [debug](https://github.com/folke/snacks.nvim/blob/main/lua/snacks/debug.lua) | Pretty inspect & backtraces for debugging | [README](https://github.com/folke/snacks.nvim/blob/main/docs/debug.md) |
|
||||
| [float](https://github.com/folke/snacks.nvim/blob/main/lua/snacks/float.lua) | Easily create and manage floating windows or splits | [README](https://github.com/folke/snacks.nvim/blob/main/docs/float.md) |
|
||||
| [git](https://github.com/folke/snacks.nvim/blob/main/lua/snacks/git.lua) | Useful tools for Git | [README](https://github.com/folke/snacks.nvim/blob/main/docs/git.md) |
|
||||
| [gitbrowse](https://github.com/folke/snacks.nvim/blob/main/lua/snacks/gitbrowse.lua) | Open the repo of the active file in the browser (e.g., GitHub) | [README](https://github.com/folke/snacks.nvim/blob/main/docs/gitbrowse.md) |
|
||||
| [lazygit](https://github.com/folke/snacks.nvim/blob/main/lua/snacks/lazygit.lua) | Open LazyGit in a float, auto-configure colorscheme and integration with Neovim | [README](https://github.com/folke/snacks.nvim/blob/main/docs/lazygit.md) |
|
||||
|
@ -48,4 +49,6 @@ A collection of small QoL plugins for Neovim.
|
|||
| [rename](https://github.com/folke/snacks.nvim/blob/main/lua/snacks/rename.lua) | LSP-integrated renaming with support for plugins like neo-tree, nvim-tree, oil, mini.files | [README](https://github.com/folke/snacks.nvim/blob/main/docs/rename.md) |
|
||||
| [statuscolumn](https://github.com/folke/snacks.nvim/blob/main/lua/snacks/statuscolumn.lua) | Customizable statuscolumn | [README](https://github.com/folke/snacks.nvim/blob/main/docs/statuscolumn.md) |
|
||||
| [terminal](https://github.com/folke/snacks.nvim/blob/main/lua/snacks/terminal.lua) | Create and toggle floating/sp. Uses **float**. | [README](https://github.com/folke/snacks.nvim/blob/main/docs/terminal.md) |
|
||||
| [toggle](https://github.com/folke/snacks.nvim/blob/main/lua/snacks/toggle.lua) | Toggle keymaps integrated with which-key icons / colors | [README](https://github.com/folke/snacks.nvim/blob/main/docs/toggle.md) |
|
||||
| [win](https://github.com/folke/snacks.nvim/blob/main/lua/snacks/win.lua) | Easily create and manage floating windows or splits | [README](https://github.com/folke/snacks.nvim/blob/main/docs/win.md) |
|
||||
| [words](https://github.com/folke/snacks.nvim/blob/main/lua/snacks/words.lua) | Auto-show LSP references, auto-show and quick navigation between them | [README](https://github.com/folke/snacks.nvim/blob/main/docs/words.md) |
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
---@field gitbrowse snacks.gitbrowse
|
||||
---@field notify snacks.notify
|
||||
---@field debug snacks.debug
|
||||
---@field toggle snacks.toggle
|
||||
local M = {}
|
||||
|
||||
setmetatable(M, {
|
||||
|
|
195
lua/snacks/toggle.lua
Normal file
195
lua/snacks/toggle.lua
Normal file
|
@ -0,0 +1,195 @@
|
|||
---@class snacks.toggle
|
||||
---@field opts snacks.toggle.Config
|
||||
---@overload fun(... :snacks.toggle.Config): snacks.toggle
|
||||
local M = setmetatable({}, {
|
||||
__call = function(t, ...)
|
||||
return t.new(...)
|
||||
end,
|
||||
})
|
||||
|
||||
---@class snacks.toggle.Config
|
||||
---@field name string
|
||||
---@field get fun():boolean
|
||||
---@field set fun(state:boolean)
|
||||
---@field icon? string|{ enabled: string, disabled: string }
|
||||
---@field color? string|{ enabled: string, disabled: string }
|
||||
local defaults = {
|
||||
map = vim.keymap.set,
|
||||
which_key = true,
|
||||
notify = true,
|
||||
icon = {
|
||||
enabled = " ",
|
||||
disabled = " ",
|
||||
},
|
||||
color = {
|
||||
enabled = "green",
|
||||
disabled = "yellow",
|
||||
},
|
||||
}
|
||||
|
||||
---@param ... snacks.toggle.Config
|
||||
---@return snacks.toggle
|
||||
function M.new(...)
|
||||
local self = setmetatable({}, { __index = M })
|
||||
self.opts = Snacks.config.get("toggle", defaults, ...)
|
||||
return self
|
||||
end
|
||||
|
||||
function M:get()
|
||||
local ok, ret = pcall(self.opts.get)
|
||||
if not ok then
|
||||
Snacks.notify.error({
|
||||
"Failed to get state for `" .. self.opts.name .. "`:\n",
|
||||
ret --[[@as string]],
|
||||
}, { title = self.opts.name, once = true })
|
||||
return false
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
---@param state boolean
|
||||
function M:set(state)
|
||||
local ok, err = pcall(self.opts.set, state) ---@type boolean, string?
|
||||
if not ok then
|
||||
Snacks.notify.error({
|
||||
"Failed to set state for `" .. self.opts.name .. "`:\n",
|
||||
err --[[@as string]],
|
||||
}, { title = self.opts.name, once = true })
|
||||
end
|
||||
end
|
||||
|
||||
function M:toggle()
|
||||
local state = not self:get()
|
||||
self:set(state)
|
||||
if self.opts.notify then
|
||||
Snacks.notify(
|
||||
(state and "Enabled" or "Disabled") .. " **" .. self.opts.name .. "**",
|
||||
{ title = self.opts.name, level = state and vim.log.levels.INFO or vim.log.levels.WARN }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
---@param keys string
|
||||
---@param opts? vim.keymap.set.Opts | { mode: string|string[]}
|
||||
function M:map(keys, opts)
|
||||
opts = opts or {}
|
||||
local mode = opts.mode or "n"
|
||||
opts.mode = nil
|
||||
opts.desc = opts.desc or ("Toggle " .. self.opts.name)
|
||||
self.opts.map(mode, keys, function()
|
||||
self:toggle()
|
||||
end, opts)
|
||||
if self.opts.which_key and pcall(require, "which-key") then
|
||||
self:_wk(keys, mode)
|
||||
end
|
||||
end
|
||||
|
||||
function M:_wk(keys, mode)
|
||||
require("which-key").add({
|
||||
{
|
||||
keys,
|
||||
mode = mode,
|
||||
icon = function()
|
||||
local key = self:get() and "enabled" or "disabled"
|
||||
return {
|
||||
icon = type(self.opts.icon) == "string" and self.opts.icon or self.opts.icon[key],
|
||||
color = type(self.opts.color) == "string" and self.opts.color or self.opts.color[key],
|
||||
}
|
||||
end,
|
||||
desc = function()
|
||||
return (self:get() and "Disable " or "Enable ") .. self.opts.name
|
||||
end,
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
---@param option string
|
||||
---@param opts? snacks.toggle.Config | {on?: unknown, off?: unknown}
|
||||
function M.option(option, opts)
|
||||
opts = opts or {}
|
||||
local on = opts.on == nil and true or opts.on
|
||||
local off = opts.off ~= nil and opts.off or false
|
||||
return M.new({
|
||||
name = option,
|
||||
get = function()
|
||||
return vim.opt_local[option]:get() == on
|
||||
end,
|
||||
set = function(state)
|
||||
vim.opt_local[option] = state and on or off
|
||||
end,
|
||||
}, opts)
|
||||
end
|
||||
|
||||
---@param opts? snacks.toggle.Config
|
||||
function M.treesitter(opts)
|
||||
return M.new({
|
||||
name = "Treesitter Highlight",
|
||||
get = function()
|
||||
return vim.b.ts_highlight
|
||||
end,
|
||||
set = function(state)
|
||||
vim.treesitter[state and "start" or "stop"]()
|
||||
end,
|
||||
}, opts)
|
||||
end
|
||||
|
||||
---@param opts? snacks.toggle.Config
|
||||
function M.line_number(opts)
|
||||
local number, relativenumber = true, true
|
||||
return M.new({
|
||||
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, vim.opt_local.relativenumber = number, relativenumber
|
||||
else
|
||||
number, relativenumber = vim.opt_local.number:get(), vim.opt_local.relativenumber:get()
|
||||
vim.opt_local.number, vim.opt_local.relativenumber = false, false
|
||||
end
|
||||
end,
|
||||
}, opts)
|
||||
end
|
||||
|
||||
---@param opts? snacks.toggle.Config
|
||||
function M.inlay_hints(opts)
|
||||
return M.new({
|
||||
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,
|
||||
}, opts)
|
||||
end
|
||||
|
||||
---@param opts? snacks.toggle.Config
|
||||
function M.diagnostics(opts)
|
||||
return M.new({
|
||||
name = "Diagnostics",
|
||||
get = function()
|
||||
local enabled = false
|
||||
if vim.diagnostic.is_enabled then
|
||||
enabled = vim.diagnostic.is_enabled()
|
||||
elseif vim.diagnostic.is_disabled then
|
||||
enabled = not vim.diagnostic.is_disabled()
|
||||
end
|
||||
return enabled
|
||||
end,
|
||||
set = function(state)
|
||||
if vim.fn.has("nvim-0.10") == 0 then
|
||||
if state then
|
||||
pcall(vim.diagnostic.enable)
|
||||
else
|
||||
pcall(vim.diagnostic.disable)
|
||||
end
|
||||
else
|
||||
vim.diagnostic.enable(state)
|
||||
end
|
||||
end,
|
||||
}, opts)
|
||||
end
|
||||
|
||||
return M
|
Loading…
Add table
Add a link
Reference in a new issue