A Neovim plugin for managing and updating your dotfiles repository directly from within Neovim.
- π Check for updates from your dotfiles repository
- π Update your dotfiles with a single keystroke
- π Visual diff of local vs remote commits
- π¨ Simple TUI interface similar to Lazy.nvim
- β‘ Configurable timeouts for git operations
- π Periodic update checking with configurable frequency
- π¦ Plugin update integration with lazy.nvim
- π‘οΈ Robust configuration validation and error handling
- π₯ Built-in health checking for troubleshooting
- π Security features to prevent shell injection
Using lazy.nvim
{
"cosmicbuffalo/updater.nvim",
opts = {
-- Configuration options (see below)
},
}The plugin comes with sensible defaults, but you can customize it:
require("updater").setup({
-- Path to the dotfiles repository (default: current Neovim config directory)
repo_path = vim.fn.stdpath("config"),
-- Utility to run commands with timeout (switch to gtimeout on macOS)
timeout_utility = "timeout",
-- Title for the updater window
title = "Neovim Dotfiles Updater",
-- How many commits to show in the log
log_count = 15,
-- Main branch name
main_branch = "main",
-- Git operation options
git = {
rebase = true,
autostash = true,
},
-- Git operation timeouts (in seconds)
timeouts = {
fetch = 30,
pull = 30,
merge = 30,
log = 15,
status = 10,
default = 20,
},
-- Keybindings
keymap = {
-- normal mode keymaps
open = "<leader>e", -- Opens the updater TUI
-- TUI buffer-local keymaps
update = "u", -- Updates dotfiles only
refresh = "r", -- Refreshes status
close = "q", -- Close the updater TUI
install_plugins = "i", -- Install plugin updates via lazy restore
update_all = "U", -- Update dotfiles + install plugin updates
},
-- Startup check configuration
check_updates_on_startup = {
enabled = true, -- Check for updates when Neovim starts
},
-- Periodic update checking
periodic_check = {
enabled = true, -- Enable periodic checking
frequency_minutes = 20, -- Check every 20 minutes (default)
},
})- Press
<leader>e(default) or run:UpdaterOpen - The updater will automatically check for updates when opened
U- Update dotfiles + install plugin updates (recommended)u- Update dotfiles onlyi- Install plugin updates only (via lazy restore)r- Refresh the statusqor<Esc>- Close the updater
:UpdaterOpen- Open the updater interface:UpdaterCheck- Check for updates and show notification:UpdaterStartChecking- Start periodic update checking:UpdaterStopChecking- Stop periodic update checking:UpdaterHealth- Run health check for troubleshooting
The plugin supports two types of automatic checking:
Check for updates when Neovim starts:
require("updater").setup({
check_updates_on_startup = { enabled = false } -- Disable startup check
})Automatically check for updates every few minutes (only notifies when updates are available):
require("updater").setup({
periodic_check = {
enabled = true,
frequency_minutes = 60, -- Check every hour
}
})Display update status in your lualine statusbar by adding this to your lualine config:
-- Basic integration
require('lualine').setup({
sections = {
lualine_x = {
{
function()
return require('updater').status.get_update_text()
end,
cond = function()
return require('updater').status.has_updates()
end,
color = { fg = '#ff9e64' }, -- Orange color for updates
on_click = function()
require('updater').open()
end,
},
-- ... your other lualine_x components
}
}
})-- With custom formatting and icons
{
function()
return require('updater').status.get_update_text('icon') -- Use icon format
end,
cond = function()
return require('updater').status.has_updates()
end,
color = function()
local status = require('updater').status.get()
-- Different colors based on update type
if status.needs_update and status.has_plugin_updates then
return { fg = '#f7768e' } -- Red for both types
elseif status.needs_update then
return { fg = '#ff9e64' } -- Orange for dotfiles
else
return { fg = '#9ece6a' } -- Green for plugins only
end
end,
on_click = function()
require('updater').open()
end,
}The get_update_text() function supports different formats:
"default": "2 dotfiles, 3 plugins updates""short": "2d 3p""icon": "σ°° 2 σ° 3"
See examples/lualine.lua for more complete integration examples.
local updater = require('updater')
-- Check if any updates are available
updater.status.has_updates() -- returns boolean
-- Get total count of available updates
updater.status.get_update_count() -- returns number
-- Get formatted update text
updater.status.get_update_text('icon') -- returns string or empty string
-- Get detailed status information
updater.status.get() -- returns table with all status info
-- Open the updater TUI
updater.open()- Fetching: The plugin fetches the latest changes from your remote repository
- Comparison: It compares your local branch with the remote main branch
- Display: Shows you what commits are available and what's different
- Plugin Updates: If lazy.nvim is available, it also checks for plugin updates
- Update:
U- Updates dotfiles + installs plugin updatesu- Updates dotfiles only (pulls changes on main branch, merges on feature branches)i- Installs plugin updates only (via lazy restore)
- Neovim >= 0.7.0
- Git
timeoutcommand (Linux) orgtimeout(macOS via Homebrew) - optional but recommended- lazy.nvim - optional, enables plugin update features
- fidget.nvim - optional, enables unobtrusive progress indicators
For local testing and development, see TESTING.md for comprehensive testing methods including:
- Debug Mode: Simulate updates without git changes
- Test Branch: Create git scenarios with real update states
- Test Repository: Set up dedicated test environments
Debug functionality is loaded on-demand to keep the main plugin lightweight:
:UpdaterDebugToggle " Toggle debug mode (lazily loads)
:UpdaterDebugSimulate 2 3 " Simulate 2 dotfile + 3 plugin updates
:UpdaterOpen " Open TUI to see simulated updates
:UpdaterDebugDisable " Turn off debug modeDebug Commands:
:UpdaterDebugToggle- Toggle debug mode on/off:UpdaterDebugSimulate <dotfiles> <plugins>- Enable debug mode and simulate specific update counts (both arguments required):UpdaterDebugDisable- Turn off debug mode
Behavior:
- Debug module loads only when
:UpdaterDebugToggleis first used :UpdaterDebugTogglesets default simulation values (2 dotfiles, 3 plugins)- Debug simulation affects both periodic checks and the updater TUI when enabled
Note: Debug mode simulates updates without making actual git changes, useful for testing UI and workflows.
If you encounter issues, run :UpdaterHealth to diagnose common problems:
- Git repository validation
- Git command availability
- Timeout utility check
- Lazy.nvim integration status
- Fidget.nvim integration status
- Remote connectivity test
The plugin includes several security features:
- Input validation to prevent shell injection
- Path sanitization for repository locations
- Timeout protection for all git operations
- Safe command execution with proper escaping
MIT License