Una introducción pragmática al uso de plugins en Neovim
Ya me he referido a Neovim alguna vez en el pasado: Lo viejo, lo bueno y lo nuevo en Neovim . Se pueden extender las funcionalidades de neovim, mediante plugins, de manera similar a las de su predecesor, el editor Vim. En este artículo propongo un modo muy sencillo y lo más transparente posible para el uso de plugins en Neovim.
Hay dos tipos de plugins:
- Globales: Funcionan para todo tipo de archivos.
- Filetype: Sirven para un tipo particular de archivos**.
El siguiente listado muestra plugins globales que forman parte del core de neovim:
ls -l /usr/share/nvim/runtime/plugin total 60 -rw-r--r-- 1 root root 411 mar 26 10:48 editorconfig.lua -rw-r--r-- 1 root root 3677 mar 26 10:48 gzip.vim -rw-r--r-- 1 root root 904 mar 26 10:48 man.lua -rw-r--r-- 1 root root 138 mar 26 10:48 matchit.vim -rw-r--r-- 1 root root 7966 mar 26 10:48 matchparen.vim -rw-r--r-- 1 root root 152 mar 26 10:48 netrwPlugin.vim -rw-r--r-- 1 root root 2160 mar 26 10:48 osc52.lua -rw-r--r-- 1 root root 2017 mar 26 10:48 rplugin.vim -rw-r--r-- 1 root root 1778 mar 26 10:48 shada.vim -rw-r--r-- 1 root root 236 mar 26 10:48 spellfile.vim -rw-r--r-- 1 root root 2527 mar 26 10:48 tarPlugin.vim -rw-r--r-- 1 root root 442 mar 26 10:48 tohtml.lua -rw-r--r-- 1 root root 202 mar 26 10:48 tutor.vim -rw-r--r-- 1 root root 2642 mar 26 10:48 zipPlugin.vim
Plugin | Funcionalidad |
---|---|
editorconfig |
Busca y lee archivos .editorconfig para aplicar reglas de indentación, fines de línea y codificación |
gzip |
Editar archivos comprimidos con gzip |
man |
Abrir páginas del manual en el editor |
matchit |
Extiende la funcionalidad del comando %
|
matchparen |
Resalta paréntesis coincidentes |
netrwPlugin |
Maneja la transferencia de archivos y listado de directorios remotos a través de una red |
osc52 |
Detecta si es posible usar el código de escape ANSI para copir desde vim a otras terminales para poder copiar texto desde neovim usand el clipboard del sistema |
rplugin |
Gestiona, migra, actualiza y carga remote plugins automáticamente (están escritos en otros lenguajes como Python, Ruby, Node.js, etc y que se manejan de manera independiente del editor sin afectar el rendimiento) |
shada |
Datos Compartidos entre las sesiones de neovim |
spellfile |
Descarga de archivos de ortografía |
tarPlugin |
Exploración de tarballs |
tohtml |
Conversor a html |
tutor |
Tutorial |
zipPlugin |
Exploración de archivos zip |
Los scripts en vimL pueden contener comandos de edición, estructuras de control, funciones, manejo de listas, diccionarios, y puede simular objetos mediante diccionarios con referencias a funciones. El otro lenguaje nativo que incorpora neovim es Lua. Los desarrolladores de neovim consideran que ese lenguaje es más eficiente, tiene una sintaxis más moderna y estándar, maneja mejor los errores, permite que sea extendido fácilmente con plugins y módulos complejos, sin necesidad de depender de procesos externos o hacks.
Si consideramos el archivo del plugin man contiene lo siguiente:
if vim.g.loaded_man ~= nil then return end vim.g.loaded_man = true vim.api.nvim_create_user_command('Man', function(params) local man = require('man') if params.bang then man.init_pager() else local err = man.open_page(params.count, params.smods, params.fargs) if err then vim.notify('man.lua: ' .. err, vim.log.levels.ERROR) end end end, { bang = true, bar = true, range = true, addr = 'other', nargs = '*', complete = function(...) return require('man').man_complete(...) end, }) local augroup = vim.api.nvim_create_augroup('nvim.man', {}) vim.api.nvim_create_autocmd('BufReadCmd', { group = augroup, pattern = 'man://*', nested = true, callback = function(params) local err = require('man').read_page(assert(params.match:match('man://(.*)'))) if err then vim.notify('man.lua: ' .. err, vim.log.levels.ERROR) end end, })
📝 Mini resumen conceptual — man.lua
✔ ¿Qué hace el plugin?
- Define cómo abrir manpages usando comandos (
:Man
) y URIs (man://...
). - Define cómo manejar errores (usa
vim.notify
).
✔ ¿Cómo funciona?
-
Previene carga múltiple con
vim.g.loaded_man
. -
Crea un comando
:Man
con opciones (bang, autocompletado, etc.). -
Crea un autocmd que detecta buffers con URI
man://
y carga la manpage. -
Usa funciones (
open_page
,init_pager
,read_page
,man_complete
) definidas en el móduloman
. -
Muestra errores con
vim.notify
si algo falla.
✔ ¿Qué flujo sigue?
Usuario → :Man o :edit man:// → función del módulo man → buffer con la manpage
✅ El plugin es 100% todo Lua
- Usa API moderna de Neovim:
vim.api.nvim_create_user_command
vim.api.nvim_create_autocmd
vim.notify
- Usa variables globales Lua:
vim.g.loaded_man
- Usa funciones Lua:
string.match
,require
, etc.
Es un plugin moderno, pensado para ser usado con Neovim o Vim con soporte de Lua.
API para plugins y herramientas
Además, neovim posee una API con la cual se pueden hacer desarrollos en otros lenguajes de programación y por eso existen plugins y/o herramientas relacionadas que no están escritos en vimL o LUA:
- Painless Java
- neovimi (node.js)
- Nodejs extension host for vim & neovim, load extensions like VSCode and host language servers
- Cliente de python para escribir plugins
El plugin far.vim está desarrollado en python:
Se debe ejecutar :UpdateRemotePlugins
cada vez que un plugin remoto se instale, se actualice, o se borre. Esto generará o actualizará un archivo manifest, por ejemplo:
cat ~/.local/share/nvim/rplugin.vim " node plugins " python3 plugins call remote#host#RegisterPlugin('python3', '/root/.local/share/nvim/plugged/far.vim/rplugin/python3/far', [ \ {'sync': v:false, 'name': '_far_nvim_rpc_async_invoke', 'type': 'function', 'opts': {}}, \ ]) " ruby plugins " python plugins
Equivalencias entre Vim y Neovim
Abro un paréntesis para recordar las equivalencias entre archivos de Vim y Neovim:
Elemento | Vim | Neovim |
---|---|---|
Config principal | ~/.vimrc |
~/.config/nvim/init.vim o init.lua
|
Carpeta de configuración | ~/.vim/ |
~/.config/nvim/ |
Plugins (autoload) | ~/.vim/autoload/ |
~/.local/share/nvim/site/autoload/ |
Plugins (paquetes) | ~/.vim/pack/ |
~/.local/share/nvim/site/pack/ |
Datos de usuario (swap, undo, backup, etc.) | Dentro de ~/.vim/ o definido por el usuario |
~/.local/state/nvim/ |
Swap files | ~/.vim/swapfiles/ |
~/.local/state/nvim/swap/ |
Undo files | ~/.vim/undodir/ |
~/.local/state/nvim/undo/ |
Backup files | ~/.vim/backup/ |
~/.local/state/nvim/backup/ |
viminfo | ~/.viminfo |
No se usa directamente |
shada | No aplica (usa viminfo) | ~/.local/share/nvim/shada/main.shada |
Colorschemes | ~/.vim/colors/ |
~/.config/nvim/colors/ |
After directory (sobreescribir plugins/config) | ~/.vim/after/ |
~/.config/nvim/after/ |
Nota sobre shada:
- Vim usa
viminfo
→~/.viminfo
. - Neovim usa
shada
→~/.local/share/nvim/shada/main.shada
.
No es recomendable hacer enlace simbólico entre estos dos archivos porque no son 100% compatibles.
Soporte nativo para plugins en Vim 8 (y en adelante)
Photo by Handy Wicaksono on Unsplash
Desde Vim 8.0 el editor cuenta con soporte nativo para paquetes. En Vim un paquete no es otra cosa que un directorio de plugins. Es decir, considerando el siguiente escenario.
El paquete lightline.vim se va a cargar automáticamente al abrir el editor, mientras que el otro plugin toggleterm podrá activarse con el comando :packadd toggleterm.nvim
Guía rápida para el método nativo de Vim 8+
Mostraré como usar 2 plugins.
1. Crear las carpetas necesarias
Abrí tu terminal y ejecutá:
mkdir -p ~/.vim/pack/misplugins/{start,opt}
Explicación rápida:
-
~/.vim/pack/
→ carpeta donde Vim busca paquetes. -
misplugins
→ nombre del grupo que quieras (puede ser cualquier nombre). -
start/
→ indica que los plugins se cargan automáticamente al abrir Vim. -
opt/
→ indica que los plugins se cargarán bajo demanda con el comandopackadd
2. Descargar los plugins
Ahora dentro de start/
, cloná los repositorios de Git de los plugins:
cd ~/.vim/pack/misplugins/opt # vim-fugitive (permite ejecutar y gestionar comandos de Git directamente dentro de Vim, como hacer commits, ver logs, ver diferencias (diffs) y manejar ramas sin salir del editor.) git clone https://tpope.io/vim/fugitive.git vim -u NONE -c "helptags fugitive/doc" -c q cd ~/.vim/pack/misplugins/start # lightline.vim (barra de estado mejorada) git clone https://github.com/itchyny/lightline.vim.git # Usar el comando siguiente si lightline.vim se muestre sin colores y guardarlo en algún archivo de configuración del shell. # export TERM=xterm-256color
Con esto ya los tenés instalados.
3. Configuración para lightline.vim|
Podés agregar algunas líneas en tu ~/.vimrc
para aprovechar lightline.vim:
" Opcional: configuración mínima para lightline set laststatus=2
4. Listo
¡Abrí Vim y ya podés usar el plugin lightline.vim!
Si querés cargar el plugin fugitive, lo hacés con:
:packadd fugitive
Importante: Los plugins escritos en lua no funcionarán en Vim
Algo interesante en Vim y Neovim es que podemos ver los plugins que ya vienen con el editor con el comando :help standard-plugin-list
y con :help local-additions
los plugins que vamos agregando:
O si preferimos algo más sofisticado, para ver nuestros plugins:
:echo join(keys(g:plugs), ' ')
Si bien esta funcionalidad también existe en Neovim, podemos administrar los plugins de manera más flexible y automatizada. Esto nos lleva a considerar el uso de gestores de plugins.
Gestores de plugins
Existen varios gestores de plugins:
- Shougo/dein.vim: Dark powered Vim/Neovim plugin manager
- VundleVim/Vundle.vim: Vundle, the plug-in manager for Vim
- junegunn/vim-plug: Minimalist Vim Plugin Manager
Me parece muy recomendable vim-plug porque:
- Requiere muy poca configuración: una lista con los paquetes de plugins deseados.
- Instala y actualiza todos los paquetes de nuestra lista o los que seleccionemos.
- Detecta y elimina plugins que borramos de nuestra lista.
- Muestra el estado de los plugins.
- Genera instantáneas de nuestros paquetes con su configuración, con la posibilidad de restaurarlas.
- Posee atajos de teclado.
- Es compatible tanto con Vim como Neovim
Si queremos deshabilitar todos los plugins podemos ejecutar nvim --noplugin
.
Neovim sigue los lineamientos de la XDG Base Directory Specification. Algo que puede ser muy útil: poner el listado de plugins en un archivo separado. Esto es: creando un archivo ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/plugins.vim
y en el archivo ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/init.vim
teniendo una simple línea:
runtime plugins.vim
Entonces, comentando esa línea es una manera alternativa para desactivarlos.
Pero hay más: supongamos que tenemos esta configuración en el archivo ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/plugins.vim
:
Plug 'nyngwang/NeoTerm.lua' call plug#end() " Esta es la manera de embeber código lua en un archivo de tipo vimL lua << EOF require("neo-term").setup { exclude_filetypes = { "oil" } } EOF nnoremap <F4> :NeoTermToggle<CR> tnoremap <F4> <C-\><C-n>:NeoTermToggle<CR> tnoremap <Esc> <C-\><C-n>:NeoTermEnterNormal<CR>
Con esta configuración:
- Al presionar F4 se abirá una terminal.
- Al presionar de vuelta F4 se cerrará la terminal.
- Con Esc se vuelve al modo Normal en la terminal.
En tiempos en los que tanto se declama la agilidad, como contrasentido se ofrecen editores que consumen muchos recursos, con desarrollos no exentos de torpezas y caprichos impuestos de antemano. El minimalismo de Vim como de Neovim nos permite adaptarlo de acuerdo a lo que necesitemos, la posibilidad de agregar distintas funcionalidades, sea para desarrollo, mejor usabilidad y experiencia del usuario (sí: el desarrollador o sysadmin también es un usuario 😀). Finalmente, si bien tanto Vim como Neovim poseen el soporte nativo para manejar paquetes de plugins, encuentro en vim-plugin una manera mucho más conveniente de hacerlo.
Característica | Sistema Nativo (Vim 8 packages ) |
vim-plug |
---|---|---|
Instalación | Manual (clonar repos en pack/ ) |
Automática vía script (plug.vim ) |
Configuración | En vimrc , usando packadd o estructura start/opt
|
Declarativa en vimrc con Plug
|
Carga diferida (lazy-loading) | Manual con packadd desde opt/
|
Incorporado: on , for , cmd , event
|
Instalación de plugins | Manual (git clone ) |
:PlugInstall |
Actualización | Manual (git pull en cada plugin) |
:PlugUpdate |
Desinstalación | Manual (borrar carpeta) | :PlugClean |
Gestión de dependencias | No soportado nativamente | Limitada (tú defines el orden) |
Soporte para branches/tags | Manual (git checkout ) |
Sí (Plug 'user/repo', { 'branch': 'dev' } ) |
Paralelismo en instalación | No | Sí (instala varios plugins a la vez) |
Interfaz de usuario | Ninguna | Básica pero útil (durante instalación/update) |
Velocidad en carga | Muy rápida (carga solo en startup) | Muy rápida con lazy loading |
Soporte oficial | Parte de Vim 8+ | Mantenido por la comunidad |
Curva de aprendizaje | Mayor (entender estructura pack/ ) |
Muy simple y bien documentado |
Compatibilidad | Solo Vim 8+ | Compatible con Vim 7.4+, Neovim |
Conclusión
El soporte nativo de Vim/Neovim es como una biblioteca física organizada con dos tipos de estantes:
-
start/
: son los libros que se abren automáticamente apenas entrás a la biblioteca —es decir, los plugins que se cargan al iniciar Vim/Neovim. -
opt/
: son libros que están en los estantes, pero que vos tenés que buscar y abrir manualmente usando el comando:packadd
.
Este sistema te da control total, pero también requiere que te ocupes de la instalación, organización y carga de cada plugin.
Los gestores de plugins, como vim-plug
, funcionan como un sistema de préstamo digital moderno:
-
Suscripción básica: Declarás qué libros (plugins) querés en una lista de solicitudes (
Plug 'autor/plugin'
), y al ejecutar un comando comoPlugInstall
, el sistema los descarga automáticamente y los organiza en las secciones correspondientes del runtimepath. -
Dependencias = citas bibliográficas que debés declarar manualmente: Si el libro A necesita al libro B para entenderse correctamente, vos tenés que pedir ambos explícitamente. A diferencia de gestores como
npm
,pip
ocargo
, no hay resolución automática de dependencias: nadie deduce relaciones por vos. -
Actualizaciones periódicas: Usando el comando
PlugUpdate
, podés sincronizar tu colección con las últimas ediciones disponibles. Eso sí: estos comandos actualizan lo que ya tenés, pero no agregan automáticamente nuevos plugins a menos que los declares en tu configuración.
Ahora cabe preguntarse dos cosas:
- ¿Cómo podemos empezar a usar Lua?
- Más allá de que
vim-plug
es una excelente opción: ¿Es actualmente la mejor para Neovim?
Comentarios
Comments powered by Disqus