Cómo migrar de vim-plug a lazy.nvim
Introducción
Ya vimos como convertir una una configuración en Vim script a Lua. Ese tipo de configuración es más flexible y reutilizaable. Ahora vamos por el paso final que es migrar de vim-plug a lazy.vim.
¿Qué es lazy.nvim?
Es un gestor de plugins escrito en Lua que sabe sacar provecho de la arquitectura moderna de Neovim.
¿Qué ventajas y funcionalidades tiene lazy.vim?
El gestor lazy.nvim se destaca por su rendimiento, usabilidad/UX y el modo de gestionar de plugins.
En la siguiente tabla vemos como se destaca en cuento a Rendimiento:
Funcionalidad/Ventaja | ¿Qué significa? |
---|---|
Inicio ultra rápido | Arranca en segundos porque los módulos se precompilan y se cachean automáticamente. |
Instalaciones livianas | Clona sólo lo esencial de los repos, ahorrando ancho de banda y espacio. |
Plugins sin bloqueo del editor | Tareas pesadas se ejecutan en segundo plano, manteniendo Neovim fluido. |
Análisis de rendimiento | Herramientas para medir tiempos de carga y optimizar tu configuración. |
Carga bajo demanda (lazy-loading) | Plugins se cargan solo cuando se necesitan, reduciendo carga inicial y memoria. |
📝 ¿Qué y dónde cachea lazy.nvim?
Directorio | Uso específico por lazy.nvim
|
---|---|
~/.cache/nvim/luac/ |
Cache de bytecode Lua. Compila tu configuración en Lua a .luac , para que Neovim no tenga que interpretarla cada vez. |
~/.local/share/nvim/lazy/ |
Instalación real de los plugins. Los plugins ya descargados no necesitan revalidarse ni reinstalarse. |
~/.local/state/nvim/lazy/ |
Cache de estado: versiones exactas de los plugins, commits, fechas, hashes. Así lazy.nvim sabe si algo cambió. |
¿Por qué migrar de vim-plug?
Los números duros
La tabla de arriba muestra que
- Si bien ambos son repositoorios populares, vim-plug (que es un proyecto más longevo) supera a lazy.nvim en este aspecto.
- Ambos proyectos están activos.
- El repo lazy.nvim tiene más colaboradores.
En este aspecto salen bastante empatados.
Aspectos ventajosos desde el punto de vista técnico
- Para sysadmins: Rendimiento y carga mínima: se puede configurar de manera natural los plugins que realmente necesitás en tu entorno (por ejemplo, se pueden configurar plugins para que solamente se carguen al usar ssh) y una configuración más clara: todo en Lua, más fácil de mantener con backups dotfiles/scripts.
- Para desarrolladores: Carga por filetype y herramientas específicas y mayor control sobre dependencias y versiones.
Funcionalidad | vim-plug | lazy.nvim | Nota / Matiz |
---|---|---|---|
Gestión de plugins (install/update) | Sí | Sí | Ambos permiten instalar, actualizar y remover plugins fácilmente |
Lazy loading de plugins | Sí (manual, limitado) | Sí (declarativo y avanzado) | vim-plug requiere configuración manual con on , for , cmd
|
Cache de estado (lockfiles, hashes) | Parcial (:PlugSnapshot ) |
Sí (lazy-lock.json ) |
vim-plug permite snapshot, pero no lo gestiona ni lo aplica automáticamente |
Cache de bytecode Lua (.luac) | No | Sí | lazy.nvim compila módulos Lua para acelerar el arranque |
Arranque optimizado | Parcial (con lazy manual) | Sí (caching + carga bajo demanda) | lazy.nvim acelera usando cache + lazy loading automático |
Integración con configuración Lua | No (Vimscript-first) | Sí (nativo en Lua) | vim-plug puede usarse con hacks en Lua, pero no está diseñado para eso |
Conceptos fundamentales para usar lazy
1. Comentarios
-- Esto es un comentario
2. Variables
local nombre = "Neovim" local numero = 14
3. Tablas (como diccionarios o listas)
local opciones = { number = true, relativenumber = true }
4. Funciones
local function saludar() print("Hola desde Lua") end
5. Requiriendo otros archivos (modularización)
require("usuario.options") require("usuario.plugins.lazy")
Ejemplo concreto de migración
Usamos como punto de partida el archivo ~/.config/nvim/plugins.vim
del post anterior:
"Plugins (Plug) call plug#begin('~/.vim/plugged') Plug 'itchyny/lightline.vim' Plug 'nyngwang/NeoTerm.lua' Plug 'NLKNguyen/papercolor-theme' call plug#end() 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>
Clonar el repo
git clone https://github.com/folke/lazy.nvim.git ~/.local/share/nvim/lazy/lazy.nvim
Prepara el entorno
Creamos un directorio para la configuración de los plugins y otro para la configuración de lazy.nvim:
mkdir ~/.config/nvim/lua/lplugins # Aquí estarán los archivos de configuración de los plugins mkdir ~/.config/nvim/lua/config/
Configuración inicial
Partimos de este archivo:
-- Cargamos módulos local commands = require('utils.commands') local extracommands = require('utils.extracommands') local keymaps = require('keymaps') local opciones = require('opciones') -- Mantenemos por ahora la configuración de plugins en Vim script vim.cmd('source ~/.config/nvim/plugins.vim')
Y hacemos las siguientes modificaciones:
-- Cargamos módulos local commands = require('utils.commands') local extracommands = require('utils.extracommands') local keymaps = require('keymaps') local opciones = require('opciones') -- Mantenemos por ahora la configuración de plugins en Vim script -- vim.cmd('source ~/.config/nvim/plugins.vim') -- require("config.lazy")
¿Qué hicimos? Deshabilitar vim-plug y por ahora dejar comentada la línea que llamará al archivo ~/.config/nvim/lua/config/lazy.lua
.
Luego en dicho archivo pondremos lo siguiente:
-- Bootstrap lazy.nvim local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" if not (vim.uv or vim.loop).fs_stat(lazypath) then local lazyrepo = "https://github.com/folke/lazy.nvim.git" local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) if vim.v.shell_error ~= 0 then vim.api.nvim_echo({ { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, { out, "WarningMsg" }, { "\nPress any key to exit..." }, }, true, {}) vim.fn.getchar() os.exit(1) end end vim.opt.rtp:prepend(lazypath) -- Make sure to setup `mapleader` and `maplocalleader` before -- loading lazy.nvim so that mappings are correct. -- This is also a good place to setup other settings (vim.opt) vim.g.mapleader = " " vim.g.maplocalleader = "\\" -- Setup lazy.nvim require("lazy").setup({ spec = { -- import your plugins { import = "lplugins" }, }, -- Configure any other settings here. See the documentation for more details. -- colorscheme that will be used when installing plugins. install = { colorscheme = { "habamax" } }, -- automatically check for plugin updates checker = { enabled = true },
Explicación
require("lazy").setup({ ... })
Es la función principal que inicia y configura los plugins en lazy.nvim.
spec =
Es el campo que indica la especificación de los plugins. Es el lugar para definir qué plugins cargar.
spec = { { import = "lplugins.ui" }, }
- Cada
{ import = "..." }
carga los plugins definidos en otros archivos lua. -
En este caso, usamoos una configuración modular:
-
~/.config/nvim/lua/lplugins/ui.lua
tendrá la especificación del plugin papercolor-theme. -
~/.config/nvim/lua/lplugins/terminal.lua
tendrá las especificaciones de los plugins lightline y Neoterm.
install = { colorscheme = { "habamax" } }
Establece un esquema de colores que se aplicará automáticamente en la interfaz del gestor de plugins.
checker =
Activa el verificador automático de actualizaciones. Cabe aclarar que esta configuración no los no los actualiza automáticamente, pero te avisa para que los actualices mediante el comando en modo ex (:Lazy update
).
En la configuración de partida teníamos solamente 3 plugins, pero decidimos dividirlos en dos categorías, a medida que vamos instalando más plugins podemos crear más archivos lua para clasificarlos.
Especificaciones de plugins
Todos los archivos donde clasificás plugins deben tener la keyword return para que cada uno de ellos debe devuelva una tabla Lua con los plugins que querés que lazy.nvim cargue desde esos archivos.
La siguiente es una plantilla de archivo en la cual se especifican plugins:
return { { "autor/repositorio", -- Reemplazá con el nombre del autor y nombre del repositorio -- lazy = false, -- true para carga diferida, false para cargar al inicio -- priority = 1000, -- Opcional. Útil para temas de colores -- event = nil, -- Reemplazá con evento si usás lazy = true (ej: "BufReadPre") -- cmd = nil, -- Reemplazá si querés cargar al ejecutar un comando -- dependencies = {}, -- Lista de plugins que este necesita (si aplica) -- config = function() -- Poné acá la configuración del plugin -- end } }
Para echar un poco de 💡 a esta cuestión de los campos:
Campo | ¿Obligatorio? | ¿Qué hace? |
---|---|---|
"autor/repositorio" |
Sí | Identifica el plugin (por ejemplo "NLKNguyen/papercolor-theme" ) |
config = function() |
No, pero común | Configura el plugin al cargarlo |
lazy = true/false |
Opcional | Define si se carga de forma diferida o al inicio |
priority = número |
Opcional | Da prioridad de carga (útil para temas de colores) |
event = "InsertEnter" |
Opcional | Carga el plugin al ocurrir cierto evento |
cmd = "Comando" |
Opcional | Carga el plugin cuando se ejecuta un comando |
dependencies = {} |
Opcional | Especifica otros plugins requeridos |
Vamos a los ejemplos concretos 💪
Archivo ui.lua
return { { "NLKNguyen/papercolor-theme", priority = 1000, -- para que se cargue antes que otros lazy = false, -- para que se cargue en el arranque config = function() vim.cmd("colorscheme PaperColor") end } }
Esto significa:
» Devuelvo una lista (tabla) con un solo plugin. Este plugin es NLKNguyen/papercolor-theme y quiero que se cargue al inicio, con prioridad alta, y que cuando se cargue, aplique el esquema de colores PaperColor.
Archivo terminal.lua
return { { -- Plugin 1: lightline.vim "itchyny/lightline.vim", config = function() vim.g.lightline = { colorscheme = 'solarized', -- <- podés cambiar por "jellybeans","OldHope", "wombat", "PaperColor", etc. } end, }, -- Separador de items en la lista { -- Plugin 2: NeoTerm.lua "nyngwang/NeoTerm.lua", config = function() require("neo-term").setup { exclude_filetypes = { "oil" }, -- evita que se use en buffers del tipo "oil" } -- Atajos de teclado: vim.keymap.set("n", "<F4>", ":NeoTermToggle<CR>", { silent = true }) -- F4 en modo normal: alterna el terminal vim.keymap.set("t", "<F4>", "<C-\\><C-n>:NeoTermToggle<CR>", { silent = true }) -- F4 en modo terminal: lo mismo vim.keymap.set("t", "<Esc>", "<C-\\><C-n>:NeoTermEnterNormal<CR>", { silent = true }) -- Esc en terminal: pasa a modo normal end }, -- Separador final, no es obligatorio pero conveniente }
Este archivo configura dos plugins:
- lightline.vim: para una línea de estado personalizada.
- NeoTerm.lua: para trabajar con terminales flotantes o integrados, y define atajos con F4 y Esc para manejarlos fácilmente.
Habilitar lazy.nvim
Ya estamos casi listos, solamente falta quitar el comentario en el archivo ~/.config/nvim/init.lua
:
require("config.lazy")
Eso es todo, la próxima vez, al entrar al editor, lazy.nvim se encargará de instalar los plugins especificados.
Es importante ejecutar el comando :checkhealth lazy
el cual hará un diagnóstico de la instalación y configuración:
Sacándole provecho a lazy.nvim
Vamos a instalar el plugin which-key el cual sirve para mostrar de una manera amigable los atajos de teclado configurados.
Editamos el archivo de configuración ~/.config/nvim/lua/lplugins/ui.lua
siguiendo la plantilla mencionada anteriormente:
return { { "NLKNguyen/papercolor-theme", priority = 1000, -- para que se cargue antes que otros lazy = false, -- para que se cargue en el arranque config = function() vim.cmd("colorscheme PaperColor") end, }, { "folke/which-key.nvim", event = "VeryLazy", opts = {}, keys = { { "<leader>ff", "<cmd>edit ~/.config/nvim/init.lua<cr>", desc = "Edit init.lua" }, { "<leader>fr", "<cmd>e #<cr>", desc = "Open recent file" }, { "<leader>tt", "<cmd>terminal<cr>", desc = "Open terminal" }, { "<leader>?", function() require("which-key").show({ global = false }) end, desc = "Buffer Local Keymaps" }, { "<leader>q", "<cmd>q<cr>", desc = "Quit" }, { "<leader>w", "<cmd>w<cr>", desc = "Save" }, -- Grupos visibles (aunque no hacen nada por sí mismos) { "<leader>f", name = "+file" }, { "<leader>t", name = "+terminal" }, }, } }
Este plugin sirve para que al teclar:
-
Espacioff Abrirá el archivo
/.config/nvim/init.lua
. - Espaciofr Abrirá el archivo más reciente.
... y así con cada uno de los atajos definidos, pero además veremos una ayuda en pantalla.
Vamos a verlo en acción:
-
1
Al presionary
.... -
2
Muestra que es Yank que en el contexto de Vi/Vim/Neovim es copiar... -
3
Aparecen automágicamente las teclas que pueden acompañar a este comando 💪
Y listo.... el resto es cuestión de usar la UI de Lazy, y familiarizarse con sus subcomandos en modo Ex.
Conclusión
-
vim-plug
sigue siendo una opción robusta y popular, especialmente para usuarios de Vim clásico o entornos donde se necesita algo probado y ampliamente documentado. -
Sin embargo,
lazy.nvim
es una solución moderna y centrada en Neovim, con alta participación comunitaria y buena agilidad en el mantenimiento. Ideal para setups nuevos o si des#eas aprovechar la asincronía y mejoras de Lua en Neovim.
Siempre que puedas
- Consultá el
README
oficial - Buscá ejemplos en GitHub o Dotfiles de otros usuarios
- Explorá el código fuente si sabés Lua
Estos tres artículos no han servidor para comenzar a usar Neovim, modernizar la configuración y utilizar un gestor de plugins nativo en Lua. wSiempre que agregues un plugin, revisa su README y especifica las dependencias manualmente si no estás seguro. Lazy puede resolver muchas automáticamente, pero declararlas te da más control y claridad.
Detrás de la fachada antigua, Neovim es un editor que adaptó su arquitectura a los nuevos tiempos.
¡Felicitaciones si llegaste hasta acá?