From a111292e734486766808d7027d044ff0410b2a20 Mon Sep 17 00:00:00 2001 From: Troy Connor Date: Fri, 19 Jun 2026 10:37:46 -0400 Subject: [PATCH] lsp: migrate to native vim.lsp.config API for nvim 0.11/0.12 Drops lsp-zero in favor of: - vim.lsp.config('*', { capabilities = ... }) for cmp_nvim_lsp capabilities - mason-lspconfig v2 automatic_enable (replaces handlers block) - client:supports_method (colon form; dot form deprecated in 0.11+) Preserves nvim-cmp behavior exactly: - Same sources and group_index - Tab/S-Tab reimplement lsp-zero's tab_complete and select_prev_or_fallback so menu open/complete/fallback semantics are unchanged. Revert with: git revert HEAD --- lua/troy0820/lazy/lsp.lua | 101 ++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 52 deletions(-) diff --git a/lua/troy0820/lazy/lsp.lua b/lua/troy0820/lazy/lsp.lua index 1f938e1..8879273 100644 --- a/lua/troy0820/lazy/lsp.lua +++ b/lua/troy0820/lazy/lsp.lua @@ -1,79 +1,76 @@ return { - 'VonHeikemen/lsp-zero.nvim', - branch = 'v3.x', + 'neovim/nvim-lspconfig', dependencies = { - --- Uncomment the two plugins below if you want to manage the language servers from neovim - { 'williamboman/mason.nvim' }, - { 'williamboman/mason-lspconfig.nvim' }, - - - { 'neovim/nvim-lspconfig' }, + { 'mason-org/mason.nvim' }, + { 'mason-org/mason-lspconfig.nvim' }, { 'hrsh7th/nvim-cmp' }, { 'hrsh7th/cmp-nvim-lsp' }, { 'hrsh7th/cmp-nvim-lsp-signature-help' }, }, config = function() - local lsp_zero = require('lsp-zero') - - lsp_zero.on_attach(function(client, bufnr) - lsp_zero.default_keymaps({ buffer = bufnr }) - end) - local buffer_autoformat = function(bufnr) - local group = 'lsp_autoformat' - vim.api.nvim_create_augroup(group, { clear = false }) - vim.api.nvim_clear_autocmds({ group = group, buffer = bufnr }) + local cmp_caps = require('cmp_nvim_lsp').default_capabilities() + vim.lsp.config('*', { capabilities = cmp_caps }) - vim.api.nvim_create_autocmd('BufWritePre', { - buffer = bufnr, - group = group, - desc = 'LSP format on save', - callback = function() - -- note: do not enable async formatting - vim.lsp.buf.format({ async = false, timeout_ms = 10000 }) - end, - }) - end + require('mason').setup({}) + require('mason-lspconfig').setup({ + automatic_enable = true, + }) vim.api.nvim_create_autocmd('LspAttach', { callback = function(event) - local id = vim.tbl_get(event, 'data', 'client_id') - local client = id and vim.lsp.get_client_by_id(id) - + local client = vim.lsp.get_client_by_id(event.data.client_id) if client == nil then return end - -- make sure there is at least one client with formatting capabilities - if client.supports_method('textDocument/formatting') then - buffer_autoformat(event.buf) + if client:supports_method('textDocument/formatting') then + local group = vim.api.nvim_create_augroup('lsp_autoformat', { clear = false }) + vim.api.nvim_clear_autocmds({ group = group, buffer = event.buf }) + vim.api.nvim_create_autocmd('BufWritePre', { + buffer = event.buf, + group = group, + desc = 'LSP format on save', + callback = function() + vim.lsp.buf.format({ async = false, timeout_ms = 10000 }) + end, + }) end - end - }) - - - require('mason').setup({}) - require('mason-lspconfig').setup({ - handlers = { - function(server_name) - require('lspconfig')[server_name].setup({}) --lsp_zero.default_setup, - end - }, + end, }) local cmp = require('cmp') - local cmp_action = require('lsp-zero').cmp_action() + + local has_words_before = function() + local line, col = unpack(vim.api.nvim_win_get_cursor(0)) + return col ~= 0 + and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1] + :sub(col, col):match('%s') == nil + end cmp.setup({ sources = cmp.config.sources({ - { name = 'copilot', group_index = 2}, - { name = 'nvim_lsp', group_index = 2}, - { name = 'nvim_lsp_signature_help' } - + { name = 'copilot', group_index = 2 }, + { name = 'nvim_lsp', group_index = 2 }, + { name = 'nvim_lsp_signature_help' }, }), mapping = cmp.mapping.preset.insert({ - [''] = cmp_action.tab_complete(), - [''] = cmp_action.select_prev_or_fallback(), + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif has_words_before() then + cmp.complete() + else + fallback() + end + end, { 'i', 's' }), + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + else + fallback() + end + end, { 'i', 's' }), }), }) - end + end, } -- 2.51.2