🍿 A collection of QoL plugins for Neovim
Find a file
github-actions[bot] eadb0ca316
chore(main): release 2.28.0
🤖 I have created a release *beep* *boop*
---


## [2.28.0](https://github.com/folke/snacks.nvim/compare/v2.27.0...v2.28.0) (2025-11-01)


### Features

* **gh:** new `gh` (GitHub cli) integration ([85b8ec2](85b8ec2109))
* **image:** when opts.conceal, conceal remainig lines that are not covered by the image. See [#2391](https://github.com/folke/snacks.nvim/issues/2391) ([404027c](404027c973))
* **picker.buffers:** add filetype/buftype to search text ([a249c86](a249c86cf1))
* **picker.buffers:** added buftype and filetype for scratch buffers ([6a13271](6a132716af))
* **picker.diff:** moved git_diff finder to separate file so it can be re-used + made it more robust. Closes [#2366](https://github.com/folke/snacks.nvim/issues/2366) ([3049ad8](3049ad8beb))
* **picker.diff:** native diff now also highlights the language of the diffed code in the diff ([7260957](726095723d))
* **picker.git_diff:** `git_diff` now also shows staged hunks and added stage/unstage/restore actions for hunks. Closes [#2382](https://github.com/folke/snacks.nvim/issues/2382) ([1fb3f4d](1fb3f4de49))
* **picker.git_diff:** added `staged` flag ([118648c](118648ce93))
* **picker.highlights:** badges ([202e595](202e595e55))
* **picker.preview:** allow items to define a title used in the preview window ([4b572f4](4b572f4785))
* **picker.preview:** support for images and render markdown ([9585da6](9585da6c57))
* **picker.util:** cmdline parser used to properly parse diff args ([5025989](502598953f))
* **picker:** better integration with markview and render-markdown when previewing ([4708e9a](4708e9a386))
* **scratch:** store scratch info in meta files, instead of the filename + custom filekeys ([85f8e22](85f8e22281))
* **util.spawn:** `Proc:json()` ([5589c9d](5589c9d355))
* **util:** `Snacks.util.stop()` to safely stop/close a luv handle ([ce9e299](ce9e2993dd))


### Bug Fixes

* **explorer.tree:** only strip trasiling forward slashes if not at root. Closes [#2375](https://github.com/folke/snacks.nvim/issues/2375) ([72dc621](72dc6213f7))
* **explorer:** differentiate if file or folder when deleting on Windows ([#2373](https://github.com/folke/snacks.nvim/issues/2373)) ([59c5545](59c5545e91))
* **explorer:** do reveal in on_show if explorer is not open yet. Closes [#2388](https://github.com/folke/snacks.nvim/issues/2388) ([ba529d4](ba529d4f5d))
* **explorer:** schedule `on_find` (typically reveal), for both files finder and when git status updates the finder. Closes [#2388](https://github.com/folke/snacks.nvim/issues/2388) ([a9b57b2](a9b57b2a7e))
* **gh:** add action idx to `gh_actions` text ([d94184d](d94184d1d9))
* **image.inline:** off-by-one for finding visible images at the last line of the buffer ([04b3a54](04b3a54576))
* **image:** avoid nested math environments ([#2345](https://github.com/folke/snacks.nvim/issues/2345)) ([66e3dc4](66e3dc4619))
* **image:** check for invalid buffer ([9ad4178](9ad41782ec))
* **image:** check to update on BufWinEnter and attach to buffer changes ([e18e4f6](e18e4f6452))
* **image:** don't add placements to concealed lines. Closes [#2391](https://github.com/folke/snacks.nvim/issues/2391) ([13963b1](13963b1ec4))
* **image:** guard against invalid buffers. Closes [#2383](https://github.com/folke/snacks.nvim/issues/2383) ([4bb1ce1](4bb1ce16ed))
* keymap docs ([583a0c1](583a0c1c06))
* **keymap:** make sure opts are a table. Closes [#2392](https://github.com/folke/snacks.nvim/issues/2392) ([367d1bd](367d1bd385))
* **layout:** only max zindex for snacks windows/layouts ([8eddc0b](8eddc0b380))
* **picker.actions:** `drop` and `tabdrop` should never reload existing buffers ([#2368](https://github.com/folke/snacks.nvim/issues/2368)) ([6cf2fee](6cf2fee619))
* **picker.actions:** use `buffer!` instead of `buffer` for edit. Closes [#2378](https://github.com/folke/snacks.nvim/issues/2378) ([2a1a001](2a1a001d3a))
* **picker.diff:** better filename parsing. See [#2366](https://github.com/folke/snacks.nvim/issues/2366) ([377f3bf](377f3bfeca))
* **picker.diff:** first line of header ([fb011c2](fb011c257f))
* **picker.diff:** only process `---` diffs directly if it doesn't start with a diff header ([0a33aec](0a33aec0c6))
* **picker.filter:** get cwd from active tabpage if available ([c1b517f](c1b517f545))
* **picker.finder:** mutate existing opts ([c91e230](c91e23060c))
* **picker.finder:** tmp fix for [#2386](https://github.com/folke/snacks.nvim/issues/2386) ([5eea5f9](5eea5f9428))
* **picker.git_branches:** git log preview. Closes [#2360](https://github.com/folke/snacks.nvim/issues/2360) ([597ebd4](597ebd4115))
* **picker.git_diff:** remove `--default-prefix`, since that's no longer needed. See [#2382](https://github.com/folke/snacks.nvim/issues/2382) ([40774ae](40774ae6ca))
* **picker.git_diff:** set `group=false` by default, since we also have `git_status` ([530e591](530e591345))
* **picker.highlights:** modifiable for set_lines ([98345fb](98345fb667))
* **picker.keymaps:** try to locate neovim compiled lua source files for keymaps ([76160be](76160be5d3))
* **picker.lsp:** fixed `vim.str_byteindex` capability check. Closes [#2389](https://github.com/folke/snacks.nvim/issues/2389) ([46917d0](46917d0629))
* **picker.lsp:** some LSP servers notify completion before sending the actual result. See [#2372](https://github.com/folke/snacks.nvim/issues/2372) ([aa8a318](aa8a318779))
* **picker.lsp:** use `LspRequest` to track completed and cancelled requests. Fixes [#2364](https://github.com/folke/snacks.nvim/issues/2364) ([8afb609](8afb609333))
* **picker.preview:** again. docgen seems broken ([758bbfa](758bbfa13a))
* **picker.preview:** don't show locations for diff preview ([b064488](b0644884ef))
* **picker.preview:** fckup ([fd7795e](fd7795e9cd))
* **picker.preview:** fix ([e2c1c52](e2c1c527e4))
* **picker.preview:** show proper preview message for deleted scratch buffers ([4ad8a41](4ad8a41eac))
* **picker.util:** better relative time format ([3e30fb6](3e30fb6c70))
* **picker.util:** ignore errors from corrupted kv stores. Closes [#2394](https://github.com/folke/snacks.nvim/issues/2394) ([b3d01c5](b3d01c59ba))
* **picker.watch:** check again for closed picker after schedule. See [#2365](https://github.com/folke/snacks.nvim/issues/2365) ([8ad80de](8ad80de67b))
* **picker:** close picker when layout closes. Closes [#2365](https://github.com/folke/snacks.nvim/issues/2365) ([779746f](779746f9a8))
* **picker:** dont watch files for closed pickers. Fixes [#2365](https://github.com/folke/snacks.nvim/issues/2365) ([c4ec8b6](c4ec8b6d12))
* **picker:** increase default show_delay to 5s. Closes [#2364](https://github.com/folke/snacks.nvim/issues/2364) ([b3197e3](b3197e3a2a))
* **picker:** only trim space in the title if it's preceded by a word like character (skips icons) ([2439c49](2439c493a5))
* **picker:** pause input progress info for 60ms to prevent flickering when finder is too fast ([ecde81f](ecde81fc0c))
* **scratch:** make sure zindex of scratch window is higher than existing floating windows ([c8422da](c8422da50d))
* **scroll:** only reset count when needed ([551d79f](551d79f1c0))
* **util.job:** scroll to top when process exits ([b544157](b5441575e0))
* **util.job:** stop on BufWipeout and BufDelete ([c956b37](c956b37246))
* **util.job:** stop when attached buffer is no longer valid ([221d4b1](221d4b1747))
* **util.job:** use nvim_win_set_cursor instead of `gg` ([5faed2f](5faed2f7ab))
* **util.lsp:** `Snacks.util.lsp.on()` should trigger for each lsp client per buffer ([52f30a1](52f30a198a))
* **util:** color() should not create hl groups ([17033e6](17033e67ef))
* **win:** ignore errors on destroy. Closes [#2381](https://github.com/folke/snacks.nvim/issues/2381) ([a8930bd](a8930bdb61))
* **win:** scratch buffers were sometimes not deleted ([0387297](03872973b3))
* **win:** when fixbuf triggers in a floating window, just close it. Closes [#2380](https://github.com/folke/snacks.nvim/issues/2380) ([de35242](de352425f7))


### Performance Improvements

* **animate:** smoother animations ([b7a3fed](b7a3fed8d9))
* **notifier:** stop trying to fit more notifs in the layout after skipping max 10 ([3a8ecf5](3a8ecf5912))
* **picker.util:** cache badge hl groups ([cb85844](cb85844e84))
* **scroll:** combine all scrolling commands in one command + restore vim.v.count ([0fbea13](0fbea13c9d))
* **scroll:** smoother scrolling using new animations ([2221fe6](2221fe6166))
* **statuscolumn:** only calculate components that are actually needed ([bb80317](bb80317647))


### Reverts

* jump `buffer` -> `buffer!`. See [#2378](https://github.com/folke/snacks.nvim/issues/2378) ([143e9b5](143e9b58c7))

---
This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
2025-11-01 13:43:16 +01:00
.github chore(main): release 2.28.0 2025-11-01 13:43:16 +01:00
doc chore(build): auto-generated vimdocs 2025-11-01 12:31:35 +00:00
docs docs: added gh docs 2025-11-01 13:29:29 +01:00
lua chore(main): release 2.28.0 2025-11-01 13:43:16 +01:00
plugin feat: ensure Snacks global is available when not using setup 2024-11-04 16:39:24 +01:00
queries fix(image): avoid nested math environments (#2345) 2025-10-29 14:47:52 +01:00
scripts ci: docs 2025-10-22 09:56:43 +02:00
tests fix(image): avoid nested math environments (#2345) 2025-10-29 14:47:52 +01:00
.editorconfig ci: integrated with ci scripts 2024-11-03 09:04:33 +01:00
.gitignore chore(update): update repository (#800) 2025-10-22 16:58:00 +02:00
.markdownlint-cli2.yaml chore(update): update repository (#2370) 2025-10-28 15:12:14 +01:00
CHANGELOG.md chore(main): release 2.28.0 2025-11-01 13:43:16 +01:00
LICENSE ci: integrated with ci scripts 2024-11-03 09:04:33 +01:00
README.md docs: added gh docs 2025-11-01 13:29:29 +01:00
selene.toml feat: initial commit 2024-11-02 23:24:33 +01:00
stylua.toml feat: initial commit 2024-11-02 23:24:33 +01:00
vim.yml ci: update test scripts 2025-10-08 21:26:25 +02:00

🍿 snacks.nvim

A collection of small QoL plugins for Neovim.

Features

Snack Description Setup
animate Efficient animations including over 45 easing functions (library)
bigfile Deal with big files ‼️
bufdelete Delete buffers without disrupting window layout
dashboard Beautiful declarative dashboards ‼️
debug Pretty inspect & backtraces for debugging
dim Focus on the active scope by dimming the rest
explorer A file explorer (picker in disguise) ‼️
gh GitHub CLI integration
git Git utilities
gitbrowse Open the current file, branch, commit, or repo in a browser (e.g. GitHub, GitLab, Bitbucket)
image Image viewer using Kitty Graphics Protocol, supported by kitty, wezterm and ghostty ‼️
indent Indent guides and scopes
input Better vim.ui.input ‼️
keymap Better vim.keymap with support for filetypes and LSP clients
layout Window layouts
lazygit Open LazyGit in a float, auto-configure colorscheme and integration with Neovim
notifier Pretty vim.notify ‼️
notify Utility functions to work with Neovim's vim.notify
picker Picker for selecting items ‼️
profiler Neovim lua profiler
quickfile When doing nvim somefile.txt, it will render the file as quickly as possible, before loading your plugins. ‼️
rename LSP-integrated file renaming with support for plugins like neo-tree.nvim and mini.files.
scope Scope detection, text objects and jumping based on treesitter or indent ‼️
scratch Scratch buffers with a persistent file
scroll Smooth scrolling ‼️
statuscolumn Pretty status column ‼️
terminal Create and toggle floating/split terminals
toggle Toggle keymaps integrated with which-key icons / colors
util Utility functions for Snacks (library)
win Create and manage floating windows or splits
words Auto-show LSP references and quickly navigate between them ‼️
zen Zen mode • distraction-free coding

Requirements

📦 Installation

Install the plugin with your package manager:

lazy.nvim

Important

A couple of plugins require snacks.nvim to be set-up early. Setup creates some autocmds and does not load any plugins. Check the code to see what it does.

Caution

You need to explicitly pass options for a plugin or set enabled = true to enable it.

Tip

It's a good idea to run :checkhealth snacks to see if everything is set up correctly.

{
  "folke/snacks.nvim",
  priority = 1000,
  lazy = false,
  ---@type snacks.Config
  opts = {
    -- your configuration comes here
    -- or leave it empty to use the default settings
    -- refer to the configuration section below
    bigfile = { enabled = true },
    dashboard = { enabled = true },
    explorer = { enabled = true },
    indent = { enabled = true },
    input = { enabled = true },
    picker = { enabled = true },
    notifier = { enabled = true },
    quickfile = { enabled = true },
    scope = { enabled = true },
    scroll = { enabled = true },
    statuscolumn = { enabled = true },
    words = { enabled = true },
  },
}

For an in-depth setup of snacks.nvim with lazy.nvim, check the example below.

⚙️ Configuration

Please refer to the readme of each plugin for their specific configuration.

Default Options
---@class snacks.Config
---@field animate? snacks.animate.Config
---@field bigfile? snacks.bigfile.Config
---@field dashboard? snacks.dashboard.Config
---@field dim? snacks.dim.Config
---@field explorer? snacks.explorer.Config
---@field gh? snacks.gh.Config
---@field gitbrowse? snacks.gitbrowse.Config
---@field image? snacks.image.Config
---@field indent? snacks.indent.Config
---@field input? snacks.input.Config
---@field layout? snacks.layout.Config
---@field lazygit? snacks.lazygit.Config
---@field notifier? snacks.notifier.Config
---@field picker? snacks.picker.Config
---@field profiler? snacks.profiler.Config
---@field quickfile? snacks.quickfile.Config
---@field scope? snacks.scope.Config
---@field scratch? snacks.scratch.Config
---@field scroll? snacks.scroll.Config
---@field statuscolumn? snacks.statuscolumn.Config
---@field terminal? snacks.terminal.Config
---@field toggle? snacks.toggle.Config
---@field win? snacks.win.Config
---@field words? snacks.words.Config
---@field zen? snacks.zen.Config
---@field styles? table<string, snacks.win.Config>
---@field image? snacks.image.Config|{}
{
  image = {
    -- define these here, so that we don't need to load the image module
    formats = {
      "png",
      "jpg",
      "jpeg",
      "gif",
      "bmp",
      "webp",
      "tiff",
      "heic",
      "avif",
      "mp4",
      "mov",
      "avi",
      "mkv",
      "webm",
      "pdf",
      "icns",
    },
  },
}

Some plugins have examples in their documentation. You can include them in your config like this:

{
  dashboard = { example = "github" }
}

If you want to customize options for a plugin after they have been resolved, you can use the config function:

{
  gitbrowse = {
    config = function(opts, defaults)
      table.insert(opts.remote_patterns, { "my", "custom pattern" })
    end
  },
}

🚀 Usage

See the example below for how to configure snacks.nvim.

{
  "folke/snacks.nvim",
  priority = 1000,
  lazy = false,
  ---@type snacks.Config
  opts = {
    bigfile = { enabled = true },
    dashboard = { enabled = true },
    explorer = { enabled = true },
    indent = { enabled = true },
    input = { enabled = true },
    notifier = {
      enabled = true,
      timeout = 3000,
    },
    picker = { enabled = true },
    quickfile = { enabled = true },
    scope = { enabled = true },
    scroll = { enabled = true },
    statuscolumn = { enabled = true },
    words = { enabled = true },
    styles = {
      notification = {
        -- wo = { wrap = true } -- Wrap notifications
      }
    }
  },
  keys = {
    -- Top Pickers & Explorer
    { "<leader><space>", function() Snacks.picker.smart() end, desc = "Smart Find Files" },
    { "<leader>,", function() Snacks.picker.buffers() end, desc = "Buffers" },
    { "<leader>/", function() Snacks.picker.grep() end, desc = "Grep" },
    { "<leader>:", function() Snacks.picker.command_history() end, desc = "Command History" },
    { "<leader>n", function() Snacks.picker.notifications() end, desc = "Notification History" },
    { "<leader>e", function() Snacks.explorer() end, desc = "File Explorer" },
    -- find
    { "<leader>fb", function() Snacks.picker.buffers() end, desc = "Buffers" },
    { "<leader>fc", function() Snacks.picker.files({ cwd = vim.fn.stdpath("config") }) end, desc = "Find Config File" },
    { "<leader>ff", function() Snacks.picker.files() end, desc = "Find Files" },
    { "<leader>fg", function() Snacks.picker.git_files() end, desc = "Find Git Files" },
    { "<leader>fp", function() Snacks.picker.projects() end, desc = "Projects" },
    { "<leader>fr", function() Snacks.picker.recent() end, desc = "Recent" },
    -- git
    { "<leader>gb", function() Snacks.picker.git_branches() end, desc = "Git Branches" },
    { "<leader>gl", function() Snacks.picker.git_log() end, desc = "Git Log" },
    { "<leader>gL", function() Snacks.picker.git_log_line() end, desc = "Git Log Line" },
    { "<leader>gs", function() Snacks.picker.git_status() end, desc = "Git Status" },
    { "<leader>gS", function() Snacks.picker.git_stash() end, desc = "Git Stash" },
    { "<leader>gd", function() Snacks.picker.git_diff() end, desc = "Git Diff (Hunks)" },
    { "<leader>gf", function() Snacks.picker.git_log_file() end, desc = "Git Log File" },
    -- Grep
    { "<leader>sb", function() Snacks.picker.lines() end, desc = "Buffer Lines" },
    { "<leader>sB", function() Snacks.picker.grep_buffers() end, desc = "Grep Open Buffers" },
    { "<leader>sg", function() Snacks.picker.grep() end, desc = "Grep" },
    { "<leader>sw", function() Snacks.picker.grep_word() end, desc = "Visual selection or word", mode = { "n", "x" } },
    -- search
    { '<leader>s"', function() Snacks.picker.registers() end, desc = "Registers" },
    { '<leader>s/', function() Snacks.picker.search_history() end, desc = "Search History" },
    { "<leader>sa", function() Snacks.picker.autocmds() end, desc = "Autocmds" },
    { "<leader>sb", function() Snacks.picker.lines() end, desc = "Buffer Lines" },
    { "<leader>sc", function() Snacks.picker.command_history() end, desc = "Command History" },
    { "<leader>sC", function() Snacks.picker.commands() end, desc = "Commands" },
    { "<leader>sd", function() Snacks.picker.diagnostics() end, desc = "Diagnostics" },
    { "<leader>sD", function() Snacks.picker.diagnostics_buffer() end, desc = "Buffer Diagnostics" },
    { "<leader>sh", function() Snacks.picker.help() end, desc = "Help Pages" },
    { "<leader>sH", function() Snacks.picker.highlights() end, desc = "Highlights" },
    { "<leader>si", function() Snacks.picker.icons() end, desc = "Icons" },
    { "<leader>sj", function() Snacks.picker.jumps() end, desc = "Jumps" },
    { "<leader>sk", function() Snacks.picker.keymaps() end, desc = "Keymaps" },
    { "<leader>sl", function() Snacks.picker.loclist() end, desc = "Location List" },
    { "<leader>sm", function() Snacks.picker.marks() end, desc = "Marks" },
    { "<leader>sM", function() Snacks.picker.man() end, desc = "Man Pages" },
    { "<leader>sp", function() Snacks.picker.lazy() end, desc = "Search for Plugin Spec" },
    { "<leader>sq", function() Snacks.picker.qflist() end, desc = "Quickfix List" },
    { "<leader>sR", function() Snacks.picker.resume() end, desc = "Resume" },
    { "<leader>su", function() Snacks.picker.undo() end, desc = "Undo History" },
    { "<leader>uC", function() Snacks.picker.colorschemes() end, desc = "Colorschemes" },
    -- LSP
    { "gd", function() Snacks.picker.lsp_definitions() end, desc = "Goto Definition" },
    { "gD", function() Snacks.picker.lsp_declarations() end, desc = "Goto Declaration" },
    { "gr", function() Snacks.picker.lsp_references() end, nowait = true, desc = "References" },
    { "gI", function() Snacks.picker.lsp_implementations() end, desc = "Goto Implementation" },
    { "gy", function() Snacks.picker.lsp_type_definitions() end, desc = "Goto T[y]pe Definition" },
    { "gai", function() Snacks.picker.lsp_incoming_calls() end, desc = "C[a]lls Incoming" },
    { "gao", function() Snacks.picker.lsp_outgoing_calls() end, desc = "C[a]lls Outgoing" },
    { "<leader>ss", function() Snacks.picker.lsp_symbols() end, desc = "LSP Symbols" },
    { "<leader>sS", function() Snacks.picker.lsp_workspace_symbols() end, desc = "LSP Workspace Symbols" },
    -- Other
    { "<leader>z",  function() Snacks.zen() end, desc = "Toggle Zen Mode" },
    { "<leader>Z",  function() Snacks.zen.zoom() end, desc = "Toggle Zoom" },
    { "<leader>.",  function() Snacks.scratch() end, desc = "Toggle Scratch Buffer" },
    { "<leader>S",  function() Snacks.scratch.select() end, desc = "Select Scratch Buffer" },
    { "<leader>n",  function() Snacks.notifier.show_history() end, desc = "Notification History" },
    { "<leader>bd", function() Snacks.bufdelete() end, desc = "Delete Buffer" },
    { "<leader>cR", function() Snacks.rename.rename_file() end, desc = "Rename File" },
    { "<leader>gB", function() Snacks.gitbrowse() end, desc = "Git Browse", mode = { "n", "v" } },
    { "<leader>gg", function() Snacks.lazygit() end, desc = "Lazygit" },
    { "<leader>un", function() Snacks.notifier.hide() end, desc = "Dismiss All Notifications" },
    { "<c-/>",      function() Snacks.terminal() end, desc = "Toggle Terminal" },
    { "<c-_>",      function() Snacks.terminal() end, desc = "which_key_ignore" },
    { "]]",         function() Snacks.words.jump(vim.v.count1) end, desc = "Next Reference", mode = { "n", "t" } },
    { "[[",         function() Snacks.words.jump(-vim.v.count1) end, desc = "Prev Reference", mode = { "n", "t" } },
    {
      "<leader>N",
      desc = "Neovim News",
      function()
        Snacks.win({
          file = vim.api.nvim_get_runtime_file("doc/news.txt", false)[1],
          width = 0.6,
          height = 0.6,
          wo = {
            spell = false,
            wrap = false,
            signcolumn = "yes",
            statuscolumn = " ",
            conceallevel = 3,
          },
        })
      end,
    }
  },
  init = function()
    vim.api.nvim_create_autocmd("User", {
      pattern = "VeryLazy",
      callback = function()
        -- Setup some globals for debugging (lazy-loaded)
        _G.dd = function(...)
          Snacks.debug.inspect(...)
        end
        _G.bt = function()
          Snacks.debug.backtrace()
        end

        -- Override print to use snacks for `:=` command
        if vim.fn.has("nvim-0.11") == 1 then
          vim._print = function(_, ...)
            dd(...)
          end
        else
          vim.print = _G.dd 
        end

        -- Create some toggle mappings
        Snacks.toggle.option("spell", { name = "Spelling" }):map("<leader>us")
        Snacks.toggle.option("wrap", { name = "Wrap" }):map("<leader>uw")
        Snacks.toggle.option("relativenumber", { name = "Relative Number" }):map("<leader>uL")
        Snacks.toggle.diagnostics():map("<leader>ud")
        Snacks.toggle.line_number():map("<leader>ul")
        Snacks.toggle.option("conceallevel", { off = 0, on = vim.o.conceallevel > 0 and vim.o.conceallevel or 2 }):map("<leader>uc")
        Snacks.toggle.treesitter():map("<leader>uT")
        Snacks.toggle.option("background", { off = "light", on = "dark", name = "Dark Background" }):map("<leader>ub")
        Snacks.toggle.inlay_hints():map("<leader>uh")
        Snacks.toggle.indent():map("<leader>ug")
        Snacks.toggle.dim():map("<leader>uD")
      end,
    })
  end,
}

🌈 Highlight Groups

Snacks defines a lot of highlight groups and it's impossible to document them all.

Instead, you can use the picker to see all the highlight groups.

Snacks.picker.highlights({pattern = "hl_group:^Snacks"})