Skip to content

Latest commit

 

History

36 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gpg.nvim

Editing GPG encrypted files symmetrically in NeoVIM

Demo

Install

Manually

Copy plugin/gpg.lua file to your ~/.config/nvim/lua/plugins/ directory

Using

-- ~/.config/nvim/lua/plugins/gpg.lua
{
   "benoror/gpg.nvim",
   ft = { "gpg", "asc", "pgp" },
}

vim.pack

-- ~/.config/nvim/init.lua
vim.pack.add({
   { "https://github.com/benoror/gpg.nvim" },
})

Config

Customize file extensions

vim.filetype.add({
	extension = {
		gpg = "gpg",
		asc = "asc",
	},
})

return {
	"benoror/gpg.nvim",
	ft = { "gpg", "asc", "pgp" },
}

Vía @Frestein Frestein/dotfiles/dot_config/nvim/lua/plugins/extras/utils/gpg.lua

Requirements

  • gpg (GnuPG 2.1+ recommended for loopback pinentry)
  • Optional: GUI pinentry (only needed if you disable loopback)

Usage

All *.gpg files will be decrypted/encrypted transparently using gpg tools (--default-recipient-self / asymmetric encrypt on write).

Encrypting / decrypting a visual selection

This plugin intentionally stays focused on transparent whole-file editing for *.gpg (and similar) buffers. Inline encrypt/decrypt of a visual selection — including picking recipients from your keyring — is left to Neovim's built-in external filter (:!) and gpg, so the plugin remains small and agnostic.

Select text in visual mode, then:

" Encrypt to yourself (ASCII-armored)
:'<,'>!gpg -ae --default-recipient-self

" Encrypt to a specific recipient
:'<,'>!gpg -ae -r alice@example.com

" Decrypt an armored PGP block
:'<,'>!gpg -qd

Optional keymaps:

vim.keymap.set("v", "<leader>ge", ":!gpg -ae --default-recipient-self<CR>", {
  desc = "GPG encrypt selection",
})
vim.keymap.set("v", "<leader>gd", ":!gpg -qd<CR>", {
  desc = "GPG decrypt selection",
})

For a recipient picker, list keys with gpg --list-keys, choose with vim.ui.select / Telescope / fzf-lua, then run the same filter with one or more -r flags. That UI is config-local and out of scope for this plugin.

Passphrase prompting (default)

By default, decrypt uses --pinentry-mode loopback so Neovim owns the passphrase prompt via inputsecret() when the agent does not already have the key cached. This avoids pinentry-curses TTY contention (dropped key presses) inside Neovim — see issue #8 and docs/pinentry.md for the assessment, exact probe argv, pros/cons, and alternatives.

The first decrypt is a probe (ciphertext on stdin). It is not supposed to prompt. If the agent lacks a passphrase, GnuPG should print gpg: Sorry, we are in batchmode - can't get input and exit; the plugin then prompts inside Neovim and retries with --passphrase-fd. A hang after that line means gpg did not exit (often GnuPG use-keyboxd / agent IPC — issue #20), not a missing plugin prompt.

The probe wait has a safety timeout so a wedged gpg cannot freeze Neovim forever (vim.g.gpg_probe_timeout, default 30000 ms; false or 0 waits indefinitely).

Loopback is on by default. To restore the legacy external pinentry path:

vim.g.gpg_pinentry_loopback = false

Legacy GPG agent TTY handling

These opt-in knobs are legacy mitigations for the external pinentry path. Prefer the default loopback behavior above.

Update the GPG agent startup TTY (equivalent to gpg-connect-agent updatestartuptty /bye):

vim.g.gpg_update_tty = true

Optional "priming" step that runs gpg --list-packets before decrypting so the passphrase may be cached by the agent:

vim.g.gpg_prime_agent = true

Testing

Local smoke tests (headless Neovim, temp keyring):

make test-bash
make test-zsh
make test-nu

Plugin manager compatibility checks:

make test-lazy
make test-packer

Notes:

  • The tests create a temporary GNUPGHOME and a throwaway key, so your user keyring is not touched.
  • The tests also set isolated XDG_* paths and NVIM_APPNAME to a temp directory to avoid writing artifacts into your normal Neovim runtime.
  • tests/init_lazy.lua and tests/init_packer.lua will clone their managers if missing (network required).

Credits

Based off

Inspired by

https://github.com/jamessan/vim-gnupg

Further reading

Releases

Packages

Contributors

Languages