diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index b0e2e610..8a820181 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "15.3.0" + ".": "15.4.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b8c6724..abe4b7c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## [15.4.0](https://github.com/LazyVim/LazyVim/compare/v15.3.0...v15.4.0) (2025-09-26) + + +### Features + +* **copilot-native:** added experimental support for next edit suggestions. check the docs to enable ([c83df9e](https://github.com/LazyVim/LazyVim/commit/c83df9e68dd41f5a3f7df5a7048169ee286a7da8)) +* **copilot-native:** added keymaps to cycle suggestions ([6bd630c](https://github.com/LazyVim/LazyVim/commit/6bd630cec6f905665691d593dc5d0fb3d54f560c)) +* **copilot-native:** better lualine status ([9913e16](https://github.com/LazyVim/LazyVim/commit/9913e1665d783d9c4407633bc33475d403aff433)) +* **copilot-native:** removed experimental **nes** support with `copilot_lsp` for now, since it's not the best experience right now ([ed637bb](https://github.com/LazyVim/LazyVim/commit/ed637bb0f7f418de069a4d5a7ed8a7b3b93eb425)) +* **copilot:** added `copilot-native` extra to setup native inline completions in Neovim ([3b02963](https://github.com/LazyVim/LazyVim/commit/3b0296358508da1eb258c8716df163dd04fa6449)) + + +### Bug Fixes + +* **catppuccin:** follow-up on api change ([#6505](https://github.com/LazyVim/LazyVim/issues/6505)) ([af6e250](https://github.com/LazyVim/LazyVim/commit/af6e2505b54270c30145e8f4191b865870537287)) +* **treesitter:** create buffer-local textobjects keymaps only when available. Closes [#6508](https://github.com/LazyVim/LazyVim/issues/6508) ([5985ca0](https://github.com/LazyVim/LazyVim/commit/5985ca0cf1a0c1ddee8b2b718c730f988cec7001)) + ## [15.3.0](https://github.com/LazyVim/LazyVim/compare/v15.2.0...v15.3.0) (2025-09-23) diff --git a/doc/LazyVim.txt b/doc/LazyVim.txt index dbeb4819..8d0a76e9 100644 --- a/doc/LazyVim.txt +++ b/doc/LazyVim.txt @@ -1,4 +1,4 @@ -*LazyVim.txt* For Neovim Last change: 2025 September 23 +*LazyVim.txt* For Neovim Last change: 2025 September 26 ============================================================================== Table of Contents *LazyVim-table-of-contents* diff --git a/lua/lazyvim/config/init.lua b/lua/lazyvim/config/init.lua index 1d288cd2..39c719cf 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.3.0" -- x-release-please-version +M.version = "15.4.0" -- x-release-please-version LazyVim.config = M ---@class LazyVimOptions diff --git a/lua/lazyvim/plugins/colorscheme.lua b/lua/lazyvim/plugins/colorscheme.lua index 4c41d492..0e19c87f 100644 --- a/lua/lazyvim/plugins/colorscheme.lua +++ b/lua/lazyvim/plugins/colorscheme.lua @@ -13,6 +13,14 @@ return { lazy = true, name = "catppuccin", opts = { + lsp_styles = { + underlines = { + errors = { "undercurl" }, + hints = { "undercurl" }, + warnings = { "undercurl" }, + information = { "undercurl" }, + }, + }, integrations = { aerial = true, alpha = true, @@ -28,26 +36,14 @@ return { leap = true, lsp_trouble = true, mason = true, - markdown = true, mini = true, - native_lsp = { - enabled = true, - underlines = { - errors = { "undercurl" }, - hints = { "undercurl" }, - warnings = { "undercurl" }, - information = { "undercurl" }, - }, - }, navic = { enabled = true, custom_bg = "lualine" }, neotest = true, neotree = true, noice = true, notify = true, - semantic_tokens = true, snacks = true, telescope = true, - treesitter = true, treesitter_context = true, which_key = true, }, @@ -58,7 +54,7 @@ return { optional = true, opts = function(_, opts) if (vim.g.colors_name or ""):find("catppuccin") then - opts.highlights = require("catppuccin.groups.integrations.bufferline").get_theme() + opts.highlights = require("catppuccin.special.bufferline").get_theme() end end, }, diff --git a/lua/lazyvim/plugins/extras/ai/copilot-native.lua b/lua/lazyvim/plugins/extras/ai/copilot-native.lua new file mode 100644 index 00000000..310fbd81 --- /dev/null +++ b/lua/lazyvim/plugins/extras/ai/copilot-native.lua @@ -0,0 +1,93 @@ +---@diagnostic disable: missing-fields +if lazyvim_docs then + -- Native inline completions don't support being shown as regular completions + vim.g.ai_cmp = false +end + +if LazyVim.has_extra("ai.copilot-native") then + if not vim.lsp.inline_completion then + LazyVim.error("You need Neovim >= 0.12 to use the `ai.copilot-native` extra.") + return {} + end + if LazyVim.has_extra("ai.copilot") then + LazyVim.error("Please disable the `ai.copilot` extra if you want to use `ai.copilot-native`") + return {} + end +end + +vim.g.ai_cmp = false +local status = {} ---@type table + +return { + desc = "Native Copilot LSP integration. Requires Neovim >= 0.12", + -- copilot-language-server + { + "neovim/nvim-lspconfig", + opts = { + servers = { + copilot = { + -- stylua: ignore + keys = { + { + "", + function() vim.lsp.inline_completion.select({ count = 1 }) end, + desc = "Next Copilot Suggestion", + mode = { "i", "n" }, + }, + { + "", + function() vim.lsp.inline_completion.select({ count = -1 }) end, + desc = "Next Copilot Suggestion", + mode = { "i", "n" }, + }, + }, + }, + }, + setup = { + copilot = function() + vim.lsp.inline_completion.enable() + -- Accept inline suggestions or next edits + LazyVim.cmp.actions.ai_accept = function() + return vim.lsp.inline_completion.get() + end + + if not LazyVim.has_extra("ai.sidekick") then + vim.lsp.config("copilot", { + handlers = { + didChangeStatus = function(err, res, ctx) + if err then + return + end + status[ctx.client_id] = res.kind ~= "Normal" and "error" or res.busy and "pending" or "ok" + if res.status == "Error" then + LazyVim.error("Please use `:LspCopilotSignIn` to sign in to Copilot") + end + end, + }, + }) + end + end, + }, + }, + }, + + -- lualine + { + "nvim-lualine/lualine.nvim", + optional = true, + event = "VeryLazy", + opts = function(_, opts) + if LazyVim.has_extra("ai.sidekick") then + return + end + table.insert( + opts.sections.lualine_x, + 2, + LazyVim.lualine.status(LazyVim.config.icons.kinds.Copilot, function() + local clients = vim.lsp.get_clients({ name = "copilot", bufnr = 0 }) + return #clients > 0 and status[clients[1].id] or nil + end) + ) + end, + }, +} diff --git a/lua/lazyvim/plugins/extras/ai/copilot.lua b/lua/lazyvim/plugins/extras/ai/copilot.lua index 7c326499..3b5d2275 100644 --- a/lua/lazyvim/plugins/extras/ai/copilot.lua +++ b/lua/lazyvim/plugins/extras/ai/copilot.lua @@ -25,6 +25,17 @@ return { }, }, + -- copilot-language-server + { + "neovim/nvim-lspconfig", + opts = { + servers = { + -- copilot.lua only works with its own copilot lsp server + copilot = { enabled = false }, + }, + }, + }, + -- add ai_accept action { "zbirenbaum/copilot.lua", diff --git a/lua/lazyvim/plugins/extras/coding/blink.lua b/lua/lazyvim/plugins/extras/coding/blink.lua index 207b1940..790808b1 100644 --- a/lua/lazyvim/plugins/extras/coding/blink.lua +++ b/lua/lazyvim/plugins/extras/coding/blink.lua @@ -122,12 +122,12 @@ return { if opts.keymap.preset == "super-tab" then -- super-tab opts.keymap[""] = { require("blink.cmp.keymap.presets").get("super-tab")[""][1], - LazyVim.cmp.map({ "snippet_forward", "ai_accept" }), + LazyVim.cmp.map({ "snippet_forward", "ai_nes", "ai_accept" }), "fallback", } else -- other presets opts.keymap[""] = { - LazyVim.cmp.map({ "snippet_forward", "ai_accept" }), + LazyVim.cmp.map({ "snippet_forward", "ai_nes", "ai_accept" }), "fallback", } end diff --git a/lua/lazyvim/plugins/extras/coding/nvim-cmp.lua b/lua/lazyvim/plugins/extras/coding/nvim-cmp.lua index 54bfbf7c..fab56250 100644 --- a/lua/lazyvim/plugins/extras/coding/nvim-cmp.lua +++ b/lua/lazyvim/plugins/extras/coding/nvim-cmp.lua @@ -52,7 +52,7 @@ return { fallback() end, [""] = function(fallback) - return LazyVim.cmp.map({ "snippet_forward", "ai_accept" }, fallback)() + return LazyVim.cmp.map({ "snippet_forward", "ai_nes", "ai_accept" }, fallback)() end, }), sources = cmp.config.sources({ diff --git a/lua/lazyvim/plugins/treesitter.lua b/lua/lazyvim/plugins/treesitter.lua index 8ad15924..78f1b3b2 100644 --- a/lua/lazyvim/plugins/treesitter.lua +++ b/lua/lazyvim/plugins/treesitter.lua @@ -128,38 +128,19 @@ return { "nvim-treesitter/nvim-treesitter-textobjects", branch = "main", event = "VeryLazy", - opts = {}, - keys = function() - local moves = { - goto_next_start = { ["]f"] = "@function.outer", ["]c"] = "@class.outer", ["]a"] = "@parameter.inner" }, - goto_next_end = { ["]F"] = "@function.outer", ["]C"] = "@class.outer", ["]A"] = "@parameter.inner" }, - goto_previous_start = { ["[f"] = "@function.outer", ["[c"] = "@class.outer", ["[a"] = "@parameter.inner" }, - goto_previous_end = { ["[F"] = "@function.outer", ["[C"] = "@class.outer", ["[A"] = "@parameter.inner" }, - } - local ret = {} ---@type LazyKeysSpec[] - for method, keymaps in pairs(moves) do - for key, query in pairs(keymaps) do - local desc = query:gsub("@", ""):gsub("%..*", "") - desc = desc:sub(1, 1):upper() .. desc:sub(2) - desc = (key:sub(1, 1) == "[" and "Prev " or "Next ") .. desc - desc = desc .. (key:sub(2, 2) == key:sub(2, 2):upper() and " End" or " Start") - ret[#ret + 1] = { - key, - function() - -- don't use treesitter if in diff mode and the key is one of the c/C keys - if vim.wo.diff and key:find("[cC]") then - return vim.cmd("normal! " .. key) - end - require("nvim-treesitter-textobjects.move")[method](query, "textobjects") - end, - desc = desc, - mode = { "n", "x", "o" }, - silent = true, - } - end - end - return ret - end, + opts = { + move = { + enable = true, + set_jumps = true, -- whether to set jumps in the jumplist + -- LazyVim extention to create buffer-local keymaps + keys = { + goto_next_start = { ["]f"] = "@function.outer", ["]c"] = "@class.outer", ["]a"] = "@parameter.inner" }, + goto_next_end = { ["]F"] = "@function.outer", ["]C"] = "@class.outer", ["]A"] = "@parameter.inner" }, + goto_previous_start = { ["[f"] = "@function.outer", ["[c"] = "@class.outer", ["[a"] = "@parameter.inner" }, + goto_previous_end = { ["[F"] = "@function.outer", ["[C"] = "@class.outer", ["[A"] = "@parameter.inner" }, + }, + }, + }, config = function(_, opts) local TS = require("nvim-treesitter-textobjects") if not TS.setup then @@ -167,6 +148,35 @@ return { return end TS.setup(opts) + + vim.api.nvim_create_autocmd("FileType", { + group = vim.api.nvim_create_augroup("lazyvim_treesitter_textobjects", { clear = true }), + callback = function(ev) + if not (vim.tbl_get(opts, "move", "enable") and LazyVim.treesitter.have(ev.match, "textobjects")) then + return + end + ---@type table> + local moves = vim.tbl_get(opts, "move", "keys") or {} + + for method, keymaps in pairs(moves) do + for key, query in pairs(keymaps) do + local desc = query:gsub("@", ""):gsub("%..*", "") + desc = desc:sub(1, 1):upper() .. desc:sub(2) + desc = (key:sub(1, 1) == "[" and "Prev " or "Next ") .. desc + desc = desc .. (key:sub(2, 2) == key:sub(2, 2):upper() and " End" or " Start") + if not (vim.wo.diff and key:find("[cC]")) then + vim.keymap.set({ "n", "x", "o" }, key, function() + require("nvim-treesitter-textobjects.move")[method](query, "textobjects") + end, { + buffer = ev.buf, + desc = desc, + silent = true, + }) + end + end + end + end, + }) end, },