diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index 9da34491..b25a6511 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "15.1.0" + ".": "15.2.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b8723e8..21249147 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,33 @@ # Changelog +## [15.2.0](https://github.com/LazyVim/LazyVim/compare/v15.1.1...v15.2.0) (2025-09-20) + + +### Features + +* **clojure:** use 'nvim-paredit' instead 'nvim-treesitter-sexp' as clojure S-exp Plugin ([#5876](https://github.com/LazyVim/LazyVim/issues/5876)) ([2659028](https://github.com/LazyVim/LazyVim/commit/26590285ead7a89bb45f309714f7f40136c89267)) +* **core:** relax hard requirement for `vim.lsp.is_enabled`. Show warning instead ([3ca7b47](https://github.com/LazyVim/LazyVim/commit/3ca7b47365c85a07047e48cad450feff66c8bdd6)) +* **options:** don't overwrite indentexpr/foldexpr/foldmethod when set by plugins. Fixes [#6464](https://github.com/LazyVim/LazyVim/issues/6464) ([ccbaf55](https://github.com/LazyVim/LazyVim/commit/ccbaf55c2f8bc691f8f64fe40ce00a1abda4fbac)) +* **yanky:** use snacks picker for improved yank history navigation ([#5802](https://github.com/LazyVim/LazyVim/issues/5802)) ([55e762a](https://github.com/LazyVim/LazyVim/commit/55e762a8888cd5f336e4e2d4b2cc6b8b1b950663)) + + +### Bug Fixes + +* **editor:** calculate the height passed to the prompt of fzf-lua properly ([#6481](https://github.com/LazyVim/LazyVim/issues/6481)) ([65e38d3](https://github.com/LazyVim/LazyVim/commit/65e38d3b34cab653a05318c1a9014df3c89fdb53)) +* **lang.clojure:** correct cmp-conjure source name ([#6208](https://github.com/LazyVim/LazyVim/issues/6208)) ([55b5c1f](https://github.com/LazyVim/LazyVim/commit/55b5c1fecb0b7e71c5eb40555b17d1e4820690f0)) +* **options:** set_default option ([2401d5f](https://github.com/LazyVim/LazyVim/commit/2401d5fca6f2a2fcaca4f9c4c84c4b713c602352)) +* **options:** track some initial options right after loading `options.lua`. See [#6463](https://github.com/LazyVim/LazyVim/issues/6463) ([9c611b0](https://github.com/LazyVim/LazyVim/commit/9c611b0c5758d0d659e7fdb29119b7083a56f989)) +* **treesitter:** check if queries for indent/fold exists before enabling it. Fixes [#6474](https://github.com/LazyVim/LazyVim/issues/6474) ([5ce7cd6](https://github.com/LazyVim/LazyVim/commit/5ce7cd650a5fffc257e0312b82fffd26abe2a1fa)) + +## [15.1.1](https://github.com/LazyVim/LazyVim/compare/v15.1.0...v15.1.1) (2025-09-18) + + +### Bug Fixes + +* **core:** check for outdated nightly. See [#6458](https://github.com/LazyVim/LazyVim/issues/6458) ([cfac3c9](https://github.com/LazyVim/LazyVim/commit/cfac3c9a85526ad7406f9b246097a1ec4fa1a2c3)) +* **lspconfig:** remove all usage of `lspconfig` ([36b4191](https://github.com/LazyVim/LazyVim/commit/36b41911ab90fe19505af306a31a5a699342d3c3)) +* **lsp:** schedule_wrap setting up LSPs to work around root cause of [#6456](https://github.com/LazyVim/LazyVim/issues/6456). Fixes [#6456](https://github.com/LazyVim/LazyVim/issues/6456) ([75a3809](https://github.com/LazyVim/LazyVim/commit/75a3809e15a0ecff9adc46c6cd3aaac51d99b561)) + ## [15.1.0](https://github.com/LazyVim/LazyVim/compare/v15.0.3...v15.1.0) (2025-09-18) diff --git a/doc/LazyVim.txt b/doc/LazyVim.txt index 5c3e670d..f7f29509 100644 --- a/doc/LazyVim.txt +++ b/doc/LazyVim.txt @@ -1,4 +1,4 @@ -*LazyVim.txt* For Neovim Last change: 2025 September 18 +*LazyVim.txt* For Neovim Last change: 2025 September 20 ============================================================================== Table of Contents *LazyVim-table-of-contents* diff --git a/lua/lazyvim/config/init.lua b/lua/lazyvim/config/init.lua index d12f2ac0..e85dbd63 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 = "15.1.0" -- x-release-please-version +M.version = "15.2.0" -- x-release-please-version LazyVim.config = M ---@class LazyVimOptions @@ -304,6 +304,8 @@ function M.load(name) end M.did_init = false +M._options = {} ---@type vim.wo|vim.bo + function M.init() if M.did_init then return @@ -326,6 +328,12 @@ function M.init() -- this is needed to make sure options will be correctly applied -- after installing missing plugins M.load("options") + + -- save some options to track defaults + M._options.indentexpr = vim.o.indentexpr + M._options.foldmethod = vim.o.foldmethod + M._options.foldexpr = vim.o.foldexpr + -- defer built-in clipboard handling: "xsel" and "pbcopy" can be slow lazy_clipboard = vim.opt.clipboard vim.opt.clipboard = "" diff --git a/lua/lazyvim/plugins/extras/coding/yanky.lua b/lua/lazyvim/plugins/extras/coding/yanky.lua index c880aceb..6285796d 100644 --- a/lua/lazyvim/plugins/extras/coding/yanky.lua +++ b/lua/lazyvim/plugins/extras/coding/yanky.lua @@ -13,6 +13,8 @@ return { function() if LazyVim.pick.picker.name == "telescope" then require("telescope").extensions.yank_history.yank_history({}) + elseif LazyVim.pick.picker.name == "snacks" then + Snacks.picker.yanky() else vim.cmd([[YankyRingHistory]]) end diff --git a/lua/lazyvim/plugins/extras/editor/fzf.lua b/lua/lazyvim/plugins/extras/editor/fzf.lua index 31297b94..9e7ef671 100644 --- a/lua/lazyvim/plugins/extras/editor/fzf.lua +++ b/lua/lazyvim/plugins/extras/editor/fzf.lua @@ -120,7 +120,7 @@ return { winopts = { layout = "vertical", -- height is number of items minus 15 lines for the preview, with a max of 80% screen height - height = math.floor(math.min(vim.o.lines * 0.8 - 16, #items + 2) + 0.5) + 16, + height = math.floor(math.min(vim.o.lines * 0.8 - 16, #items + 4) + 0.5) + 16, width = 0.5, preview = not vim.tbl_isempty(vim.lsp.get_clients({ bufnr = 0, name = "vtsls" })) and { layout = "vertical", @@ -135,7 +135,7 @@ return { winopts = { width = 0.5, -- height is number of items, with a max of 80% screen height - height = math.floor(math.min(vim.o.lines * 0.8, #items + 2) + 0.5), + height = math.floor(math.min(vim.o.lines * 0.8, #items + 4) + 0.5), }, }) end, diff --git a/lua/lazyvim/plugins/extras/lang/clojure.lua b/lua/lazyvim/plugins/extras/lang/clojure.lua index 7197aabd..c7af0b55 100644 --- a/lua/lazyvim/plugins/extras/lang/clojure.lua +++ b/lua/lazyvim/plugins/extras/lang/clojure.lua @@ -21,13 +21,13 @@ return { }, opts = function(_, opts) if type(opts.sources) == "table" then - vim.list_extend(opts.sources, { name = "clojure" }) + vim.list_extend(opts.sources, { name = "conjure" }) end end, }, -- Add s-exp mappings - { "PaterJason/nvim-treesitter-sexp", opts = {}, event = "LazyFile" }, + { "julienvincent/nvim-paredit", opts = {}, event = "LazyFile" }, -- Colorize the output of the log buffer { diff --git a/lua/lazyvim/plugins/extras/lang/java.lua b/lua/lazyvim/plugins/extras/lang/java.lua index e4926521..d4eb5f6e 100644 --- a/lua/lazyvim/plugins/extras/lang/java.lua +++ b/lua/lazyvim/plugins/extras/lang/java.lua @@ -91,7 +91,9 @@ return { table.insert(cmd, string.format("--jvm-arg=-javaagent:%s", lombok_jar)) end return { - root_dir = require("lspconfig.util").root_pattern(vim.lsp.config.jdtls.root_markers), + root_dir = function(path) + return vim.fs.root(path, vim.lsp.config.jdtls.root_markers) + end, -- How to find the project name for a given root dir. project_name = function(root_dir) diff --git a/lua/lazyvim/plugins/extras/lang/ocaml.lua b/lua/lazyvim/plugins/extras/lang/ocaml.lua index 0e733a4a..631223d4 100644 --- a/lua/lazyvim/plugins/extras/lang/ocaml.lua +++ b/lua/lazyvim/plugins/extras/lang/ocaml.lua @@ -26,12 +26,19 @@ return { "reason", "dune", }, - root_dir = function(bufnr, on_dir) - local util = require("lspconfig.util") - local fname = vim.api.nvim_buf_get_name(bufnr) - --stylua: ignore - on_dir(util.root_pattern("*.opam", "esy.json", "package.json", ".git", "dune-project", "dune-workspace", "*.ml")( fname)) - end, + root_markers = { + function(name) + return name:match(".*%.opam$") + end, + "esy.json", + "package.json", + ".git", + "dune-project", + "dune-workspace", + function(name) + return name:match(".*%.ml$") + end, + }, }, }, }, diff --git a/lua/lazyvim/plugins/init.lua b/lua/lazyvim/plugins/init.lua index 7797b047..80394371 100644 --- a/lua/lazyvim/plugins/init.lua +++ b/lua/lazyvim/plugins/init.lua @@ -7,6 +7,14 @@ if vim.fn.has("nvim-0.11.2") == 0 then vim.fn.getchar() vim.cmd([[quit]]) return {} +elseif not vim.lsp.is_enabled then + vim.schedule(function() + LazyVim.warn({ + "You're using an **old** `nightly` version of **Neovim**", + "Please update to a recent `nightly`,", + "or a stable version (`>= 0.11.2`).", + }) + end) end require("lazyvim.config").init() diff --git a/lua/lazyvim/plugins/lsp/init.lua b/lua/lazyvim/plugins/lsp/init.lua index 1984c31b..51b6f022 100644 --- a/lua/lazyvim/plugins/lsp/init.lua +++ b/lua/lazyvim/plugins/lsp/init.lua @@ -2,7 +2,7 @@ return { -- lspconfig { "neovim/nvim-lspconfig", - event = { "BufReadPre", "BufNewFile", "BufWritePre" }, + event = "LazyFile", dependencies = { "mason.nvim", { "mason-org/mason-lspconfig.nvim", config = function() end }, @@ -118,7 +118,7 @@ return { return ret end, ---@param opts PluginLspOpts - config = function(_, opts) + config = vim.schedule_wrap(function(_, opts) -- setup autoformat LazyVim.format.register(LazyVim.lsp.formatter()) @@ -146,9 +146,9 @@ return { -- folds if opts.folds.enabled then LazyVim.lsp.on_supports_method("textDocument/foldingRange", function(client, buffer) - local win = vim.api.nvim_get_current_win() - vim.wo[win][0].foldexpr = "v:lua.vim.lsp.foldexpr()" - vim.wo[win][0].foldmethod = "expr" + if LazyVim.set_default("foldmethod", "expr") then + LazyVim.set_default("foldexpr", "v:lua.vim.lsp.foldexpr()") + end end) end @@ -235,7 +235,7 @@ return { }) end - if vim.lsp.is_enabled("denols") and vim.lsp.is_enabled("vtsls") then + if vim.lsp.is_enabled and vim.lsp.is_enabled("denols") and vim.lsp.is_enabled("vtsls") then ---@param server string local resolve = function(server) local markers, root_dir = vim.lsp.config[server].root_markers, vim.lsp.config[server].root_dir @@ -256,7 +256,7 @@ return { resolve("denols") resolve("vtsls") end - end, + end), }, -- cmdline tools and lsp servers diff --git a/lua/lazyvim/plugins/treesitter.lua b/lua/lazyvim/plugins/treesitter.lua index a7ef7ed8..5721979d 100644 --- a/lua/lazyvim/plugins/treesitter.lua +++ b/lua/lazyvim/plugins/treesitter.lua @@ -94,14 +94,15 @@ return { end -- indents - if vim.tbl_get(opts, "indent", "enable") ~= false then - vim.bo[ev.buf].indentexpr = "v:lua.LazyVim.treesitter.indentexpr()" + if vim.tbl_get(opts, "indent", "enable") ~= false and LazyVim.treesitter.have(ev.match, "indents") then + LazyVim.set_default("indentexpr", "v:lua.LazyVim.treesitter.indentexpr()") end -- folds - if vim.tbl_get(opts, "folds", "enable") ~= false then - vim.wo.foldmethod = "expr" - vim.wo.foldexpr = "v:lua.LazyVim.treesitter.foldexpr()" + if vim.tbl_get(opts, "folds", "enable") ~= false and LazyVim.treesitter.have(ev.match, "folds") then + if LazyVim.set_default("foldmethod", "expr") then + LazyVim.set_default("foldexpr", "v:lua.LazyVim.treesitter.foldexpr()") + end end end, }) diff --git a/lua/lazyvim/util/init.lua b/lua/lazyvim/util/init.lua index 44a135ad..812e6f22 100644 --- a/lua/lazyvim/util/init.lua +++ b/lua/lazyvim/util/init.lua @@ -304,4 +304,58 @@ function M.statuscolumn() return package.loaded.snacks and require("snacks.statuscolumn").get() or "" end +local _defaults = {} ---@type table + +-- Determines whether it's safe to set an option to a default value. +-- +-- It will only set the option if: +-- * it is the same as the global value +-- * it's current value is a default value +-- * it was last set by a script in $VIMRUNTIME +---@param option string +---@param value string|number|boolean +---@return boolean was_set +function M.set_default(option, value) + local l = vim.api.nvim_get_option_value(option, { scope = "local" }) + local g = LazyVim.config._options[option] or vim.api.nvim_get_option_value(option, { scope = "global" }) + + _defaults[("%s=%s"):format(option, value)] = true + local key = ("%s=%s"):format(option, l) + + local source = "" + if l ~= g and not _defaults[key] then + -- Option does not match global and is not a default value + -- Check if it was set by a script in $VIMRUNTIME + local info = vim.api.nvim_get_option_info2(option, { scope = "local" }) + ---@param e vim.fn.getscriptinfo.ret + local scriptinfo = vim.tbl_filter(function(e) + return e.sid == info.last_set_sid + end, vim.fn.getscriptinfo()) + source = scriptinfo[1] and scriptinfo[1].name or "" + local by_rtp = #scriptinfo == 1 and vim.startswith(scriptinfo[1].name, vim.fn.expand("$VIMRUNTIME")) + if not by_rtp then + if vim.g.lazyvim_debug_set_default then + LazyVim.warn( + ("Not setting option `%s` to `%q` because it was changed by a plugin."):format(option, value), + { title = "LazyVim", once = true } + ) + end + return false + end + end + + if vim.g.lazyvim_debug_set_default then + LazyVim.info({ + ("Setting option `%s` to `%q`"):format(option, value), + ("Was: %q"):format(l), + ("Global: %q"):format(g), + source ~= "" and ("Last set by: %s"):format(source) or "", + "buf: " .. vim.api.nvim_buf_get_name(0), + }, { title = "LazyVim", once = true }) + end + + vim.api.nvim_set_option_value(option, value, { scope = "local" }) + return true +end + return M diff --git a/lua/lazyvim/util/treesitter.lua b/lua/lazyvim/util/treesitter.lua index 5df6aa53..b1d647e8 100644 --- a/lua/lazyvim/util/treesitter.lua +++ b/lua/lazyvim/util/treesitter.lua @@ -1,36 +1,54 @@ ---@class lazyvim.util.treesitter local M = {} -M._installed = nil ---@type table? +M._installed = nil ---@type table? +M._queries = {} ---@type table ---@param update boolean? function M.get_installed(update) if update then - M._installed = {} + M._installed, M._queries = {}, {} for _, lang in ipairs(require("nvim-treesitter").get_installed("parsers")) do - M._installed[lang] = lang + M._installed[lang] = true end end return M._installed or {} end +---@param lang string +---@param query string +function M.have_query(lang, query) + local key = lang .. ":" .. query + if M._queries[key] == nil then + M._queries[key] = vim.treesitter.query.get(lang, query) ~= nil + end + return M._queries[key] +end + ---@param what string|number|nil +---@param query? string ---@overload fun(buf?:number):boolean ---@overload fun(ft:string):boolean ---@return boolean -function M.have(what) +function M.have(what, query) what = what or vim.api.nvim_get_current_buf() what = type(what) == "number" and vim.bo[what].filetype or what --[[@as string]] local lang = vim.treesitter.language.get_lang(what) - return lang ~= nil and M.get_installed()[lang] ~= nil + if lang == nil or M.get_installed()[lang] == nil then + return false + end + if query and not M.have_query(lang, query) then + return false + end + return true end function M.foldexpr() - return M.have() and vim.treesitter.foldexpr() or "0" + return M.have(nil, "folds") and vim.treesitter.foldexpr() or "0" end function M.indentexpr() - return M.have() and require("nvim-treesitter").indentexpr() or -1 + return M.have(nil, "indents") and require("nvim-treesitter").indentexpr() or -1 end ---@param cb fun()