feat: nvim improvement on opening encrypted files

This commit is contained in:
Ray Andrew 2025-12-09 11:45:09 -06:00
parent d9b8015e4f
commit 8e9f2496c7
Signed by: rayandrew
SSH key fingerprint: SHA256:XYrYrxF0Z3A72n8P/p6mqPRNQZT22F88XcLsG+kX4xw
10 changed files with 123 additions and 7 deletions

View file

@ -3,6 +3,12 @@ keys:
- &lemur age1pdk6dmyxqhdaja5d0nf8f9qjd43hmfahmkure5yrf8al9jyfmd8qfdxwl6
- &dango age15vscvpe79l287h8f3hssrj2r45xy0l3ns94zfue2fxlq43cqdsxq58vq3c
creation_rules:
- path_regex: secrets/.*\.enc$
key_groups:
- age:
- *pickwick
- *lemur
- *dango
- path_regex: secrets/wb\.txt$
key_groups:
- age:

View file

@ -6,6 +6,9 @@
[gpg]
format = ssh
[gpg "ssh"]
allowedSignersFile = ~/.ssh/allowed_signers
[core]
editor = nvim

View file

@ -1,3 +1,5 @@
.DS_Store
*~
*.swp
**/.claude/settings.local.json

View file

@ -60,6 +60,7 @@ add 'OXY2DEV/markview.nvim'
add { source = 'R-nvim/R.nvim', depends = { 'nvim-treesitter/nvim-treesitter' } }
add 'nvim-treesitter/nvim-treesitter'
add 'nvim-treesitter/nvim-treesitter-textobjects'
add { source = 'nvim-pack/nvim-spectre', depends = { 'nvim-lua/plenary.nvim' } }
-- color themes
add 'EdenEast/nightfox.nvim'
@ -755,6 +756,101 @@ map('t', '<C-q>', '<C-\\><C-n>', 'Unfocus terminal and return to editor')
-- Auto commands
-- SOPS encrypted files (.enc) - decrypt on read, encrypt on save
vim.api.nvim_create_autocmd('BufReadCmd', {
pattern = '*.enc',
callback = function(ev)
local file = vim.fn.expand '%:p'
-- Decrypt with sops
local result = vim.fn.systemlist('sops -d ' .. vim.fn.shellescape(file) .. ' 2>/dev/null')
if vim.v.shell_error ~= 0 then
vim.notify('SOPS decryption failed: ' .. table.concat(result, '\n'), vim.log.levels.ERROR)
return
end
-- Set buffer content
vim.api.nvim_buf_set_lines(ev.buf, 0, -1, false, result)
-- Detect filetype from content
local first_line = result[1] or ''
if first_line:match '^{' then
vim.bo[ev.buf].filetype = 'json'
vim.b[ev.buf].sops_input_type = 'json'
elseif first_line:match '^%-%-%-' or first_line:match '^%w+:' then
vim.bo[ev.buf].filetype = 'yaml'
vim.b[ev.buf].sops_input_type = 'yaml'
elseif first_line:match '^%[' then
vim.bo[ev.buf].filetype = 'dosini'
vim.b[ev.buf].sops_input_type = 'ini'
else
-- Plain text or unknown - use binary mode (sops wraps in {"data": "..."})
vim.bo[ev.buf].filetype = 'text'
vim.b[ev.buf].sops_input_type = 'binary'
end
-- Store original file path and mark as not modified
vim.b[ev.buf].sops_file = file
vim.bo[ev.buf].modified = false
vim.bo[ev.buf].buftype = 'acwrite' -- enable BufWriteCmd
end,
})
vim.api.nvim_create_autocmd('BufWriteCmd', {
pattern = '*.enc',
callback = function(ev)
local file = vim.b[ev.buf].sops_file or vim.fn.expand '%:p'
local tmpfile = vim.fn.tempname()
local input_type = vim.b[ev.buf].sops_input_type or 'binary'
-- Find .sops.yaml config by walking up from the file's directory
local function find_sops_config(start_dir)
local dir = start_dir
while dir ~= '/' do
local config = dir .. '/.sops.yaml'
if vim.fn.filereadable(config) == 1 then return config end
dir = vim.fn.fnamemodify(dir, ':h')
end
return nil
end
local sops_config = find_sops_config(vim.fn.fnamemodify(file, ':h'))
-- Write current buffer to temp file
vim.cmd('silent write! ' .. tmpfile)
-- Encrypt with sops (use config if found, and override filename for path matching)
local config_arg = sops_config and ('SOPS_CONFIG=' .. vim.fn.shellescape(sops_config) .. ' ') or ''
local cmd = string.format(
'%ssops -e --input-type %s --output-type json --filename-override %s %s > %s',
config_arg,
input_type,
vim.fn.shellescape(file),
vim.fn.shellescape(tmpfile),
vim.fn.shellescape(file)
)
local result = vim.fn.system(cmd)
vim.fn.delete(tmpfile)
if vim.v.shell_error ~= 0 then
vim.notify('SOPS encryption failed: ' .. result, vim.log.levels.ERROR)
return
end
vim.bo[ev.buf].modified = false
vim.notify('Saved: ' .. file, vim.log.levels.INFO)
end,
})
-- Command to manually open a file with sops (for non-.enc files)
vim.api.nvim_create_user_command('Sops', function(opts)
local file = opts.args ~= '' and opts.args or vim.fn.expand '%:p'
vim.cmd('terminal sops ' .. vim.fn.shellescape(file))
vim.cmd 'startinsert'
end, { nargs = '?', complete = 'file', desc = 'Edit file with sops' })
vim.api.nvim_create_autocmd('QuickFixCmdPost', {
callback = function()
vim.cmd 'redraw!'

View file

@ -60,6 +60,9 @@ end
---@param opts? MailCountConfig
function M.setup(opts)
-- Skip setup if notmuch is not available
if vim.fn.executable 'notmuch' ~= 1 then return end
config = vim.tbl_deep_extend('force', config, opts or {})
-- Initialize counts

View file

@ -4,7 +4,6 @@
inputs,
lib,
pkgs,
self,
user,
dots,
system,
@ -73,6 +72,7 @@
"https://rayandrew.cachix.org"
"https://devenv.cachix.org"
"https://yazi.cachix.org"
"https://rslib.cachix.org"
];
# allow building and pushing of laptop config from desktop
trusted-users = [ user ];
@ -82,6 +82,7 @@
"rayandrew.cachix.org-1:kJnvdWgUyErPGaQWgh/yyu91szgRYD+V/WQ4Dbc4n9M="
"devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw="
"yazi.cachix.org-1:Dcdz63NZKfvUCbDGngQDAZq6kOroIrFoyO064uvLh8k="
"rslib.cachix.org-1:8OHneG2sLeTDlsZ4AZyNh8zx2zAwoiZUKVPnl21B+58="
];
};
# // lib.optionalAttrs (config.nix.package.pname == "lix") {

View file

@ -6,6 +6,7 @@
}:
{
home.packages = with pkgs; [
git
gh
git-lfs
];

View file

@ -72,6 +72,8 @@
spotify-player
eza
bat
man-pages-posix
man-pages
]
++ lib.optionals pkgs.stdenv.isDarwin [ coreutils ]
++ (lib.attrValues config.custom.shell.packages);

View file

@ -87,6 +87,7 @@
"https://rayandrew.cachix.org"
"https://devenv.cachix.org"
"https://yazi.cachix.org"
"https://rslib.cachix.org"
];
# allow building and pushing of laptop config from desktop
trusted-users = [ user ];
@ -96,6 +97,7 @@
"rayandrew.cachix.org-1:kJnvdWgUyErPGaQWgh/yyu91szgRYD+V/WQ4Dbc4n9M="
"devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw="
"yazi.cachix.org-1:Dcdz63NZKfvUCbDGngQDAZq6kOroIrFoyO064uvLh8k="
"rslib.cachix.org-1:8OHneG2sLeTDlsZ4AZyNh8zx2zAwoiZUKVPnl21B+58="
];
};
# // lib.optionalAttrs (config.nix.package.pname == "lix") {

File diff suppressed because one or more lines are too long