El árbol de deshacer (undo tree)
El deshacer de Neovim no es una línea, es un árbol. Nunca vuelvas a perder código: viaja en el tiempo por tus ramas de edición con undotree y :earlier.
En casi todos los editores, deshacer y volver a escribir borra el “futuro” que descartaste. En Neovim no: cada rama se guarda. El historial de deshacer es un árbol completo, y con undofile sobrevive incluso a cerrar el editor.
- Entender por qué el deshacer es un árbol, no una línea.
- Persistir el historial entre sesiones con undofile.
- Viajar en el tiempo con
:earlier/:lateryg-/g+. - Visualizar y navegar el árbol con undotree.
Deshacer lineal vs árbol
Imagina: escribes A, luego B. Deshaces B y escribes C. En un editor normal, B se ha perdido para siempre. En Neovim, tu historial es:
flowchart TD Base[estado inicial] --> A[edicion A] A --> B[edicion B] A --> C[edicion C] style Base fill:#45475a,color:#cdd6f4 style B fill:#f9e2af,color:#11111b style C fill:#a6e3a1,color:#11111b
Tanto B como C siguen ahí. Puedes volver a cualquier rama. Nunca pierdes trabajo por deshacer y re-escribir.
Persistencia entre sesiones
Ya activaste esto en el Nivel 1, pero aquí está su verdadero valor:
vim.o.undofile = true -- guarda el historial en disco
vim.o.undolevels = 10000 -- muchísimos pasos de deshacer
No hace falta que toques undodir: Neovim ya trae una carpeta propia dentro de su directorio de estado. Compruébala con :echo &undodir y cámbiala solo si quieres otra ruta.
Con undofile, cierras Neovim, vuelves mañana, abres el archivo y puedes deshacer cambios de ayer. El historial persiste.
Viajar en el tiempo
Más allá de u y Ctrl-r:
| Comando | Acción |
|---|---|
u / Ctrl-r |
deshacer / rehacer (por la rama actual) |
g- / g+ |
ir al estado anterior / siguiente en el tiempo (cruza ramas) |
:earlier 10m |
vuelve al estado de hace 10 minutos |
:later 5m |
avanza 5 minutos |
:earlier 3f |
retrocede 3 guardados de archivo |
u deshace por la rama actual del árbol. g- retrocede por orden cronológico, saltando entre ramas. Cuando “deshiciste demasiado” y Ctrl-r no encuentra lo que buscas porque estaba en otra rama, g-/g+ recorren todo el historial temporal. Es tu red de seguridad definitiva.
Visualizar el árbol: undotree
Ver el árbol como texto es abstracto. undotree lo dibuja y te deja navegarlo visualmente:
return {
"mbbill/undotree",
cmd = { "UndotreeToggle", "UndotreePersistUndo" },
keys = {
{ "<leader>u", "<cmd>UndotreeToggle<cr>", desc = "Árbol de deshacer" },
},
init = function()
vim.g.undotree_WindowLayout = 2
vim.g.undotree_SetFocusWhenToggle = 1
end,
}vim.g.undotree_WindowLayout = 2 -- árbol a la izquierda, diff abajo del todo
vim.g.undotree_SetFocusWhenToggle = 1 -- el cursor salta al panel al abrirlo
vim.pack.add({ { src = "https://github.com/mbbill/undotree" } })
vim.keymap.set("n", "<leader>u", "<cmd>UndotreeToggle<cr>", { desc = "Árbol de deshacer" })Este es de los que sí ganan con carga perezosa: es Vimscript y solo lo abres de vez en cuando, así que con lazy.nvim ni se toca hasta que pulsas la tecla. Con vim.pack se carga siempre, pero es un plugin diminuto.
Las vim.g.undotree_* se leen cuando el panel se dibuja, así que en lazy van en init (antes de cargar el plugin) y con vim.pack basta con ponerlas arriba del init.lua.
Pulsa <leader>u y aparece un panel con todas las ramas y marcas de tiempo. Navégalas y verás el estado del archivo en cada punto. Recuperar código “perdido” pasa de ser imposible a un par de teclas.
Visualiza el árbol de deshacer completo con marcas de tiempo. Navega ramas y recupera cualquier versión anterior del archivo.
Ver solución
Con undotree (<leader>u) ves ambas ramas: navega a la del borrado y restaura. Sin plugin, g- retrocede en el tiempo hasta reencontrar la función aunque u/Ctrl-r no la alcancen por rama.
- Confirma que tienes
undofile = true. - Haz varias ediciones creando ramas (edita, deshaz, edita distinto).
- Abre
<leader>uy navega el árbol. - Usa
:earlier 2mpara volver 2 minutos atrás y:laterpara regresar.