From 1b3f24e5c0981c1de02ff86b25f6b8ed54880374 Mon Sep 17 00:00:00 2001 From: Reuben Martin Date: Fri, 10 Jul 2026 15:16:43 -0500 Subject: [PATCH] fix(toggle): modified buffer Allow toggle on modified buffer to re-encrypt it without need of syncing the buffer to dish first. Without this patch, trying to do so throws an error. --- lua/sops/api.lua | 19 +++++++++++++++++-- lua/sops/sops.lua | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/lua/sops/api.lua b/lua/sops/api.lua index 04a9c74..f60231a 100644 --- a/lua/sops/api.lua +++ b/lua/sops/api.lua @@ -84,8 +84,23 @@ function M.close() return end local bufnr = fn.bufnr() - cmd.edit { args = { get_file_name():sub(8) } } - cmd.bwipeout { count = bufnr } + local file_name = get_file_name():sub(8) + + if not vim.bo.modified then + cmd.edit { args = { file_name } } + cmd.bwipeout { count = bufnr } + return + end + + sops.read_buffer_as_encrypted_file(file_name, bufnr, function(contents, code) + vim.bo[bufnr].modified = false + cmd.edit { bang = true, args = { file_name } } + api.nvim_buf_set_lines(fn.bufnr(), 0, -1, false, contents) + if code ~= 200 then + vim.bo.modified = true + end + cmd.bwipeout { bang = true, count = bufnr } + end) end function M.toggle() diff --git a/lua/sops/sops.lua b/lua/sops/sops.lua index 862d83f..fc7ebdf 100644 --- a/lua/sops/sops.lua +++ b/lua/sops/sops.lua @@ -1,8 +1,19 @@ local config = require 'sops.config' local notify = require 'sops.notify' +local utils = require 'sops.utils' local M = {} +local function get_editor_path() + local Path = require 'plenary.path' + return Path:new(utils.get_script_path()):joinpath('../../editor.lua'):absolute() +end + +local function get_temp_file(file) + local extension = file:match('(%.[^./\\]+)$') or '' + return vim.fn.tempname() .. extension +end + local function build_env(...) local env = {} local os_env = vim.loop.os_environ() @@ -121,4 +132,37 @@ function M.read_encrypted_file(file, on_success, on_error) return job end +function M.read_buffer_as_encrypted_file(file, bufnr, on_success, on_error) + local temp_file = get_temp_file(file) + local editor = get_editor_path() + + local copy_success, copy_error = vim.loop.fs_copyfile(file, temp_file) + if not copy_success then + notify.error('SOPS: Unable to copy encrypted file: ' .. vim.inspect(copy_error)) + return nil + end + + local job = M.call_sops { + args = { temp_file }, + env = { + EDITOR = vim.v.progpath .. ' -l ' .. editor, + SOPS_NVIM_SOCKET = vim.v.servername, + SOPS_NVIM_BUFNR = bufnr, + }, + success_codes = { 0, 200 }, + on_success = function(ctx) + local encrypted_content = vim.fn.readfile(temp_file) + vim.fn.delete(temp_file) + on_success(encrypted_content, ctx.code) + end, + on_error = function(ctx) + vim.fn.delete(temp_file) + if on_error then + on_error(ctx.stderr) + end + end, + } + return job +end + return M