From 6935fbea8b7f4e36049e61956aea69bb5d6dafee Mon Sep 17 00:00:00 2001 From: Dominik Polakovics Date: Fri, 28 Nov 2025 01:32:23 +0100 Subject: [PATCH] fix: sops implementation --- .../modules/development/nvim/config/sops.lua | 81 ++++++++++--------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/hosts/nb/modules/development/nvim/config/sops.lua b/hosts/nb/modules/development/nvim/config/sops.lua index e35d153..4a17e8a 100644 --- a/hosts/nb/modules/development/nvim/config/sops.lua +++ b/hosts/nb/modules/development/nvim/config/sops.lua @@ -44,7 +44,7 @@ vim.api.nvim_create_autocmd("BufReadPre", { pattern = secrets_patterns, callback = function(args) -- Set filetype to yaml before the file is read so syntax highlighting works - vim.bo.filetype = "yaml" + vim.bo[args.buf].filetype = "yaml" end, }) @@ -98,26 +98,26 @@ vim.api.nvim_create_autocmd("BufReadPost", { return end + -- Detach LSP clients BEFORE replacing buffer to prevent sync errors + detach_lsp_clients(args.buf) + -- Replace buffer content with decrypted content - vim.api.nvim_buf_set_lines(0, 0, -1, false, vim.split(result, "\n")) + vim.api.nvim_buf_set_lines(args.buf, 0, -1, false, vim.split(result, "\n")) -- Mark buffer as not modified (since we just loaded it) - vim.bo.modified = false + vim.bo[args.buf].modified = false -- Restore cursor position pcall(vim.api.nvim_win_set_cursor, 0, cursor_pos) -- Disable swap, backup, and undo files for security - vim.bo.swapfile = false - vim.bo.backup = false - vim.bo.writebackup = false - vim.bo.undofile = false + vim.bo[args.buf].swapfile = false + vim.bo[args.buf].backup = false + vim.bo[args.buf].writebackup = false + vim.bo[args.buf].undofile = false -- Ensure filetype is set to yaml for syntax highlighting - vim.bo.filetype = "yaml" - - -- Detach LSP clients to prevent sync errors when buffer content is replaced - detach_lsp_clients(0) + vim.bo[args.buf].filetype = "yaml" vim.notify("SOPS: File decrypted successfully", vim.log.levels.INFO) else @@ -132,17 +132,22 @@ vim.api.nvim_create_autocmd("BufWriteCmd", { group = sops_group, pattern = secrets_patterns, callback = function(args) - local filepath = vim.fn.expand("%:p") + local filepath = vim.api.nvim_buf_get_name(args.buf) - if is_secrets_file(filepath) then - -- Guard against double-execution - if currently_saving[filepath] then - return - end - currently_saving[filepath] = true + if not is_secrets_file(filepath) then + return + end + -- Guard against double-execution + if currently_saving[filepath] then + return + end + currently_saving[filepath] = true + + -- Use pcall to ensure guard is always cleared, even on unexpected errors + local ok, err = pcall(function() -- Get current buffer content - local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) + local lines = vim.api.nvim_buf_get_lines(args.buf, 0, -1, false) local content = table.concat(lines, "\n") -- Check buffer content size before encrypting @@ -153,8 +158,6 @@ vim.api.nvim_create_autocmd("BufWriteCmd", { string.format("SOPS: Buffer content too large (%sMB > %sMB limit). Cannot encrypt.", size_mb, limit_mb), vim.log.levels.ERROR ) - -- Don't write anything, leave buffer marked as modified - currently_saving[filepath] = nil return end @@ -168,8 +171,6 @@ vim.api.nvim_create_autocmd("BufWriteCmd", { local temp_f, temp_err = io.open(temp_file, "w") if not temp_f then vim.notify("SOPS: Failed to create temp file: " .. (temp_err or "unknown error"), vim.log.levels.ERROR) - -- Don't write anything, leave buffer marked as modified - currently_saving[filepath] = nil return end temp_f:write(content) @@ -188,14 +189,14 @@ vim.api.nvim_create_autocmd("BufWriteCmd", { if sops_exit_code == 0 then -- Write encrypted content directly to file - local file, err = io.open(filepath, "w") + local file, file_err = io.open(filepath, "w") if file then local success, write_err = file:write(encrypted) file:close() if success then -- Mark buffer as saved - vim.bo.modified = false + vim.bo[args.buf].modified = false vim.notify("SOPS: File encrypted and saved successfully", vim.log.levels.INFO) -- Re-decrypt to show plaintext in buffer @@ -207,37 +208,37 @@ vim.api.nvim_create_autocmd("BufWriteCmd", { -- Save cursor position local cursor_pos = vim.api.nvim_win_get_cursor(0) + -- Detach LSP clients BEFORE replacing buffer to prevent sync errors + detach_lsp_clients(args.buf) + -- Replace buffer with decrypted content - vim.api.nvim_buf_set_lines(0, 0, -1, false, vim.split(decrypted, "\n")) + vim.api.nvim_buf_set_lines(args.buf, 0, -1, false, vim.split(decrypted, "\n")) -- Mark as not modified since we just saved - vim.bo.modified = false + vim.bo[args.buf].modified = false -- Restore cursor position pcall(vim.api.nvim_win_set_cursor, 0, cursor_pos) - - -- Detach LSP clients to prevent sync errors when buffer content is replaced - detach_lsp_clients(0) else vim.notify("SOPS: Could not re-decrypt after save. Buffer may show encrypted content.", vim.log.levels.WARN) end - -- Clear guard after successful save - currently_saving[filepath] = nil else vim.notify("SOPS: Failed to write encrypted content: " .. (write_err or "unknown error"), vim.log.levels.ERROR) - -- Don't mark as saved, keep buffer marked as modified - currently_saving[filepath] = nil end else - vim.notify("SOPS: Failed to open file for writing: " .. (err or "unknown error"), vim.log.levels.ERROR) - -- Don't mark as saved, keep buffer marked as modified - currently_saving[filepath] = nil + vim.notify("SOPS: Failed to open file for writing: " .. (file_err or "unknown error"), vim.log.levels.ERROR) end else vim.notify("SOPS: Failed to encrypt file - NOT SAVED! Error: " .. encrypted, vim.log.levels.ERROR) - -- Don't write anything, leave buffer marked as modified - currently_saving[filepath] = nil end + end) + + -- Always clear guard, even if pcall caught an error + currently_saving[filepath] = nil + + -- Re-throw unexpected errors so they're visible + if not ok then + vim.notify("SOPS: Unexpected error during save: " .. tostring(err), vim.log.levels.ERROR) end end, }) @@ -247,7 +248,7 @@ vim.api.nvim_create_autocmd("BufLeave", { group = sops_group, pattern = secrets_patterns, callback = function(args) - if vim.bo.modified then + if vim.bo[args.buf].modified then vim.notify("Warning: Unsaved changes in secrets file!", vim.log.levels.WARN) end end,