diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json
index b3c4f00b..d1d210f5 100644
--- a/.github/.release-please-manifest.json
+++ b/.github/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "14.8.0"
+ ".": "14.9.0"
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1057fb57..7c9c762e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,33 @@
# Changelog
+## [14.9.0](https://github.com/LazyVim/LazyVim/compare/v14.8.0...v14.9.0) (2025-01-30)
+
+
+### Features
+
+* **markdown:** added markdown support for codecompanion ([e9db488](https://github.com/LazyVim/LazyVim/commit/e9db488acaa04f1a9eca6d022e57fed4271b8af8))
+* **snacks.picker:** added <leader>si to search icons ([#5460](https://github.com/LazyVim/LazyVim/issues/5460)) ([eea52be](https://github.com/LazyVim/LazyVim/commit/eea52be3447502dde77d9e6fa75fd597a0b5a86a))
+* **snacks.picker:** added <leader>su to search undotree ([#5447](https://github.com/LazyVim/LazyVim/issues/5447)) ([332b320](https://github.com/LazyVim/LazyVim/commit/332b32080c52727a16db90e06989caa0c378caa1))
+* **snacks.picker:** added `leader-fB` to find any buffer (including hidden & nofile) ([83bf636](https://github.com/LazyVim/LazyVim/commit/83bf6360a1f28a3fc1afe31ae300247fc01c7a90))
+* **snacks.picker:** added `leader-sp` to search for plugin spec ([7cf4185](https://github.com/LazyVim/LazyVim/commit/7cf4185dc4d1fe49ad004d33a6703603fb4500ff))
+* **snacks.picker:** added alt-c to toggle between cwd/root dir ([6be7c4f](https://github.com/LazyVim/LazyVim/commit/6be7c4fee4fb755ff07f7bcc13eac96e1d8c279a))
+* **snacks.picker:** flash.nvim integration ([5d24aa6](https://github.com/LazyVim/LazyVim/commit/5d24aa63111af68fbada8c97fedb75b07b8c3c92))
+* **snacks.picker:** use snacks picker for notifications when enabled ([01a70cc](https://github.com/LazyVim/LazyVim/commit/01a70cc60ed2760afc819510177fb8d12a371b25))
+* **snacks:** extra for snacks explorer (replacement for neo-tree) ([e20d9af](https://github.com/LazyVim/LazyVim/commit/e20d9afcbc980510093a3753a3991d8c934cbb75))
+* **snippets:** an extra for mini.snippets ([#5274](https://github.com/LazyVim/LazyVim/issues/5274)) ([8b4e6ff](https://github.com/LazyVim/LazyVim/commit/8b4e6ff70d682cad3b1f4999623c3f0ac639fa82))
+
+
+### Bug Fixes
+
+* **keymaps:** remove unneeded and ambiguous `<leader>w` keymap ([#5459](https://github.com/LazyVim/LazyVim/issues/5459)) ([132986a](https://github.com/LazyVim/LazyVim/commit/132986a624b49bf740161d90ce94f16dd5ea5883))
+* **luasnip:** schedule `jump` to be compatible with blink, nvim-cmp still works after change ([#5470](https://github.com/LazyVim/LazyVim/issues/5470)) ([0350934](https://github.com/LazyVim/LazyVim/commit/0350934d56579f3e6a9d40fa47313b2970d74772))
+* **root:** pass args to root.get ([dc8512f](https://github.com/LazyVim/LazyVim/commit/dc8512fce1ec1cd4b0ca52d1077b2ed3894d51c8))
+* **snacks.picker:** flash integration ([b5cd0d0](https://github.com/LazyVim/LazyVim/commit/b5cd0d0e27081be3ef1905475a0fe541b7661870))
+* **snacks.picker:** snacks => flash ([3de7b24](https://github.com/LazyVim/LazyVim/commit/3de7b24cf6ed844772ea047476a400c56d5f4b42))
+* **snacks:** use `Snacks.picker` for recent files ([#5485](https://github.com/LazyVim/LazyVim/issues/5485)) ([f0d2629](https://github.com/LazyVim/LazyVim/commit/f0d2629bd859eeac343999b0fe145f9beb227c4a))
+* **sql:** better nvim-cmp check. Closes [#5188](https://github.com/LazyVim/LazyVim/issues/5188) ([1e83b4f](https://github.com/LazyVim/LazyVim/commit/1e83b4f843f88678189df81b1c88a400c53abdbc))
+* **vscode:** diabled some snacks plugins. Fixes [#5364](https://github.com/LazyVim/LazyVim/issues/5364) ([c7a7ab5](https://github.com/LazyVim/LazyVim/commit/c7a7ab51129692927ae47f4e57ce22d10d48467e))
+
## [14.8.0](https://github.com/LazyVim/LazyVim/compare/v14.7.0...v14.8.0) (2025-01-20)
diff --git a/doc/LazyVim.txt b/doc/LazyVim.txt
index 23f8a322..fa81c82c 100644
--- a/doc/LazyVim.txt
+++ b/doc/LazyVim.txt
@@ -1,4 +1,4 @@
-*LazyVim.txt* For Neovim Last change: 2025 January 20
+*LazyVim.txt* For Neovim Last change: 2025 January 31
==============================================================================
Table of Contents *LazyVim-table-of-contents*
diff --git a/lua/lazyvim/config/init.lua b/lua/lazyvim/config/init.lua
index 8a0b2ced..cbe0a571 100644
--- a/lua/lazyvim/config/init.lua
+++ b/lua/lazyvim/config/init.lua
@@ -3,7 +3,7 @@ _G.LazyVim = require("lazyvim.util")
---@class LazyVimConfig: LazyVimOptions
local M = {}
-M.version = "14.8.0" -- x-release-please-version
+M.version = "14.9.0" -- x-release-please-version
LazyVim.config = M
---@class LazyVimOptions
diff --git a/lua/lazyvim/config/keymaps.lua b/lua/lazyvim/config/keymaps.lua
index 48726b02..3e3829d1 100644
--- a/lua/lazyvim/config/keymaps.lua
+++ b/lua/lazyvim/config/keymaps.lua
@@ -182,7 +182,6 @@ map("t", "", "close", { desc = "Hide Terminal" })
map("t", "", "close", { desc = "which_key_ignore" })
-- windows
-map("n", "w", "", { desc = "Windows", remap = true })
map("n", "-", "s", { desc = "Split Window Below", remap = true })
map("n", "|", "v", { desc = "Split Window Right", remap = true })
map("n", "wd", "c", { desc = "Delete Window", remap = true })
diff --git a/lua/lazyvim/plugins/extras/coding/luasnip.lua b/lua/lazyvim/plugins/extras/coding/luasnip.lua
index 8b3daed7..85ed2fd5 100644
--- a/lua/lazyvim/plugins/extras/coding/luasnip.lua
+++ b/lua/lazyvim/plugins/extras/coding/luasnip.lua
@@ -30,7 +30,9 @@ return {
opts = function()
LazyVim.cmp.actions.snippet_forward = function()
if require("luasnip").jumpable(1) then
- require("luasnip").jump(1)
+ vim.schedule(function()
+ require("luasnip").jump(1)
+ end)
return true
end
end
diff --git a/lua/lazyvim/plugins/extras/coding/mini-snippets.lua b/lua/lazyvim/plugins/extras/coding/mini-snippets.lua
new file mode 100644
index 00000000..f68af110
--- /dev/null
+++ b/lua/lazyvim/plugins/extras/coding/mini-snippets.lua
@@ -0,0 +1,167 @@
+if lazyvim_docs then
+ -- Set to `false` to prevent "non-lsp snippets"" from appearing inside completion windows
+ -- Motivation: Less clutter in completion windows and a more direct usage of snippits
+ vim.g.lazyvim_mini_snippets_in_completion = true
+
+ -- NOTE: Please also read:
+ -- https://github.com/echasnovski/mini.nvim/blob/main/readmes/mini-snippets.md#expand
+ -- :h MiniSnippets-session
+
+ -- Example override for your own config:
+ --[[
+ return {
+ {
+ "echasnovski/mini.snippets",
+ opts = function(_, opts)
+ -- By default, for opts.snippets, the extra for mini.snippets only adds gen_loader.from_lang()
+ -- This provides a sensible quickstart, integrating with friendly-snippets
+ -- and your own language-specific snippets
+ --
+ -- In order to change opts.snippets, replace the entire table inside your own opts
+
+ local snippets, config_path = require("mini.snippets"), vim.fn.stdpath("config")
+
+ opts.snippets = { -- override opts.snippets provided by extra...
+ -- Load custom file with global snippets first (order matters)
+ snippets.gen_loader.from_file(config_path .. "/snippets/global.json"),
+
+ -- Load snippets based on current language by reading files from
+ -- "snippets/" subdirectories from 'runtimepath' directories.
+ snippets.gen_loader.from_lang(), -- this is the default in the extra...
+ }
+ end,
+ },
+ }
+--]]
+end
+
+local include_in_completion = vim.g.lazyvim_mini_snippets_in_completion == nil
+ or vim.g.lazyvim_mini_snippets_in_completion
+
+local function expand_from_lsp(snippet)
+ local insert = MiniSnippets.config.expand.insert or MiniSnippets.default_insert
+ insert({ body = snippet })
+end
+
+local function jump(direction)
+ local is_active = MiniSnippets.session.get(false) ~= nil
+ if is_active then
+ MiniSnippets.session.jump(direction)
+ return true
+ end
+end
+
+---@type fun(snippets, insert) | nil
+local expand_select_override = nil
+
+return {
+ -- disable builtin snippet support:
+ { "garymjr/nvim-snippets", optional = true, enabled = false },
+ -- disable luasnip:
+ { "L3MON4D3/LuaSnip", optional = true, enabled = false },
+
+ -- add mini.snippets
+ desc = "mini.snippets(beta), a plugin to manage and expand snippets (alternative for luasnip)",
+ {
+ "echasnovski/mini.snippets",
+ event = "InsertEnter", -- don't depend on other plugins to load...
+ dependencies = "rafamadriz/friendly-snippets",
+ opts = function()
+ ---@diagnostic disable-next-line: duplicate-set-field
+ LazyVim.cmp.actions.snippet_stop = function() end -- by design, should not stop the session!
+ ---@diagnostic disable-next-line: duplicate-set-field
+ LazyVim.cmp.actions.snippet_forward = function()
+ return jump("next")
+ end
+
+ local mini_snippets = require("mini.snippets")
+ return {
+ snippets = { mini_snippets.gen_loader.from_lang() },
+
+ -- Following the behavior of vim.snippets,
+ -- the intended usage of is to be able to temporarily exit into normal mode for quick edits.
+ --
+ -- If you'd rather stop the snippet on , activate the line below in your own config:
+ -- mappings = { stop = "" }, -- by default, see :h MiniSnippets-session
+
+ expand = {
+ select = function(snippets, insert)
+ -- Close completion window on snippet select - vim.ui.select
+ -- Needed to remove virtual text for fzf-lua and telescope, but not for mini.pick...
+ local select = expand_select_override or MiniSnippets.default_select
+ select(snippets, insert)
+ end,
+ },
+ }
+ end,
+ },
+
+ -- nvim-cmp integration
+ {
+ "hrsh7th/nvim-cmp",
+ optional = true,
+ dependencies = include_in_completion and { "abeldekat/cmp-mini-snippets" } or nil,
+ opts = function(_, opts)
+ local cmp = require("cmp")
+ local cmp_config = require("cmp.config")
+
+ opts.snippet = {
+ expand = function(args)
+ expand_from_lsp(args.body)
+ cmp.resubscribe({ "TextChangedI", "TextChangedP" })
+ cmp_config.set_onetime({ sources = {} })
+ end,
+ }
+
+ if include_in_completion then
+ table.insert(opts.sources, { name = "mini_snippets" })
+ else
+ expand_select_override = function(snippets, insert)
+ -- stylua: ignore
+ if cmp.visible() then cmp.close() end
+ MiniSnippets.default_select(snippets, insert)
+ end
+ end
+ end,
+ -- stylua: ignore
+ -- counterpart to defined in cmp.mappings
+ keys = include_in_completion and { { "", function() jump("prev") end, mode = "i" } } or nil,
+ },
+
+ -- blink.cmp integration
+ {
+ "saghen/blink.cmp",
+ optional = true,
+ opts = function(_, opts)
+ -- Return early
+ if include_in_completion then
+ opts.snippets = { preset = "mini_snippets" }
+ return
+ end
+
+ -- Standalone --
+ expand_select_override = function(snippets, insert)
+ -- Schedule, otherwise blink's virtual text is not removed on vim.ui.select
+ require("blink.cmp").cancel()
+ vim.schedule(function()
+ MiniSnippets.default_select(snippets, insert)
+ end)
+ end
+ --
+ -- Blink performs a require on blink.cmp.sources.snippets.default
+ -- By removing the source, the default engine will not be used
+ opts.sources.default = vim.tbl_filter(function(source)
+ return source ~= "snippets"
+ end, opts.sources.default)
+ opts.snippets = { -- need to repeat blink's preset here
+ expand = expand_from_lsp,
+ active = function()
+ return MiniSnippets.session.get(false) ~= nil
+ end,
+ jump = function(direction)
+ jump(direction == -1 and "prev" or "next")
+ end,
+ }
+ end,
+ },
+}
diff --git a/lua/lazyvim/plugins/extras/editor/snacks_explorer.lua b/lua/lazyvim/plugins/extras/editor/snacks_explorer.lua
new file mode 100644
index 00000000..aa87e85c
--- /dev/null
+++ b/lua/lazyvim/plugins/extras/editor/snacks_explorer.lua
@@ -0,0 +1,25 @@
+return {
+ { "nvim-neo-tree/neo-tree.nvim", enabled = false },
+ {
+ "folke/snacks.nvim",
+ opts = { explorer = {} },
+ keys = {
+ {
+ "fe",
+ function()
+ Snacks.explorer({ cwd = LazyVim.root() })
+ end,
+ desc = "Explorer Snacks (root dir)",
+ },
+ {
+ "fE",
+ function()
+ Snacks.explorer()
+ end,
+ desc = "Explorer Snacks (cwd)",
+ },
+ { "e", "fe", desc = "Explorer Snacks (root dir)", remap = true },
+ { "E", "fE", desc = "Explorer Snacks (cwd)", remap = true },
+ },
+ },
+}
diff --git a/lua/lazyvim/plugins/extras/editor/snacks_picker.lua b/lua/lazyvim/plugins/extras/editor/snacks_picker.lua
index e286dff3..b6b6deee 100644
--- a/lua/lazyvim/plugins/extras/editor/snacks_picker.lua
+++ b/lua/lazyvim/plugins/extras/editor/snacks_picker.lua
@@ -27,11 +27,32 @@ end
return {
desc = "Fast and modern file picker",
- -- recommended = true,
+ recommended = true,
{
"folke/snacks.nvim",
opts = {
- picker = {},
+ picker = {
+ win = {
+ input = {
+ keys = {
+ [""] = {
+ "toggle_cwd",
+ mode = { "n", "i" },
+ },
+ },
+ },
+ },
+ actions = {
+ ---@param p snacks.Picker
+ toggle_cwd = function(p)
+ local root = LazyVim.root({ buf = p.input.filter.current_buf, normalize = true })
+ local cwd = vim.fs.normalize((vim.uv or vim.loop).cwd() or ".")
+ local current = p:cwd()
+ p:set_cwd(current == root and cwd or root)
+ p:find()
+ end,
+ },
+ },
},
-- stylua: ignore
keys = {
@@ -39,14 +60,17 @@ return {
{ "/", LazyVim.pick("grep"), desc = "Grep (Root Dir)" },
{ ":", function() Snacks.picker.command_history() end, desc = "Command History" },
{ "", LazyVim.pick("files"), desc = "Find Files (Root Dir)" },
+ { "n", function() Snacks.picker.notifications() end, desc = "Notification History" },
-- find
{ "fb", function() Snacks.picker.buffers() end, desc = "Buffers" },
+ { "fB", function() Snacks.picker.buffers({ hidden = true, nofile = true }) end, desc = "Buffers (all)" },
{ "fc", LazyVim.pick.config_files(), desc = "Find Config File" },
{ "ff", LazyVim.pick("files"), desc = "Find Files (Root Dir)" },
{ "fF", LazyVim.pick("files", { root = false }), desc = "Find Files (cwd)" },
{ "fg", function() Snacks.picker.git_files() end, desc = "Find Files (git-files)" },
{ "fr", LazyVim.pick("oldfiles"), desc = "Recent" },
- { "fR", LazyVim.pick("oldfiles", { filter = { cwd = true }}), desc = "Recent (cwd)" },
+ { "fR", function() Snacks.picker.recent({ filter = { cwd = true }}) end, desc = "Recent (cwd)" },
+ { "fp", function() Snacks.picker.projects() end, desc = "Projects" },
-- git
{ "gc", function() Snacks.picker.git_log() end, desc = "Git Log" },
{ "gd", function() Snacks.picker.git_diff() end, desc = "Git Diff (hunks)" },
@@ -56,6 +80,7 @@ return {
{ "sB", function() Snacks.picker.grep_buffers() end, desc = "Grep Open Buffers" },
{ "sg", LazyVim.pick("live_grep"), desc = "Grep (Root Dir)" },
{ "sG", LazyVim.pick("live_grep", { root = false }), desc = "Grep (cwd)" },
+ { "sp", function() Snacks.picker.lazy() end, desc = "Search for Plugin Spec" },
{ "sw", LazyVim.pick("grep_word"), desc = "Visual selection or word (Root Dir)", mode = { "n", "x" } },
{ "sW", LazyVim.pick("grep_word", { root = false }), desc = "Visual selection or word (cwd)", mode = { "n", "x" } },
-- search
@@ -66,6 +91,7 @@ return {
{ "sd", function() Snacks.picker.diagnostics() end, desc = "Diagnostics" },
{ "sh", function() Snacks.picker.help() end, desc = "Help Pages" },
{ "sH", function() Snacks.picker.highlights() end, desc = "Highlights" },
+ { "si", function() Snacks.picker.icons() end, desc = "Icons" },
{ "sj", function() Snacks.picker.jumps() end, desc = "Jumps" },
{ "sk", function() Snacks.picker.keymaps() end, desc = "Keymaps" },
{ "sl", function() Snacks.picker.loclist() end, desc = "Location List" },
@@ -73,8 +99,9 @@ return {
{ "sm", function() Snacks.picker.marks() end, desc = "Marks" },
{ "sR", function() Snacks.picker.resume() end, desc = "Resume" },
{ "sq", function() Snacks.picker.qflist() end, desc = "Quickfix List" },
+ { "su", function() Snacks.picker.undo() end, desc = "Undotree" },
+ -- ui
{ "uC", function() Snacks.picker.colorschemes() end, desc = "Colorschemes" },
- { "fp", function() Snacks.picker.projects() end, desc = "Projects" },
},
},
{
@@ -126,4 +153,45 @@ return {
{ "sT", function () Snacks.picker.todo_comments({ keywords = { "TODO", "FIX", "FIXME" } }) end, desc = "Todo/Fix/Fixme" },
},
},
+ {
+ "folke/flash.nvim",
+ optional = true,
+ specs = {
+ {
+ "folke/snacks.nvim",
+ opts = {
+ picker = {
+ win = {
+ input = {
+ keys = {
+ [""] = { "flash", mode = { "n", "i" } },
+ ["s"] = { "flash" },
+ },
+ },
+ },
+ actions = {
+ flash = function(picker)
+ require("flash").jump({
+ pattern = "^",
+ label = { after = { 0, 0 } },
+ search = {
+ mode = "search",
+ exclude = {
+ function(win)
+ return vim.bo[vim.api.nvim_win_get_buf(win)].filetype ~= "snacks_picker_list"
+ end,
+ },
+ },
+ action = function(match)
+ local idx = picker.list:row2idx(match.pos[1])
+ picker.list:_move(idx, true, true)
+ end,
+ })
+ end,
+ },
+ },
+ },
+ },
+ },
+ },
}
diff --git a/lua/lazyvim/plugins/extras/lang/markdown.lua b/lua/lazyvim/plugins/extras/lang/markdown.lua
index a73fe114..8b07985b 100644
--- a/lua/lazyvim/plugins/extras/lang/markdown.lua
+++ b/lua/lazyvim/plugins/extras/lang/markdown.lua
@@ -108,7 +108,7 @@ return {
enabled = false,
},
},
- ft = { "markdown", "norg", "rmd", "org" },
+ ft = { "markdown", "norg", "rmd", "org", "codecompanion" },
config = function(_, opts)
require("render-markdown").setup(opts)
Snacks.toggle({
diff --git a/lua/lazyvim/plugins/extras/lang/sql.lua b/lua/lazyvim/plugins/extras/lang/sql.lua
index 075182d6..83de5ee1 100644
--- a/lua/lazyvim/plugins/extras/lang/sql.lua
+++ b/lua/lazyvim/plugins/extras/lang/sql.lua
@@ -48,7 +48,7 @@ return {
vim.api.nvim_create_autocmd("FileType", {
pattern = sql_ft,
callback = function()
- if LazyVim.has("nvim-cmp") then
+ if LazyVim.cmp_engine() == "nvim-cmp" then
local cmp = require("cmp")
-- global sources
diff --git a/lua/lazyvim/plugins/extras/vscode.lua b/lua/lazyvim/plugins/extras/vscode.lua
index b9b1e0b1..5115a2b4 100644
--- a/lua/lazyvim/plugins/extras/vscode.lua
+++ b/lua/lazyvim/plugins/extras/vscode.lua
@@ -57,9 +57,14 @@ return {
{
"snacks.nvim",
opts = {
+ bigfile = { enabled = false },
+ dashboard = { enabled = false },
indent = { enabled = false },
- scroll = { enabled = false },
+ input = { enabled = false },
notifier = { enabled = false },
+ picker = { enabled = false },
+ quickfile = { enabled = false },
+ scroll = { enabled = false },
statuscolumn = { enabled = false },
},
},
diff --git a/lua/lazyvim/plugins/ui.lua b/lua/lazyvim/plugins/ui.lua
index d556d1f1..6e03a217 100644
--- a/lua/lazyvim/plugins/ui.lua
+++ b/lua/lazyvim/plugins/ui.lua
@@ -278,7 +278,13 @@ return {
},
-- stylua: ignore
keys = {
- { "n", function() Snacks.notifier.show_history() end, desc = "Notification History" },
+ { "n", function()
+ if Snacks.config.picker and Snacks.config.picker.enabled then
+ Snacks.picker.notifications()
+ else
+ Snacks.notifier.show_history()
+ end
+ end, desc = "Notification History" },
{ "un", function() Snacks.notifier.hide() end, desc = "Dismiss All Notifications" },
},
},
diff --git a/lua/lazyvim/util/root.lua b/lua/lazyvim/util/root.lua
index b723b227..fc6d6d7d 100644
--- a/lua/lazyvim/util/root.lua
+++ b/lua/lazyvim/util/root.lua
@@ -1,8 +1,8 @@
---@class lazyvim.util.root
---@overload fun(): string
local M = setmetatable({}, {
- __call = function(m)
- return m.get()
+ __call = function(m, ...)
+ return m.get(...)
end,
})