Neovim's plugin ecosystem moves fast. Sometimes this is great because we get new features. Other times... things break. Having your editor in an unusable state is not fun. But we can recover from that. In going tell you how to use packer.nvim to take your editor back to a good state.
The tools
In packer.nvim there is a thing called a snapshot. This is a JSON file that contains the commit hash of every plugin installed.
To manage the snapshot files packer.nvim offers these commands:
-
PackerSnapshot {name}
:
Creates the snapshot file. The first argument of this command the name of the file.
-
PackerSnapshotRollback {name} [{plugin}]
:
Reverts the plugins back to the commit specified by a snapshot. {name}
must be the name of snapshot file. If you provide the argument {plugin}
then only that plugin will be restored.
PackerSnapshotDelete {name}
Deletes the snapshot file with {name}
.
Our first step
We can't go back to a good state if we don't have snapshot of that.
So the first thing we should do is take a snapshot of our plugins when everything is good. If your editor is working fine right now, you should execute this command.
:PackerSnapshot stable
You could even add a date format to the name. Maybe add month and year.
:PackerSnapshot stable-07-2023
In case of emergency...
What to do when things go wrong? Rollback. Execute the command to revert all your plugins to the state of the stable
snapshot.
:PackerSnapshotRollback stable
And remember, you can specify which plugin you want to restore. Something like this would work.
:PackerSnapshotRollback stable nvim-treesitter
Worst case scenario
If your Neovim config breaks before it loads packer.nvim then you'll have to source it yourself.
If your packer config lives in its own lua module, navigate to that file and execute this command
:source %
If you can't execute your packer config without triggering an error, you'll have to go to the place where you have the require('packer').startup
block, select the whole thing, then execute this command.
:'<,'>source
Once packer is loaded you can use the rollback command.
Make it convenient
Snapshot are great and all but we can make them better.
We can make a command that creates a snapshot before an update. And make another command that restores the most recent snapshot.
Here is the code.
local last_snapshot = vim.fn.stdpath('data') .. '/last-snapshot-date'
vim.api.nvim_create_user_command(
'PluginUpdate',
function()
local packer = require('packer')
local name = vim.fn.strftime('%Y-%m-%d@%H:%M:%S')
packer.snapshot(name)
vim.fn.writefile({name}, last_snapshot)
local timer = vim.loop.new_timer()
local wait_ms = 1000
timer:start(wait_ms, 0, function()
timer:stop()
timer:close()
packer.sync()
end)
end,
{}
)
vim.api.nvim_create_user_command(
'PluginRestore',
function()
local ok, name = pcall(vim.fn.readfile, last_snapshot, 1)
if not ok then return end
require('packer').rollback(name[1])
end,
{}
)
With this in your config you will use :PluginUpdate
instead of :PackerSync
. And if there is a bad update you can use :PluginRestore
to go back to the previous state.
How to keep Neovim from breaking
Here is my advice.
Use a stable release. Avoid nightly versions if you can.
Don't update your plugins daily. Stop it.
Update your plugins only on the weekends when you have free time.
Conclusion
Neovim plugins change all the time. They update frecuently and things can break. That's why we need to learn how to deal with this situation. If a plugins breaks our editor, we can go back to a working state using packer.nvim's snapshots.
Thank you for your time. If you find this article useful and want to support my efforts, consider leaving a tip in ko-fi.com/vonheikemen.
Top comments (0)