shaunvxc / envy

:memo: safely make edits and sync local changes to files living in the site-packages of your virtualenvs
MIT License
39 stars 3 forks source link

envy edit vim issues #4

Open shaunvxc opened 8 years ago

shaunvxc commented 8 years ago

vim does not want to play nicely when launched from an envy edit call using python's subprocess module. Currently, if $EDITOR is set to be vim, it will launch, but in a frozen state.

Not quite sure if there is a workaround for this yet (I see others having similar issues on stackoverflow).

vi works just fine, so in the meantime (see 06c4392408222ed611073e31e02ee872ccda5f38, and as of 0.0.8), envy edit will default to vi if :

  1. $EDITOR is not set.
  2. $EDITOR is set to be vim

While it does feel a little strange to both rely on $EDITOR but ignore it in a specific case (ie vim), the logic is that envy edit is not useful AT ALL if $EDITOR is set to vim. (vi should be available on most systems..)

Any suggestions as to how to better work around (or solve!) this issue would be greatly appreciated!

mwhooker commented 8 years ago

It sounds like you might want to use exec https://en.wikipedia.org/wiki/Exec_(system_call)

https://docs.python.org/2/library/os.html#os.execl

something like

import os

os.execl("/usr/local/bin/vim", "--", "/tmp/editme")
shaunvxc commented 8 years ago

This seems to work. However, many have mentioned to be that it is bad practice to use os.system()-- I'm wondering if the same sort of thing applies to os.execl()?

Using this approach would require users to specify the full path to the executable when exporting $EDITOR (EDITOR=/usr/local/bin/vim vs. EDITOR=vim). Not sure whether or not that is something I should worry about.

Thank you very much though-- I will certainly consider this to fix my issue.

vodik commented 8 years ago

Couple things to note:

args = ["/usr/local/bin/vim", "--", "/tmp/editme"]
os.execl(args[0], *args)

But there's technically no need for argv[0] and the binary to match. Most programs just happen not to care about what's in argv[0]. argv[0] is what shows up in the process tree, so in your case above, you'd see vim labelled as "--".

$ pgrep -a vim
3002 --

Now if you look at subprocess's source (https://github.com/python/cpython/blob/2.7/Lib/subprocess.py) you can see how it does things. It basically wraps forking, exec (it uses os.execvp in particular), and waiting (os.waitpid) - while also wrapping up error handling, so forth. So there should be no reason why using the lowlevel stuff directly vs subprocess should make a difference.

Continuing on from my previous comments (I'm OCCASIONAL_CATNAPPER on reddit), I'd suspect maybe you have two copies of vim, on in /usr/bin/local and one elsewhere and maybe that's the difference for why os.execl worked.

shaunvxc commented 8 years ago

Thanks so much for taking the time to write up such a helpful response! os.execlp() does the trick, I will update the code to use this instead of subprocess.

As far as why subprocess doesn't work for me-- I still can't tell. I'll play around with it a bit more.

I'm fairly certain I only have one vim installation-- the only one I can find lives in /usr/bin. One thing to clarify-- launching vim from subprocess was never the issue-- it would just be launched in a frozen state (apologies if you were already aware of this).

Anyways, thanks again!

vodik commented 8 years ago

One last thing actually, try attach strace to the stuck vim process and see what its hanging on. It'll tell you which syscall its stuck on, which can be useful in figuring out exactly whats broken.