Cuando llega el momento de "agregar soporte para el protocolo LSP" en neovim muchas personas usan estos plugins:
Lograr que estas piezas se integren requiere de un esfuerzo considerable. No es un problema, tampoco es que sea difícil... es sólo que requiere esfuerzo y no todos están dispuestos a hacerlo.
Pero ahora les digo que hay una manera fácil. Hice un plugin (lsp-zero) que puede ayudarles a integrar todas esas piezas.
Y esta es toda la configuración necesaria para empezar.
local lsp_zero = require('lsp-zero')
lsp_zero.on_attach(function(client, bufnr)
lsp_zero.default_keymaps({buffer = bufnr})
end)
require('mason').setup({})
require('mason-lspconfig').setup({
handlers = {
lsp_zero.default_setup,
},
})
Deben estar pensando "¿eso es todo?" Sí... y no. Técnicamente tienen que instalar algunas dependencias para que funcione.
Vamos a crear una configuración con todo lo necesario para que nuestro ejemplo funcione.
Empezando de cero
Requerimientos
- Conocimiento básico sobre Neovim: qué es el
modo normal
,modo de inserción
,modo de comandos
y cómo navegar entre ellos. - Neovim versión 0.8.0 o mayor.
- Si tienes un sistema de la familia
unix
: git, curl o wget, unzip, tar, gzip. - Para
windows
+ powershell: git, tar, and 7zip or peazip or archiver or winzip o WinRAR.
Necesitamos todo eso porque queremos gestionar todos nuestros servidores de lenguaje desde neovim.
El punto de entrada
Comenzamos nuestro viaje creando el archivo de configuración init.lua
. La ubicación de este archivo varía de acuerdo al sistema operativo. Entonces lo primero que haremos será obtener la ubicación de la carpeta de configuración de Neovim. Deben ejecutar este comando en su terminal.
nvim --headless -c 'echo stdpath("config")' -c 'echo ""' -c 'quit'
Ahora deben crear esa carpeta. Pueden el método que les resulte más cómodo, puede ser con la terminal o con un explorador de archivos.
Ya dentro de la carpeta de configuración creamos un archivo vacío llamado init.lua
.
En este punto podremos acceder al archivo de configuración desde Neovim usando este comando.
nvim -c 'edit $MYVIMRC'
Lo siguiente que haremos será probar si Neovim puede leer nuestra configuración. Vamos a cambiar el tema del editor, usaremos un tema claro. Abrán el archivo init.lua
y coloquen esto.
vim.cmd.colorscheme('morning')
Reinicien Neovim. Deberían notar el cambio en el tema. Si Neovim les arroja un error eso quiere decir que su versión de Neovim no cumple los requerimientos. Les sugiero que vayan el repositorio de Neovim en github, en la sección "releases" podrán encontrar los ejecutables para la versión más reciente.
¿Qué pueden hacer?
Si tienen Neovim v0.7 pueden instalar la rama
compat-07
de lsp-zero. Pueden seguir este tutorial.Si tienen Neovim v0.6 o v0.5 pueden instalar la version
v1
de lsp-zero. Puede seguir el tutorial de la version 1.
Suponiendo que todo salió bien, ya pueden cambiar el tema a algo más cómodo.
vim.cmd.colorscheme('habamax')
El manejador de plugins
Nota: técnicamente no necesitamos uno pero los manejadores de plugins nos faciltan la vida.
Vamos a usar lazy.nvim, simplemente porque es popular. Pueden hacer muchas cosas con lazy.nvim pero aquí sólo les mostraré un uso básico.
Algo muy bueno que tiene lazy.nvim es que desde su documentación nos enseñan cómo podemos instalarlo usando lua.
Vamos a agregar esto en nuestro init.lua
.
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
-- Instalar lazy.nvim si no está presente
if not vim.loop.fs_stat(lazypath) then
print('Instalando lazy.nvim....')
vim.fn.system({
'git',
'clone',
'--filter=blob:none',
'https://github.com/folke/lazy.nvim.git',
'--branch=stable',
lazypath,
})
print('Listo.')
end
vim.opt.rtp:prepend(lazypath)
Prestén atención a la variable lazypath
, esta almacena el resultado de la función stdpath('data')
la cual nos da la ubicación de la carpeta de datos de Neovim. De esta manera no necesitamos cambiar la ruta dependiendo del sistema operativo, Neovim lo hará por nosotros. Si quieren saber la ubicación de esa carpeta ejecute este comando en Neovim.
:echo stdpath('data') . '/lazy/lazy.nvim'
Para usar lazy.nvim tenemos que invocar la función .setup()
del módulo lazy
.
require('lazy').setup({
---
-- Lista de plugins...
---
})
Agregando un plugin
Esta es la parte donde aprendemos a usar lazy.nvim. Vamos a probar con un plugin simple, un tema para Neovim llamado tokyonight.nvim.
¿Listos? Estos son los pasos para descargar un tema.
- Añadimos el plugin a nuestra lista de plugins.
require('lazy').setup({
{'folke/tokyonight.nvim'},
})
Con lazy.nvim lo único que necesitamos para descargar un plugin desde github es el nombre de usuario y el nombre del repositorio.
Debemos borrar la línea que configura el tema.
Configuramos el tema nuevo al final de
init.lua
.
vim.opt.termguicolors = true
vim.cmd.colorscheme('tokyonight')
Guardamos los cambios.
Reiniciamos Neovim.
Después de abrir Neovim debería mostrarnos un mensaje indicando que está descargando lazy.nvim. Después deberá aparecer una ventana flotante, esta nos va a mostrar el progreso de la descarga del resto de los plugins. Finalmente los plugins que instalamos serán cargados.
Configurando lsp-zero
Ahora podemos agregar lsp-zero y todas sus dependencias a la lista de plugins.
require('lazy').setup({
{'folke/tokyonight.nvim'},
{'VonHeikemen/lsp-zero.nvim', branch = 'v3.x'},
{'williamboman/mason.nvim'},
{'williamboman/mason-lspconfig.nvim'},
{'neovim/nvim-lspconfig'},
{'hrsh7th/nvim-cmp'},
{'hrsh7th/cmp-nvim-lsp'},
{'L3MON4D3/LuaSnip'},
})
Luego de eso podemos agregar el código de configuración al final de nuestra configuración.
local lsp_zero = require('lsp-zero')
lsp_zero.on_attach(function(client, bufnr)
lsp_zero.default_keymaps({buffer = bufnr})
end)
require('mason').setup({})
require('mason-lspconfig').setup({
handlers = {
lsp_zero.default_setup,
},
})
Guarden los cambios, reinicien Neovim y esperen a que termine la descarga de los plugins.
Instalando un servidor LSP
Vamos a probar con el servidor LSP para lua.
Van a abrir el archivo init.lua
con Neovim y van a ejecutar este comando :LspInstall
. El plugin mason-lspconfig.nvim
va a sugerir una lista de servidores. Neovim deberá mostrar este mensaje.
Please select which server you want to install for filetype "lua":
1: lua_ls
Type number and <Enter> or click with the mouse (q or empty cancels):
Por el momento sólo tenemos una opción, lua_ls
. Deben oprimir 1
y confirman la selección presionando Enter
. Deberá aparecer una ventana flotante. Cuando se termina la descarga del servidor aparecerá un mensaje.
Actualmente los servidors LSP no pueden iniciar automáticamente después de su instalación. Deben reiniciar Neovim. Una vez que el servidor empiece a analizar su código deberán notar las advertencias en la variable global vim
, eso significa que todo está bien.
Para asegurarnos que lua_ls
pueda detectar la raíz de nuestro proyecto debemos crear un archivo llamado .luarc.json
. Este archivo puede estar vacío, sólo debe existir en la carpeta de configuración de Neovim.
Si quieren, pueden configurar lua_ls
específicamente para Neovim, usando la función .nvim_lua_ls()
.
require('mason-lspconfig').setup({
handlers = {
lsp_zero.default_setup,
lua_ls = function()
local lua_opts = lsp_zero.nvim_lua_ls()
require('lspconfig').lua_ls.setup(lua_opts)
end,
},
})
Ya están listos. Pueden reiniciar Neovim y abrir init.lua
, el soporte para la configuración deberá mejorar ligeramente.
Ejemplo completo
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
-- Instalar lazy.nvim si no está presente
if not vim.loop.fs_stat(lazypath) then
print('Instalando lazy.nvim....')
vim.fn.system({
'git',
'clone',
'--filter=blob:none',
'https://github.com/folke/lazy.nvim.git',
'--branch=stable',
lazypath,
})
print('Listo.')
end
vim.opt.rtp:prepend(lazypath)
require('lazy').setup({
{'folke/tokyonight.nvim'},
{'VonHeikemen/lsp-zero.nvim', branch = 'v3.x'},
{'williamboman/mason.nvim'},
{'williamboman/mason-lspconfig.nvim'},
{'neovim/nvim-lspconfig'},
{'hrsh7th/nvim-cmp'},
{'hrsh7th/cmp-nvim-lsp'},
{'L3MON4D3/LuaSnip'},
})
-- Set colorscheme
vim.opt.termguicolors = true
vim.cmd.colorscheme('tokyonight')
-- LSP
local lsp_zero = require('lsp-zero')
lsp_zero.on_attach(function(client, bufnr)
lsp_zero.default_keymaps({buffer = bufnr})
end)
require('mason').setup({})
require('mason-lspconfig').setup({
handlers = {
lsp_zero.default_setup,
lua_ls = function()
local lua_opts = lsp_zero.nvim_lua_ls()
require('lspconfig').lua_ls.setup(lua_opts)
end,
},
})
¿Qué Sigue?
Visiten el repositorio de lsp-zero en github. Lean la documentación ahí o con el comando :help lsp-zero
.
Lean sobre los atajos de teclado que crea lsp-zero:
También pasen por la documentación de mason.nvim.
Pueden preguntarme cualquier cosa sobre lsp-zero
aquí, en la sección de discusión en github, o en matrix #lsp-zero-nvim:matrix.org.
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 buymeacoffee ☕.
Top comments (10)
Aquí les dejo la misma configuración pero creada en vimscript, usando vim-plug para descargar plugins.
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 modulocmp
para 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 propiedadname
no 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...
![Image description](https://res.cloudinary.com/practicaldev/image/fetch/s--4L10yd62--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aprr60zvoboaw16wid47.png)
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
user
y 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
.