Mucho ha cambiado desde que escribí esta guía en el año 2022. En aquel entonces Neovim v0.6 era la versión estable más reciente e implementar "funcionalidades básicas" no era fácil. Ahora quiero mostrarles una configuración que pueden usar en Neovim v0.9 o mayor.
Importante: si no saben cómo configurar Neovim usando lua les recomiendo leer esto: Cómo crear tu primera configuración de Neovim usando lua.
Voy a enseñarles cómo usar el cliente LSP de Neovim. Esto es lo que haremos:
- Instalar un servidor LSP
- Configurar el servidor LSP
- Crear atajos de teclado
- Configurar autocompletado de código
En esta ocasión voy a mostrar dos ejemplos prácticos, vamos a configurar servidores LSP para golang y rust. ¿Por qué esos lenguajes? Porque ambos funcionan relativamente bien en Windows, Mac y Linux. Y necesito al menos 2 ejemplos para que sea evidente que algunos pasos varían dependendiendo del lenguaje de programación que quieren usar.
Necesitamos un servidor LSP
Un servidor LSP es un programa externo. Por lo general están diseñados para analizar el código fuente de un proyecto y proveer información a un editor de texto. Si quieren conocer más detalles pueden ver este video: LSP explained (5 min).
Ahora bien ¿Dónde podemos encontrar servidores LSP para Neovim?
La comunidad de Neovim ha creado el plugin nvim-lspconfig, en la documentación de este plugin podrán encontrar una lista de servidores compatibles con Neovim: nvim-lspconfig/doc/configs.md.
Vamos con nuestro primer ejemplo:
Si ya tienen instalado las herramientas de desarrollo para golang, podrán instalar el servidor LSP (gopls) ejecutando este comando en la terminal.
go install golang.org/x/tools/gopls@latest
En el caso de rust, si tienen rustup instalado pueden usar este comando para descargar rust_analyzer.
rustup component add rust-analyzer
¿Hay alguna forma de automatizar este paso?
Sí. Existe un plugin llamado mason.nvim. Este nos ofrece una interfaz que nos permite descargar herramientas desde Neovim.
No les enseñaré cómo usar mason.nvim aquí, porque este plugin es opcional. No quiero que nadie piense que mason.nvim es obligatorio para este proceso. Funciona genial pero antes de usarlo ustedes deben leer bien las instrucciones, y deben entender si les conviene instalarlo o no.
Configurando un servidor LSP
nvim-lspconfig es el plugin que usaremos para configurar servidores LSP.
Justo ahora (Febrero 2026) estamos en un periodo de transición. Neovim v0.11 es la versión estable actual, y aquí se ha implementado un método nuevo para configurar servidores LSP. Pero en muchos sistemas basados en Linux la versión de Neovim puede variar. En algunos casos Neovim v0.9 o v0.10 es la versión que tienen disponibles de manera oficial.
Aquí les mostraré el método antiguo para versiones anteriores a v0.11 y el método nuevo.
En Neovim v0.11 en adelante, para configurar un servidor LSP deben ejecutar la función vim.lsp.enable().
vim.lsp.enable({'example_server'})
En Neovim v0.10 o versiones anteriores debemos usar el "framework" que se encuentra en el módulo lspconfig.
require('lspconfig').example_server.setup({})
Importante: Las versiones más reciente de nvim-lspconfig sólo ofrecen soporte para Neovim v0.10 en adelante. Si necesitan soporte para Neovim v0.9 pueden usar el tag v1.8.0 de nvim-lspconfig.
Entonces, si tenemos disponible Neovim v0.11 podremos habilitar los servidores LSP de esta manera:
vim.lsp.enable({'gopls', 'rust_analyzer'})
Para versiones anteriores tendríamos que hacer esto:
require('lspconfig').gopls.setup({})
require('lspconfig').rust_analyzer.setup({})
Ya esto es suficiente para poder usar algunas funcionalidades de los servidores LSP. gopls and rust_analyzer podrán indicar si tenemos errores en nuestro código.
Si quieren que su configuración sea compatible en diferentes versiones de Neovim pueden crear una función que invoque el método correcto de acuerdo a la versión de Neovim que están usando.
-- Esta función usará el método adecuado para configurar un servidor LSP.
-- Ya que vim.lsp.enable() sólo está disponible en versiones más recientes.
local function lsp_setup(server, opts)
if vim.fn.has('nvim-0.11') == 0 then
require('lspconfig')[server].setup(opts)
return
end
if not vim.tbl_isempty(opts) then
vim.lsp.config(server, opts)
end
vim.lsp.enable(server)
end
Y luego para habilitar un servidor LSP lo usamos de esta manera:
lsp_setup('gopls', {})
lsp_setup('rust_analyzer', {})
Recuerden revisar la documentación de nvim-lspconfig para saber qué servidores LSP pueden usar.
Atajos de teclado
Neovim v0.11 viene con atajos de teclado predefinidos, pero si tenemos una versión anterior debemos crear esos atajos nosotros mismos. Aquí les muestro el código que pueden usar en caso de no tener acceso a Neovim v0.11.
-- Estos atajos ya están definidos en Neovim v0.10
vim.keymap.set('n', '[d', '<cmd>lua vim.diagnostic.goto_prev()<cr>')
vim.keymap.set('n', ']d', '<cmd>lua vim.diagnostic.goto_next()<cr>')
vim.keymap.set('n', '<C-w>d', '<cmd>lua vim.diagnostic.open_float()<cr>')
vim.keymap.set('n', '<C-w><C-d>', '<cmd>lua vim.diagnostic.open_float()<cr>')
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(event)
local bufmap = function(mode, rhs, lhs)
vim.keymap.set(mode, rhs, lhs, {buffer = event.buf})
end
-- Estos atajos ya están definidos en Neovim v0.11
bufmap('n', 'K', '<cmd>lua vim.lsp.buf.hover()<cr>')
bufmap('n', 'grr', '<cmd>lua vim.lsp.buf.references()<cr>')
bufmap('n', 'gri', '<cmd>lua vim.lsp.buf.implementation()<cr>')
bufmap('n', 'grt', '<cmd>lua vim.lsp.buf.type_definition()<cr>')
bufmap('n', 'grn', '<cmd>lua vim.lsp.buf.rename()<cr>')
bufmap('n', 'gra', '<cmd>lua vim.lsp.buf.code_action()<cr>')
bufmap('n', 'gO', '<cmd>lua vim.lsp.buf.document_symbol()<cr>')
bufmap({'i', 's'}, '<C-s>', '<cmd>lua vim.lsp.buf.signature_help()<cr>')
end,
})
Esta es la descripción de todos los atajos que están relacionados con el cliente LSP.
-
<Ctrl-]>: Saltar a definición del símbolo que está debajo del cursor. -
gq: Formatea el código seleccionado. Este atajo utilizará el servidor LSP si es posible. -
[d: Saltar al diagnóstico anterior del archivo actual. -
]d: Saltar al siguiente diagnóstico del archivo actual. -
<Ctrl-w>d: Mostrar diagnósticos de la línea actual. -
K: Muestra información sobre símbolo debajo del cursor. -
grr: Listar referencias del símbolo debajo del cursor. -
gri: Mostrar implementaciones del símbolo debajo del cursor. -
grt: Saltar a definición de tipo del símbolo debajo del cursor. -
grn: Renombrar todas las referencias del símbolo debajo del cursor. -
gra: Listar "code actions" disponibles en la posición del cursor. -
g0: Listar todos los símbolos en el archivo actual -
<Ctrl-s>: En modo de inserción, mostrar argumentos de la función debajo del cursor.
Autocompletado de código
Vale la pena mencionar que Neovim provee un mecanismo de completado de código, lo pueden encontrar en la documentación como ins-completion. Desafortunadamente no es como en otros editores. No se activa de manera automática. Y en versiones antiguas no ofrece soporte para expandir "snippets" de código.
Para obtener un autocompletado verdadero con soporte para snippets podemos usar mini.nvim. mini.nvim es una colección de módulos escritos en lua, está diseñado para complementar las funcionalidades nativas de Neovim. Para habilitar autocompletado con snippets podemos usar estos dos módulos.
require('mini.snippets').setup({})
require('mini.completion').setup({})
Cabe destacar que mini.nvim es compatible con Neovim v0.9 así que podrán usarlo incluso en versiones antiguas.
mini.completion utiliza el mecanismo nativo de Neovim, esto quiere decir que para controlarlo los mismos atajos que Neovim define por defecto.
<Down>: Selecciona el siguiente item en la lista.<Up>: Selecciona el item anterior en la lista.<Ctrl-n>: Selecciona e inserta el contenido del siguiente item en la lista.<ctrl-p>: Selecciona e inserta el contenido del item anterior.<Ctrl-y>: Confirma el item seleccionado.<Ctrl-e>: Cancela el proceso de completado y esconde el menú.<Enter>: Si el item fue seleccionado con<Up>o<Down>confirma la selección. Si no hay ningún item seleccionado, esconde el menú. Si no, inserta un salto de línea.
Ejemplo completo
Eso es todo. Ya tenemos todo lo necesario para empezar a usar el cliente LSP de Neovim.
Si tienen acceso a Neovim v0.11 o una versión mayor, esto es todo lo que necesitan:
-- NOTA: Esta configuración es para Neovim v0.11 o una versión mayor
require('mini.snippets').setup({})
require('mini.completion').setup({})
vim.lsp.enable({'gopls', 'rust_analyzer'})
Si quieren una configuración compatible en versiones anteriores:
-- NOTE: Esta configuración es compatible con Neovim v0.9 o una versión mayor
---
-- Autocompletado de código
---
require('mini.snippets').setup({})
require('mini.completion').setup({})
---
-- LSP
---
-- Estos atajos ya están definidos en Neovim v0.10
if vim.fn.has('nvim-0.11') == 0 then
-- NOTA: vim.diagnostic.goto_* fue renombrado en v0.11
-- es por eso que este bloque está bajo una condición
vim.keymap.set('n', '[d', '<cmd>lua vim.diagnostic.goto_prev()<cr>')
vim.keymap.set('n', ']d', '<cmd>lua vim.diagnostic.goto_next()<cr>')
vim.keymap.set('n', '<C-w>d', '<cmd>lua vim.diagnostic.open_float()<cr>')
vim.keymap.set('n', '<C-w><C-d>', '<cmd>lua vim.diagnostic.open_float()<cr>')
end
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(event)
local bufmap = function(mode, rhs, lhs)
vim.keymap.set(mode, rhs, lhs, {buffer = event.buf})
end
-- Estos atajos ya están definidos en Neovim v0.11
bufmap('n', 'K', '<cmd>lua vim.lsp.buf.hover()<cr>')
bufmap('n', 'grr', '<cmd>lua vim.lsp.buf.references()<cr>')
bufmap('n', 'gri', '<cmd>lua vim.lsp.buf.implementation()<cr>')
bufmap('n', 'grn', '<cmd>lua vim.lsp.buf.rename()<cr>')
bufmap('n', 'gra', '<cmd>lua vim.lsp.buf.code_action()<cr>')
bufmap('n', 'gO', '<cmd>lua vim.lsp.buf.document_symbol()<cr>')
bufmap({'i', 's'}, '<C-s>', '<cmd>lua vim.lsp.buf.signature_help()<cr>')
end,
})
-- Esta función usará el método adecuado para configurar un servidor LSP.
-- Ya que vim.lsp.enable() sólo está disponible en versiones más recientes.
local function lsp_setup(server, opts)
if vim.fn.has('nvim-0.11') == 0 then
require('lspconfig')[server].setup(opts)
return
end
if not vim.tbl_isempty(opts) then
vim.lsp.config(server, opts)
end
vim.lsp.enable(server)
end
lsp_setup('gopls', {})
lsp_setup('rust_analyzer', {})
Gracias por su tiempo. Si este artículo les pareció útil y quieren apoyar mis esfuerzos para crear más contenido pueden dejar una propina en ko-fi.com/vonheikemen.

Top comments (10)
Hola, muy bueno tu post, pero tengo dos problemas, ojalá me puedas guiar.
Tengo instalado neovim en windows y esta es mi configuración de init.lua
Un problema que tengo es que cuando paso al modo insertar me sale el mensaje de error de la imgen de abajo. Luego puedo insertar pero no puedo quitar ese error.
El otro problema es que no tengo opciones de autocompletado con palabras del mismo buffer y no se como configurar esa opción. Entiendo que hay que poner
sources = {
{ name = 'buffer' }
}
})
O algo así pero no entiendo en que archivo debería hacerlo. Soy muy nuevo en esto y estoy bastante perdido. Sepan comprender y acepto consejos.
Saludos
Intenta colocar tus nuevos plugins fuera de las dependencias de lsp-zero. Probablemente hay un problema en el orden en que se cargan los módulos.
Con el otro problema. Puedes configurar el autocompletado en tu archivo
init.lua. Debes tener en cuenta que cada "source" que agregas a nvim-cmp es un plugin nuevo que debes instalar. Entonces, debes instalar este plugin: cmp-buffer. Luego, usa el modulocmppara configurar la opciónsources. Así.Debes usar
cmp.setup()después de configurar lsp-zero, así te aseguras de que tu configuración sobreescriba la de lsp-zero.Aqui
{name = 'nvim_lsp'}pertenece a este plugin cmp-nvim-lsp, ese ya lo tienes instalado, esta en las dependencias de lsp-zero, pero debes colocarlo para no perder el autocompletado del cliente LSP. Ahora,{name = 'buffer'}es cmp-buffer. Esto es importante: la propiedadnameno es el nombre del plugin. Cuando vas a instalar un "source" para nvim-cmp no intentes adivinar, revisa la documentación para saber qué valor debería tenername.¡Muchisimas gracias hermano! Gracias por contestar y gracias por la paciencia.
tengo una pregnta...

lo que pasa es que me sale este error al tratar de instalar el server de phppactor
adjunto pantallazo del error
solo me deja instalar el de instelepehense pero cuando trato de escribir algo en un archivo php no sale ninguna sujerencia
Para instalar phpactor necesitas composer.
Si quieres saber si un servidor LSP está activo en un archivo ejecuta el comando
:LspInfo.Hola disculpa por las molestias soy nuevo con lo de las configuraciones y conozco muy poco sobre nvim y lua, segui los pasos que tienes en el post pero tengo el siguiente error y no se muy bien a que se debe
espero me puedas ayudar
Este archivo está creando un conflicto.
Impide que neovim cargue el script que está dentro del plugin. Porque estás creando otro módulo con el nombre
lsp-zero.Debes crear otro módulo con un nombre único para evitar conflictos con cualquier plugin. Puedes crear uno llamado
usery colocar tu script ahí.Luego en tu configuración lo llamas de esta manera.
*Espectacular trabajo! en unos minutos has resuelto mi busqueda de semanas. Gracias!
1.- Se puede hacer lo mismo con vim, quiza con otro conjunto de plugins?
2.- Cuando aparecen errores en el código pre-existente como sacas el menú de correcciones o el detalle del error en neovim?
Creo que sí. Se puede usar vim-lsp para integrar un cliente lsp. Luego tienes vim-lsp-settings, es como un complemento de
vim-lsp, es una colección de configuraciones para servidores LSP. También parece tener un método para instalar servidores. La integración con el autocompletado puede hacerse con asyncomplete,vim (plugin del mismo autor devim-lsp) o ddc.vim que también es muy bueno.El mensaje de error en la ventana flotante se activa con el atajo
g+l. Las correcciones (en neovim le dicen "code actions") se activan conF4.