In my Markdown notes, I would like to:

  • Select a few lines with V
  • Encrypt those lines, externally, with :!gpg
  • Prompt for a password rather than store it, possibly with input()

I tried executing over a range, but that doesn't seem to work:

'<,'>:execute '!gpg -ca --batch --yes --passphrase "'.input('Password: ').'"'<CR>

I tried deleting the selection, running the command, and then putting the result with:

:normal '"zd' | let res = execute '!echo -e '.shellescape(@z, 1).'|gpg -ca --batch --yes --passphrase "'.input('Password: ').'" | put res<CR>

But that either says 'mark not set' or nothing seems to happen. Any help would be greatly appreciated, thanks.

1 Answer 1

  1. Making use of expression register seems preferable for this case
  2. If inside mapping then have to call inputsave() and inputrestore()
function! Pass() abort
    call inputsave()
    let p = inputsecret("password: ")
    call inputrestore()
    return p

xnoremap G :!gpg -ca --passphrase <C-R>=shellescape(Pass(), 1)<CR> --batch --yes<CR>

Upd. The custom command using execute:

command! -bar -range=% GPG execute
    \ '<line1>,<line2>!gpg -ca --batch --yes --passphrase'
    \ inputsecret("password: ")->shellescape(1)
  • Thank you, this worked perfectly. Is it possible to map this as a custom command? E.g. command! -range Encrypt ...etc...? I tried it, but it gave me a parse error.
    – Luke
    Commented May 28, 2022 at 5:44
  • 1
    @Luke I updated the answer.
    – Matt
    Commented May 28, 2022 at 9:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.