Configurando el cliente LSP de neovim: la manera fácil
Tags: vim, neovim, shell, spanish
Published: 2022-02-26 21:59:23

---
title: Configurando el cliente LSP de neovim: la manera fácil
published: true
description: Vamos a agregar funcionalidades basadas en el protocolo LSP
tags: #vim #neovim #shell #spanish
//cover_image: https://direct_url_to_image.jpg
---

Cuando llega el momento de "agregar soporte para el protocolo LSP" en neovim muchas personas usan estos plugins: 

* [nvim-cmp](https://github.com/hrsh7th/nvim-cmp)
* [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig) 
* [mason.nvim](https://github.com/williamboman/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](https://github.com/VonHeikemen/lsp-zero.nvim)) que puede ayudarles a integrar todas esas piezas.

Y esta es toda la configuración necesaria para empezar.

```lua
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.

```sh
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.

```sh
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.

```lua
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"](https://github.com/neovim/neovim/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](https://github.com/VonHeikemen/lsp-zero.nvim/blob/compat-07/doc/md/tutorial.md).

* Si tienen Neovim v0.6 o v0.5 pueden instalar la version `v1` de lsp-zero. Puede seguir el [tutorial de la version 1](https://github.com/VonHeikemen/lsp-zero.nvim/blob/v1.x/doc/md/tutorial.md).

Suponiendo que todo salió bien, ya pueden cambiar el tema a algo más cómodo.

```lua
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](https://github.com/folke/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`.

```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.

```vim
:echo stdpath('data') . '/lazy/lazy.nvim'
```

Para usar lazy.nvim tenemos que invocar la función `.setup()` del módulo `lazy`.

```lua
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](https://github.com/folke/tokyonight.nvim).

¿Listos? Estos son los pasos para descargar un tema.

1. Añadimos el plugin a nuestra lista de plugins.

```lua
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.

2. Debemos borrar la línea que configura el tema.

3. Configuramos el tema nuevo al final de `init.lua`.

```lua
vim.opt.termguicolors = true
vim.cmd.colorscheme('tokyonight')
```

4. Guardamos los cambios.

5. 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.

```lua
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.

```lua
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()`.

```lua
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

```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)

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](https://github.com/VonHeikemen/lsp-zero.nvim) en github. Lean la documentación ahí o con el comando `:help lsp-zero`.

Lean sobre los atajos de teclado que crea lsp-zero:

* [Atajos para autocompletado](https://github.com/VonHeikemen/lsp-zero.nvim/tree/v3.x#keybindings-1)
* [Atajos para funciones de LSP](https://github.com/VonHeikemen/lsp-zero.nvim/tree/v3.x#keybindings)

También pasen por la documentación de [mason.nvim](https://github.com/williamboman/mason.nvim). 

Pueden preguntarme cualquier cosa sobre `lsp-zero` aquí, en la sección de [discusión en github](https://github.com/VonHeikemen/lsp-zero.nvim/discussions), o en matrix [#lsp-zero-nvim:matrix.org](https://matrix.to/#/#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 ☕](https://www.buymeacoffee.com/vonheikemen).

[![buy me a coffee](https://res.cloudinary.com/vonheikemen/image/upload/v1618466522/buy-me-coffee_ah0uzh.png)](https://www.buymeacoffee.com/vonheikemen)