vis-gpg

edit GPG encrypted files in place with vis
git clone anongit@rnpnr.xyz:vis-gpg.git
Log | Files | Refs | Feed | README | LICENSE

init.lua (2267B)


      1 local gpg = { key = 0 }
      2 
      3 -- replacing the whole buffer clamps all selections to the start of the
      4 -- file, so remember cursor positions across the encrypt/decrypt cycle
      5 local positions = setmetatable({}, { __mode = 'k' })
      6 
      7 local function save_positions(file)
      8 	for win in vis:windows() do
      9 		if win.file == file then
     10 			positions[win] = win.selection.pos
     11 		end
     12 	end
     13 end
     14 
     15 local function restore_positions(file)
     16 	for win in vis:windows() do
     17 		if win.file == file and positions[win] ~= nil then
     18 			win.selection.pos = positions[win]
     19 			positions[win] = nil
     20 		end
     21 	end
     22 end
     23 
     24 local function splitext(file)
     25 	if file == nil then return nil, nil end
     26 	local i = file:reverse():find('%.')
     27 	if i == nil then return file, nil end
     28 	return file:sub(0, -(i + 1)), file:sub(-i)
     29 end
     30 
     31 local function errpipe(file, cmd, p)
     32 	local err, ostr, estr = vis:pipe(file, {start = 0, finish = file.size}, cmd)
     33 	if p == true and err ~= 0 and estr ~= nil then
     34 		vis:message(estr)
     35 	end
     36 
     37 	return err, ostr, estr
     38 end
     39 
     40 local function decrypt(file)
     41 	local f, e = splitext(file.name)
     42 	if e ~= '.gpg' then return end
     43 
     44 	local err, ostr, estr = errpipe(file, "gpg -d", false)
     45 	if err ~= 0 then return false end
     46 
     47 	local i = estr:find("ID")
     48 	local j = estr:find(",", i)
     49 	local keyid = estr:sub(i+3, j-1)
     50 	if keyid ~= gpg.key then
     51 		vis:info(estr:gsub("\n[ ]*", " "))
     52 		gpg.key = keyid
     53 	end
     54 
     55 	file:delete(0, file.size)
     56 	file:insert(0, ostr)
     57 	file.modified = false
     58 	restore_positions(file)
     59 	return true
     60 end
     61 vis.events.subscribe(vis.events.FILE_OPEN, decrypt)
     62 vis.events.subscribe(vis.events.FILE_SAVE_POST, decrypt)
     63 
     64 local function encrypt(file)
     65 	local f, e = splitext(file.name)
     66 	if e ~= '.gpg' then return end
     67 
     68 	if gpg.key == 0 then
     69 		vis:info('encrypt: keyid not found. file not saved.')
     70 		return false
     71 	end
     72 
     73 	save_positions(file)
     74 
     75 	local tfn = os.tmpname()
     76 	local cmd = "gpg --yes -o " .. tfn .. " -e -r " .. gpg.key
     77 	local err = errpipe(file, cmd, true)
     78 	if err ~= 0 then return false end
     79 
     80 	local tf = io.open(tfn, 'rb')
     81 	file:delete(0, file.size)
     82 	file:insert(0, tf:read("*a"))
     83 	tf:close()
     84 	os.remove(tfn)
     85 
     86 	return true
     87 end
     88 vis.events.subscribe(vis.events.FILE_SAVE_PRE, encrypt)
     89 
     90 vis:command_register("gpg-key", function()
     91 	vis:info("gpg-key: " .. gpg.key)
     92 end, "Echo the currently set key ID")
     93 
     94 return gpg