jamessan / vim-gnupg

This script implements transparent editing of gpg encrypted files.
http://www.vim.org/scripts/script.php?script_id=3645
724 stars 72 forks source link

Unable to save a file after changing directory due to buftype=acwrite #81

Closed haadr closed 6 years ago

haadr commented 7 years ago

Hi,

I've had this on two machines. When I want to edit a .gpg file (created with vim-gnupg), and I run the command gvim file.gpg from the terminal (konsole in my case), I can :w and :update the file. When I start gvim from my DE (kde), then open the .gpg file using :e path/to/file.gpg, it doesn't work. Nothing happens at all, no error messages are printed within gvim. Stranger still, writing :wq doesn't quit, and doesn't print any warnings about not being able to exit due to unwritten changes, simply nothing happens. If I run :q only, it gives me the "E37: No write since last change" etc.

The log that seems relevant which I get by enabling g:GPGDebugLevel=3 and specifying a logfile, with the file encrypted to user named "Test User" and file is test.gpg:

GnuPG: rc: 0
GnuPG: >>>>>>>> Entering s:GPGInit(0)
GnuPG: >>>>>>>> Entering s:GPGEncrypt()
GnuPG: called BufWritePre autocommand for temp_classy/test
GnuPG: >>>>>>>> Entering s:GPGCheckRecipients()
GnuPG: >>>>>>>> Entering s:GPGNameToID()
GnuPG: command: gpg --trust-model always --no-tty --use-agent --quiet --with-colons --fixed-list-mode --list-keys 'F0397571B29CF881' 2>/dev/null
GnuPG: rc: 0
GnuPG: output: tru:ot:1:1480873261:1:3:1:5^@pub:-:2048:1:F0397571B29CF881:1496698348:1559770348::u:::scESC:::::::^@fpr:::::::::3949A65A31D0AC461FD03DAEF0397571B29CF881:^@uid:-::::1496698348::81C4974C00DFA1C8AB6CC70E50D513BF8A61B81C::Test Name <test@test.com>:^@sub:-:2048:1:C9F4EBE0CEFD5EAC:1496698348:1559770348:::::e::::::^@fpr:::::::::0493ED77FCB49B66F545F1FAC9F4EBE0CEFD5EAC:^@
GnuPG: <<<<<<<< Leaving s:GPGNameToID()
GnuPG: recipients are: ['F0397571B29CF881']
GnuPG: unknown recipients are: []
GnuPG: <<<<<<<< Leaving s:GPGCheckRecipients()
GnuPG: command: '[,']write !gpg --trust-model always --no-tty --use-agent --quiet --no-encrypt-to  --encrypt  -r F0397571B29CF881 >'/tmp/v4SF11O/20' 2>/dev/null

Edit: It seems that starting gvim from the terminal or not isn't the deciding factor, but whether the working directory of vim is the same as for the file being written to. When I do e: path/to/file.gpg it doesn't work, when I first do :cd path/to/ and then e: file.gpg, it works.

jamessan commented 7 years ago

When you do :e path/to/file.gpg, is it an absolute path or a relative path? If it's relative, are you sure gvim's current directory is what you expect it to be? It sounds like maybe path/to/file.gpg is non-existent so gvim just creates an empty buffer.

haadr commented 7 years ago

It's a relative path. The problem isn't that the file cannot be found, since the file is opened, decrypted and displayed correctly (ie. reading the encrypted file works fine, asks for my keyring password etc). The problem is that after the file has been opened and decrypted, I cannot write to it.

So, the decrypting/opening works fine, but writing to the file only works if I cd to the file's directory first, and then open it.

On 10. juni 2017 01:17, James McCoy wrote:

When you do |:e path/to/file.gpg|, is it an absolute path or a relative path? If it's relative, are you sure gvim's current directory is what you expect it to be? It sounds like maybe |path/to/file.gpg| is non-existent so gvim just creates an empty buffer.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jamessan/vim-gnupg/issues/81#issuecomment-307522472, or mute the thread https://github.com/notifications/unsubscribe-auth/APgEdk6TXZu2WV4uFq0rvoQiup1z8sK-ks5sCdKMgaJpZM4NwrjL.

kmac commented 6 years ago

I can confirm this. I think it's related to 'autochdir'.

I have 'set autochdir' in my .vimrc. I can't write to a file unless it is opened in the same current directory. If I turn off autochdir then it works in both cases.

(There is a warning in the documentation for autochdir that it may break plugins)

jamessan commented 6 years ago

I can confirm this. I think it's related to 'autochdir'.

Ah ha! Thanks for the tip. With that, I can easily reproduce the behavior.

I'm looking into it. I'm not sure yet whether it's a bug in the plugin or in vim, but I'm leaning towards vim at this point. If so, I'll look report it upstream (hopefully with a patch).

jamessan commented 6 years ago

There are a couple things at play here.

  1. When buftype=acwrite, as it is for this plugin, Vim intentionally doesn't update the buffer name when the directory changes.
    1. This means that the buffer's associated filename will be wrong if the working directory is different than the buffer's parent directory.
  2. Code invoked for the BufWriteCmd event has no way to know whether the user is using :w, :w somefile, or :saveas somefile.

In order to address 1, my first thought was to cache the fully-resolved path to the file upon first reading it (before setting buftype=acwrite). However, due to 2 I can't tell if I should re-use the cached path of if I should be trying to use the path provided to BufWriteCmd.

An alternative would be to require using names like gpg://... as the filename to indicate that the plugin should handle reading/writing the buffer. This would be an incompatible change, but would be more in line with how Vim expects buftype=acwrite to be used.

In Neovim, I could possibly work around 1 by also setting up DirChanged event handlers so that I can manually update the buffer's filename. That would likely also make it so that 2 doesn't matter, since the buffer's filename would always be accurate with respect to the working directory.

I'm leaning towards the gpg://... solution, which means this won't get fixed right away. I'll probably bundle that in with the release that implements Neovim supports, since both changes are going to require a bit of rework and both are also, to an extent, incompatible with portions of the current way the plugin works.

jamessan commented 6 years ago

Of course, after all that, simply setting the buffer's name to an absolute path seems to solve the issue.

arturog commented 6 years ago

Since this commit went through, I get an error

Messages maintainer: Mike Williams <mrw@eandem.co.uk>
Error detected while processing function <SNR>68_GPGDecrypt:
line  161:
E172: Only one file name allowed: file /home/user/Documents/Important Security Stuff/myfile.pgp

I believe it's the spaces in the directory name. Moving the same file to a path that doesn't have spaces work as expected.

Edit: Fixed with #84