|
| 1 | +# `Mini-snippets` |
| 2 | + |
| 3 | +<!-- plugins:start --> |
| 4 | + |
| 5 | +:::info |
| 6 | +You can enable the extra with the `:LazyExtras` command. |
| 7 | +Plugins marked as optional will only be configured if they are installed. |
| 8 | +::: |
| 9 | + |
| 10 | +### Options |
| 11 | + |
| 12 | +Additional options for this extra can be configured in your [lua/config/options.lua](/configuration/general#options) file: |
| 13 | + |
| 14 | +```lua title="lua/config/options.lua" |
| 15 | +-- Set to `false` to prevent "non-lsp snippets"" from appearing inside completion windows |
| 16 | +-- Motivation: Less clutter in completion windows and a more direct usage of snippits |
| 17 | +vim.g.lazyvim_mini_snippets_in_completion = true |
| 18 | + |
| 19 | +-- NOTE: Please also read: |
| 20 | +-- https://github.com/echasnovski/mini.nvim/blob/main/readmes/mini-snippets.md#expand |
| 21 | +-- :h MiniSnippets-session |
| 22 | + |
| 23 | +-- Example override for your own config: |
| 24 | +--[[ |
| 25 | +return { |
| 26 | +{ |
| 27 | +"echasnovski/mini.snippets", |
| 28 | +opts = function(_, opts) |
| 29 | +-- By default, for opts.snippets, the extra for mini.snippets only adds gen_loader.from_lang() |
| 30 | +-- This provides a sensible quickstart, integrating with friendly-snippets |
| 31 | +-- and your own language-specific snippets |
| 32 | +-- |
| 33 | +-- In order to change opts.snippets, replace the entire table inside your own opts |
| 34 | +
|
| 35 | +local snippets, config_path = require("mini.snippets"), vim.fn.stdpath("config") |
| 36 | +
|
| 37 | +opts.snippets = { -- override opts.snippets provided by extra... |
| 38 | +-- Load custom file with global snippets first (order matters) |
| 39 | +snippets.gen_loader.from_file(config_path .. "/snippets/global.json"), |
| 40 | +
|
| 41 | +-- Load snippets based on current language by reading files from |
| 42 | +-- "snippets/" subdirectories from 'runtimepath' directories. |
| 43 | +snippets.gen_loader.from_lang(), -- this is the default in the extra... |
| 44 | +} |
| 45 | +end, |
| 46 | +}, |
| 47 | +} |
| 48 | +--]] |
| 49 | +``` |
| 50 | + |
| 51 | +Below you can find a list of included plugins and their default settings. |
| 52 | + |
| 53 | +:::caution |
| 54 | +You don't need to copy the default settings to your config. |
| 55 | +They are only shown here for reference. |
| 56 | +::: |
| 57 | + |
| 58 | +import Tabs from '@theme/Tabs'; |
| 59 | +import TabItem from '@theme/TabItem'; |
| 60 | + |
| 61 | +## [mini.snippets](https://github.com/echasnovski/mini.snippets) |
| 62 | + |
| 63 | +<Tabs> |
| 64 | + |
| 65 | +<TabItem value="opts" label="Options"> |
| 66 | + |
| 67 | +```lua |
| 68 | +opts = function() |
| 69 | + ---@diagnostic disable-next-line: duplicate-set-field |
| 70 | + LazyVim.cmp.actions.snippet_stop = function() end -- by design, <esc> should not stop the session! |
| 71 | + ---@diagnostic disable-next-line: duplicate-set-field |
| 72 | + LazyVim.cmp.actions.snippet_forward = function() |
| 73 | + return jump("next") |
| 74 | + end |
| 75 | + |
| 76 | + local mini_snippets = require("mini.snippets") |
| 77 | + return { |
| 78 | + snippets = { mini_snippets.gen_loader.from_lang() }, |
| 79 | + |
| 80 | + -- Following the behavior of vim.snippets, |
| 81 | + -- the intended usage of <esc> is to be able to temporarily exit into normal mode for quick edits. |
| 82 | + -- |
| 83 | + -- If you'd rather stop the snippet on <esc>, activate the line below in your own config: |
| 84 | + -- mappings = { stop = "<esc>" }, -- <c-c> by default, see :h MiniSnippets-session |
| 85 | + |
| 86 | + expand = { |
| 87 | + select = function(snippets, insert) |
| 88 | + -- Close completion window on snippet select - vim.ui.select |
| 89 | + -- Needed to remove virtual text for fzf-lua and telescope, but not for mini.pick... |
| 90 | + local select = expand_select_override or MiniSnippets.default_select |
| 91 | + select(snippets, insert) |
| 92 | + end, |
| 93 | + }, |
| 94 | + } |
| 95 | +end |
| 96 | +``` |
| 97 | + |
| 98 | +</TabItem> |
| 99 | + |
| 100 | + |
| 101 | +<TabItem value="code" label="Full Spec"> |
| 102 | + |
| 103 | +```lua |
| 104 | +{ |
| 105 | + "echasnovski/mini.snippets", |
| 106 | + event = "InsertEnter", -- don't depend on other plugins to load... |
| 107 | + dependencies = "rafamadriz/friendly-snippets", |
| 108 | + opts = function() |
| 109 | + ---@diagnostic disable-next-line: duplicate-set-field |
| 110 | + LazyVim.cmp.actions.snippet_stop = function() end -- by design, <esc> should not stop the session! |
| 111 | + ---@diagnostic disable-next-line: duplicate-set-field |
| 112 | + LazyVim.cmp.actions.snippet_forward = function() |
| 113 | + return jump("next") |
| 114 | + end |
| 115 | + |
| 116 | + local mini_snippets = require("mini.snippets") |
| 117 | + return { |
| 118 | + snippets = { mini_snippets.gen_loader.from_lang() }, |
| 119 | + |
| 120 | + -- Following the behavior of vim.snippets, |
| 121 | + -- the intended usage of <esc> is to be able to temporarily exit into normal mode for quick edits. |
| 122 | + -- |
| 123 | + -- If you'd rather stop the snippet on <esc>, activate the line below in your own config: |
| 124 | + -- mappings = { stop = "<esc>" }, -- <c-c> by default, see :h MiniSnippets-session |
| 125 | + |
| 126 | + expand = { |
| 127 | + select = function(snippets, insert) |
| 128 | + -- Close completion window on snippet select - vim.ui.select |
| 129 | + -- Needed to remove virtual text for fzf-lua and telescope, but not for mini.pick... |
| 130 | + local select = expand_select_override or MiniSnippets.default_select |
| 131 | + select(snippets, insert) |
| 132 | + end, |
| 133 | + }, |
| 134 | + } |
| 135 | + end, |
| 136 | +} |
| 137 | +``` |
| 138 | + |
| 139 | +</TabItem> |
| 140 | + |
| 141 | +</Tabs> |
| 142 | + |
| 143 | +## [cmp-mini-snippets](https://github.com/abeldekat/cmp-mini-snippets) |
| 144 | + |
| 145 | +<Tabs> |
| 146 | + |
| 147 | +<TabItem value="opts" label="Options"> |
| 148 | + |
| 149 | +```lua |
| 150 | +opts = nil |
| 151 | +``` |
| 152 | + |
| 153 | +</TabItem> |
| 154 | + |
| 155 | + |
| 156 | +<TabItem value="code" label="Full Spec"> |
| 157 | + |
| 158 | +```lua |
| 159 | +{ "abeldekat/cmp-mini-snippets" } |
| 160 | +``` |
| 161 | + |
| 162 | +</TabItem> |
| 163 | + |
| 164 | +</Tabs> |
| 165 | + |
| 166 | +## [nvim-cmp](https://github.com/hrsh7th/nvim-cmp) _(optional)_ |
| 167 | + |
| 168 | + nvim-cmp integration |
| 169 | + |
| 170 | + |
| 171 | +<Tabs> |
| 172 | + |
| 173 | +<TabItem value="opts" label="Options"> |
| 174 | + |
| 175 | +```lua |
| 176 | +opts = function(_, opts) |
| 177 | + local cmp = require("cmp") |
| 178 | + local cmp_config = require("cmp.config") |
| 179 | + |
| 180 | + opts.snippet = { |
| 181 | + expand = function(args) |
| 182 | + expand_from_lsp(args.body) |
| 183 | + cmp.resubscribe({ "TextChangedI", "TextChangedP" }) |
| 184 | + cmp_config.set_onetime({ sources = {} }) |
| 185 | + end, |
| 186 | + } |
| 187 | + |
| 188 | + if include_in_completion then |
| 189 | + table.insert(opts.sources, { name = "mini_snippets" }) |
| 190 | + else |
| 191 | + expand_select_override = function(snippets, insert) |
| 192 | + -- stylua: ignore |
| 193 | + if cmp.visible() then cmp.close() end |
| 194 | + MiniSnippets.default_select(snippets, insert) |
| 195 | + end |
| 196 | + end |
| 197 | +end |
| 198 | +``` |
| 199 | + |
| 200 | +</TabItem> |
| 201 | + |
| 202 | + |
| 203 | +<TabItem value="code" label="Full Spec"> |
| 204 | + |
| 205 | +```lua |
| 206 | +{ |
| 207 | + "hrsh7th/nvim-cmp", |
| 208 | + optional = true, |
| 209 | + dependencies = include_in_completion and { "abeldekat/cmp-mini-snippets" } or nil, |
| 210 | + opts = function(_, opts) |
| 211 | + local cmp = require("cmp") |
| 212 | + local cmp_config = require("cmp.config") |
| 213 | + |
| 214 | + opts.snippet = { |
| 215 | + expand = function(args) |
| 216 | + expand_from_lsp(args.body) |
| 217 | + cmp.resubscribe({ "TextChangedI", "TextChangedP" }) |
| 218 | + cmp_config.set_onetime({ sources = {} }) |
| 219 | + end, |
| 220 | + } |
| 221 | + |
| 222 | + if include_in_completion then |
| 223 | + table.insert(opts.sources, { name = "mini_snippets" }) |
| 224 | + else |
| 225 | + expand_select_override = function(snippets, insert) |
| 226 | + -- stylua: ignore |
| 227 | + if cmp.visible() then cmp.close() end |
| 228 | + MiniSnippets.default_select(snippets, insert) |
| 229 | + end |
| 230 | + end |
| 231 | + end, |
| 232 | + -- stylua: ignore |
| 233 | + -- counterpart to <tab> defined in cmp.mappings |
| 234 | + keys = include_in_completion and { { "<s-tab>", function() jump("prev") end, mode = "i" } } or nil, |
| 235 | +} |
| 236 | +``` |
| 237 | + |
| 238 | +</TabItem> |
| 239 | + |
| 240 | +</Tabs> |
| 241 | + |
| 242 | +## [blink.cmp](https://github.com/saghen/blink.cmp) _(optional)_ |
| 243 | + |
| 244 | + blink.cmp integration |
| 245 | + |
| 246 | + |
| 247 | +<Tabs> |
| 248 | + |
| 249 | +<TabItem value="opts" label="Options"> |
| 250 | + |
| 251 | +```lua |
| 252 | +opts = function(_, opts) |
| 253 | + -- Return early |
| 254 | + if include_in_completion then |
| 255 | + opts.snippets = { preset = "mini_snippets" } |
| 256 | + return |
| 257 | + end |
| 258 | + |
| 259 | + -- Standalone -- |
| 260 | + expand_select_override = function(snippets, insert) |
| 261 | + -- Schedule, otherwise blink's virtual text is not removed on vim.ui.select |
| 262 | + require("blink.cmp").cancel() |
| 263 | + vim.schedule(function() |
| 264 | + MiniSnippets.default_select(snippets, insert) |
| 265 | + end) |
| 266 | + end |
| 267 | + -- |
| 268 | + -- Blink performs a require on blink.cmp.sources.snippets.default |
| 269 | + -- By removing the source, the default engine will not be used |
| 270 | + opts.sources.default = vim.tbl_filter(function(source) |
| 271 | + return source ~= "snippets" |
| 272 | + end, opts.sources.default) |
| 273 | + opts.snippets = { -- need to repeat blink's preset here |
| 274 | + expand = expand_from_lsp, |
| 275 | + active = function() |
| 276 | + return MiniSnippets.session.get(false) ~= nil |
| 277 | + end, |
| 278 | + jump = function(direction) |
| 279 | + jump(direction == -1 and "prev" or "next") |
| 280 | + end, |
| 281 | + } |
| 282 | +end |
| 283 | +``` |
| 284 | + |
| 285 | +</TabItem> |
| 286 | + |
| 287 | + |
| 288 | +<TabItem value="code" label="Full Spec"> |
| 289 | + |
| 290 | +```lua |
| 291 | +{ |
| 292 | + "saghen/blink.cmp", |
| 293 | + optional = true, |
| 294 | + opts = function(_, opts) |
| 295 | + -- Return early |
| 296 | + if include_in_completion then |
| 297 | + opts.snippets = { preset = "mini_snippets" } |
| 298 | + return |
| 299 | + end |
| 300 | + |
| 301 | + -- Standalone -- |
| 302 | + expand_select_override = function(snippets, insert) |
| 303 | + -- Schedule, otherwise blink's virtual text is not removed on vim.ui.select |
| 304 | + require("blink.cmp").cancel() |
| 305 | + vim.schedule(function() |
| 306 | + MiniSnippets.default_select(snippets, insert) |
| 307 | + end) |
| 308 | + end |
| 309 | + -- |
| 310 | + -- Blink performs a require on blink.cmp.sources.snippets.default |
| 311 | + -- By removing the source, the default engine will not be used |
| 312 | + opts.sources.default = vim.tbl_filter(function(source) |
| 313 | + return source ~= "snippets" |
| 314 | + end, opts.sources.default) |
| 315 | + opts.snippets = { -- need to repeat blink's preset here |
| 316 | + expand = expand_from_lsp, |
| 317 | + active = function() |
| 318 | + return MiniSnippets.session.get(false) ~= nil |
| 319 | + end, |
| 320 | + jump = function(direction) |
| 321 | + jump(direction == -1 and "prev" or "next") |
| 322 | + end, |
| 323 | + } |
| 324 | + end, |
| 325 | +} |
| 326 | +``` |
| 327 | + |
| 328 | +</TabItem> |
| 329 | + |
| 330 | +</Tabs> |
| 331 | + |
| 332 | +<!-- plugins:end --> |
0 commit comments