Cuando llega el momento de "agregar soporte para LSP" en neovim muchas personas usan tres componentes: el cliente LSP nativo, nvim-cmp (un plugin de autocompletado) y mason.nvim. 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 incluye todo el código de configuración necesario para integrar nvim-cmp
, mason.nvim
y el cliente LSP. Y la mejor parte, ustedes como usuarios sólo deben agregar estas líneas de código en su configuración personal:
local lsp = require('lsp-zero').preset({
name = 'minimal',
set_lsp_keymaps = true,
manage_nvim_cmp = true,
suggest_lsp_servers = false,
})
lsp.setup()
Aquí un vistazo de lo que van a obtener.
Ver video completo.
Mostrado en video:
- Plugin de autocompletado (
nvim-cmp
) completamente configurado. - Sugerencias de autocompletado proporcionadas por el servidor de lenguaje
lua_ls
, así como también de otras fuentes. - Expansión de snippets y movilización del cursor entre placeholders.
- Íconos de diagnóstico mostrados al costado.
- Mensajes de diagnóstico mostrados en una ventana flotante.
- "Code actions."
Deben estar pensando "¿Todo eso con 7 líneas de código?" Sí... y no. Técnicamente tienen que instalar algunas dependencias para que funcione. Se requieren más de 7 líneas.
Si utilizan packer.nvim deberán incluir esto en su lista de plugins.
use {
'VonHeikemen/lsp-zero.nvim',
branch = 'v1.x',
requires = {
-- Soporte LSP
{'neovim/nvim-lspconfig'},
{
'williamboman/mason.nvim',
run = function() pcall(vim.cmd, 'MasonUpdate') end
},
{'williamboman/mason-lspconfig.nvim'},
-- Autocompletado
{'hrsh7th/nvim-cmp'},
{'hrsh7th/cmp-buffer'},
{'hrsh7th/cmp-path'},
{'saadparwaiz1/cmp_luasnip'},
{'hrsh7th/cmp-nvim-lsp'},
{'hrsh7th/cmp-nvim-lua'},
-- Snippets
{'L3MON4D3/LuaSnip'},
{'rafamadriz/friendly-snippets'},
}
}
Si desean podemos probarlo recreando la configuración que usé en el demo.
Empezando de cero
Requerimientos
Primero lo primero, vamos revisar qué necesitamos.
- Neovim versión 0.7.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.
De aquí en adelante voy a asumir que el sistema que usan es linux. También asumiré que saben cómo ejecutar comandos dentro de neovim.
Comenzamos con un poco de lua
Vamos ver dónde debería estar el archivo de configuración de neovim. Abren neovim y ejecutan el comando :echo stdpath('config)
, les mostrará la carpeta donde debería estar nuestro archivo init.lua
. En mi caso muestra /home/dev/.config/nvim
. Vamos a crear la configuración desde neovim, ejecutamos:
:edit ~/.config/nvim/init.lua
Empecemos con una simple prueba. Si presionan <Tab>
en modo de inserción se darán cuenta que el cursor avanza 8 espacios, vamos a cambiar eso. En nuestra configuración agregaremos esto.
-- Expande tab a dos espacios
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.softtabstop = 2
vim.opt.expandtab = true
Guardamos el archivo y salimos de neovim con el comando :wq
.
Entramos nuevamente a neovim, vamos a modo de inserción y presionamos <Tab>
. El cursor debería avanzar sólo 2 espacios. De no ser así probablemente se equivocaron colocando la ruta del archivo.
Plugin manager
Para descargar los plugins necesarios vamos a usar packer
, pero sólo porque todo los demás hacen lo mismo.
Vamos al repositorio de packer.nvim en github, nos pasamos por la sección quickstart, copiamos el git clone
que corresponde a nuestro sistema operativo. Yo les mostraré el de linux:
git clone --depth 1 https://github.com/wbthomason/packer.nvim\
~/.local/share/nvim/site/pack/packer/start/packer.nvim
Ahora regresamos al init.lua
. Al final del archivo vamos a añadir:
require('packer').startup(function(use)
-- Packer puede actualizarse solo
use 'wbthomason/packer.nvim'
-- Tema
use 'joshdick/onedark.vim'
end)
Aquí ocurren un par de cosas. Primero inicializamos packer
y le decimos que queremos gestionar dos plugins. El patrón que deberían tener en cuenta cuando agregan un plugin es este:
use 'usuario-github/repositorio'
Eso es todo lo que necesita packer
para descargar un plugin desde github.
En este punto no necesitamos hacer la rutina de guardar y salir. Guardamos el archivo con el comando :write
, luego lo evaluamos con :source %
. Ya podremos instalar los nuevos plugins. Ejecutamos :PackerSync
. Aparecerá una ventana lateral anunciando el progreso de la descarga. Una vez que culmine la descarga podremos cerrar la ventana presionando q
.
Para asegurarnos que todo salió bien vamos a usar el nuevo tema que descargamos. Al final del archivo agregaremos.
vim.opt.signcolumn = 'yes'
vim.opt.termguicolors = true
pcall(vim.cmd, 'colorscheme onedark')
Guardan, evalúan. Notarán que los colores de la interfaz cambian.
Soporte para LSP
Finalmente, ya tenemos una buena base para agregar las funcionalidades basadas en LSP. Bien, vamos a añadir lsp-zero y todas sus dependencias justo debajo de la sentencia use
que tiene el tema.
Su lista de plugins debería verse así.
require('packer').startup(function(use)
-- Packer puede actualizarse solo
use 'wbthomason/packer.nvim'
-- Tema
use 'joshdick/onedark.vim'
-- LSP
use {
'VonHeikemen/lsp-zero.nvim',
branch = 'v1.x',
requires = {
-- Soporte LSP
{'neovim/nvim-lspconfig'},
{
'williamboman/mason.nvim',
run = function() pcall(vim.cmd, 'MasonUpdate') end
},
{'williamboman/mason-lspconfig.nvim'},
-- Autocompletado
{'hrsh7th/nvim-cmp'},
{'hrsh7th/cmp-buffer'},
{'hrsh7th/cmp-path'},
{'saadparwaiz1/cmp_luasnip'},
{'hrsh7th/cmp-nvim-lsp'},
{'hrsh7th/cmp-nvim-lua'},
-- Snippets
{'L3MON4D3/LuaSnip'},
{'rafamadriz/friendly-snippets'},
}
}
end)
Guardamos el archivo, lo evaluamos. Instalamos con :PackerSync
.
Ahora añadimos la configuración de lsp-zero
.
local lsp = require('lsp-zero')
lsp.preset('recommended')
lsp.setup()
Guardamos el archivo y salimos de neovim.
Abrimos neovim nuevamente. Vamos a editar init.lua
. Usen :edit ~/.config/nvim/init.lua
. Ahora ejecuten el comando :LspInstall
, con esto mason.nvim
nos mostrará una lista de servidores que podremos instalar para lua. Deberá aparecer algo como esto.
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):
Presionamos 1 para elegir lua_ls
, luego presionamos enter. Aparecerá una ventana flotante que nos mostrará el progreso de la instalación.
Es muy probable que el servidor LSP no pueda iniciar automáticamente después de la instalación. Deberán usar el comando :edit
para refrescar el archivo o reinciar neovim si lo anterior no funciona. Una vez que neovim inicialice el servidor aparecerán indicadores de advertencia donde está la variable global vim
.
Si desean pueden añadir una configuración de lua_ls
hecha a la medida para neovim, agregando una sola línea de código.
lsp.nvim_workspace()
Agregan esa línea antes del llamado a .setup()
.
local lsp = require('lsp-zero').preset({
name = 'minimal',
set_lsp_keymaps = true,
manage_nvim_cmp = true,
suggest_lsp_servers = false,
})
lsp.nvim_workspace()
lsp.setup()
Eso es todo. Ya están listos. Reinicien neovim nuevamente, deberían tener soporte total para la api de lua dentro de neovim.
Ejemplo completo
---
-- Opciones del editor
---
-- Expande tab a dos espacios
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.softtabstop = 2
vim.opt.expandtab = true
-- Dame espacio
vim.opt.signcolumn = 'yes'
---
-- Plugins
---
require('packer').startup(function(use)
-- Packer puede actualizarse solo
use 'wbthomason/packer.nvim'
-- Tema
use 'joshdick/onedark.vim'
-- LSP
use {
'VonHeikemen/lsp-zero.nvim',
branch = 'v1.x',
requires = {
-- Soporte LSP
{'neovim/nvim-lspconfig'},
{
'williamboman/mason.nvim',
run = function() pcall(vim.cmd, 'MasonUpdate') end
},
{'williamboman/mason-lspconfig.nvim'},
-- Autocompletado
{'hrsh7th/nvim-cmp'},
{'hrsh7th/cmp-buffer'},
{'hrsh7th/cmp-path'},
{'saadparwaiz1/cmp_luasnip'},
{'hrsh7th/cmp-nvim-lsp'},
{'hrsh7th/cmp-nvim-lua'},
-- Snippets
{'L3MON4D3/LuaSnip'},
{'rafamadriz/friendly-snippets'},
}
}
end)
-- Declaramos el tema
vim.opt.termguicolors = true
pcall(vim.cmd, 'colorscheme onedark')
-- Configuración LSP
local lsp = require('lsp-zero').preset({
name = 'minimal',
set_lsp_keymaps = true,
manage_nvim_cmp = true,
suggest_lsp_servers = false,
})
lsp.nvim_workspace()
lsp.setup()
¿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:
Revisen este ejemplo de configuración más avanzado, aquí se muestran las funciones que tienen disponibles para configurar e instalar servidores LSP.
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 (7)
Aquí les muestro la misma configuración pero creada en vimscript, usando vim-plug para descargar plugins.
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
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
.