Skip to content

How to enable Neovim undo, backup, and swap files when switching Linux groups

Posted on:March 18, 2023 at 08:44 PM

Introduction

I am a member of multiple Linux groups on our HPC cluster and I frequently jump between them using the newgrp command. When this happens, the ${HOME} directory variable does not change — it stays assigned to the home directory of my primary group (e.g. /home/GROUP-PRIMARY/USER). Neovim has three very useful features (undo, backup, and swap) that allow you to have persistent undo capabilities, a backup of your file between saves, and a constantly-updating copy of your unsaved work (called a swap file) in case your system crashes.

These are usually saved in the same directory as the original file — but that makes your project cluttered with temp files. Another simple approach is to save these files somewhere in your home dir (e.g. ${HOME}/nvim directory. That works great — unless you have switched your current group via nwegrp (and now have different read/write permissions). If I switched to “GROUP-2”, I can no longer read/write files in my original primary group’s home dir.

Therefore, we need to dynamically change the directory for these files to be inside the current group’s user directory (e.g. /home/GROUP-2/USER). This way, we can always read/write these Neovim temp files and don’t have to worry about ever losing our code!

Lua config for Neovim

USER = os.getenv("USER")
local curr_group = vim.fn.system("id -ng 2> /dev/null | tr -d '\n'")
SWAPDIR = "/home/" .. curr_group .. "/" .. USER .. "/nvim/swap//"
BACKUPDIR = "/home/" .. curr_group .. "/" .. USER .. "/nvim/backup//"
UNDODIR = "/home/" .. curr_group .. "/" .. USER .. "/nvim/undo//"
if vim.fn.isdirectory(SWAPDIR) == 0 then
	vim.fn.mkdir(SWAPDIR, "p", "0o700")
end

if vim.fn.isdirectory(BACKUPDIR) == 0 then
	vim.fn.mkdir(BACKUPDIR, "p", "0o700")
end

if vim.fn.isdirectory(UNDODIR) == 0 then
	vim.fn.mkdir(UNDODIR, "p", "0o700")
end
-- Enable swap, backup, and persistant undo
vim.opt.directory = SWAPDIR
vim.opt.backupdir = BACKUPDIR
vim.opt.undodir = UNDODIR
vim.opt.swapfile = true
vim.opt.backup = true
vim.opt.undofile = true

-- Append backup files with timestamp
vim.api.nvim_create_autocmd("BufWritePre", {
	callback = function()
		local extension = "~" .. vim.fn.strftime("%Y-%m-%d-%H%M%S")
		vim.o.backupext = extension
	end,
})