christoomey / vim-tmux-navigator

Seamless navigation between tmux panes and vim splits
MIT License
5.2k stars 320 forks source link

is_vim Doesn't Work In Subshell #195

Open kwrobert opened 6 years ago

kwrobert commented 6 years ago

Hello!

I have discovered that the is_vim tmux command in the config snippet from the README, which is designed to determine whether or not the current pane is running vim, does not work when vim is opened within a subshell.

I discovered this because I use a tool called hatch to manage my virtual environments when working with python. That tool uses subshells to drop you into a virtual environment, and whenever I am inside a virtual environment and use vim, the :TmuxPaneCurrentCommand reports "python3" as the current command. This means none of the keybindings get sent to VIM.

Not a huge deal for me, I just open vim outside my virtual environments now and everything works, but I thought I would submit this issue in case anyone runs into the same issue and knows how to/has the motivation to fix this.

christoomey commented 6 years ago

@kwrobert can you confirm that you're using the current command, specifically:

is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"

Likewise, can you run the following and share the output:

ps -o state= -o comm= -t $(tmux display-message -t 1 -p '#{pane_tty}')

Note the above command assumes you're interacting with a shell in pane 0, and have Vim open in pane 1.

kwrobert commented 6 years ago

Confirmed I am using the the current is_vim command.

The output of the second command if I have a plain zsh shell in pane 0 and vim open in pane 1, and execute the command in pane 0.

S zsh
S vim

Now, if I exit vim, drop into a subshell/virtualenv, then reopen vim and re-execute the command in pane 0, here is the output I get

S zsh
S hatch

So this seems to be the problem. I ran ps auxf to get a sense of the parent/child relationship between processes and pasted the relevant results below:

me     12534  0.1  0.0  60772  9788 pts/3    Ss   21:01   0:00  \_ /usr/bin/zsh
me     21067  0.0  0.0  37760  3700 pts/3    R+   21:10   0:00  |   \_ ps auxf 16188
me     12756  0.0  0.0  57308  8280 pts/2    Ss   21:01   0:00  \_ /usr/bin/zsh
me     16188  0.0  0.1  72980 20252 pts/2    S+   21:05   0:00      \_ /usr/bin/python3 /home/me/.local/bin/hatch shell nanowire
me     16193  0.0  0.0  57312  8228 pts/4    Ss   21:05   0:00          \_ /usr/bin/zsh -i
me     17304  0.1  0.2 366912 41224 pts/4    Sl+  21:06   0:00              \_ vim
me    17311  0.0  0.2 2497512 39748 ?       Ssl  21:06   0:00                  \_ /usr/bin/python /home/me/.vim/plugged/YouCompleteMe/python/ycm/../../third_party/ycmd/ycmd --port=54815 --options_file=/tmp/tmp8shv6m8d --log=info --idle_suicide_seconds=1800 --stdout=/tmp/ycmd_54815_stdout_pshlvxgy.log --stderr=/tmp/ycmd_54815_stderr_ie6lplp0.log

I hope that is helpful. It seems the is_vim command only checks the first child of the parent process (parent process = zsh, PID = 12756) running in pane 1, and finds the child is hatch/python3 which is not what we want. I'm not sure if there is a way to traverse the tree (or if that is even a wise thing to do), but that seems to be the trouble here.

mike-hearn commented 6 years ago

I believe this is also related to this issue with pipenv, where the vim split switching doesn't work when inside the pipenv shell.

One user in that thread had a solution for Linux (https://github.com/pypa/pipenv/issues/1407#issuecomment-368864956).

blueyed commented 6 years ago

Based on the workaround by @robbieclarken in https://github.com/pypa/pipenv/issues/1407#issuecomment-368864956, I think we could use a script/loop that would use ps -o state= -o pid= -t … initially, and ps -o state= -o pid= --ppid` then recursively.

~~OTOH the main issue appears to be e.g. pipenv creating a new pty (via pexpect), and it looks like using T (for the current tty / associated with ps) instead of -t … might work. Does ps T work on MacOS? If not, does ps t '' work there?~~ Scratch that: the if-shell command (i.e. ps) is not run in the "current" pty, but rather (I assume) by the tmux server.

blueyed commented 6 years ago

btw: :TmuxPaneCurrentCommand is different from $is_vim (#197).

sjoegren commented 6 years ago

I had this issue too, using pipenv that launches a subshell. I created a workaround script, something like @blueyed suggested. I've tested it on Ubuntu 16.04, tmux 2.6, vim 8.0. I'm not sure if it works with other shells than bash.

Create a script in your PATH called vim-tmux-navigator-is-vim.sh and make it executable (chmod +x ...): Link to vim-tmux-navigator-is-vim.sh

In tmux.conf, change this:

is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"

to:

is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$' \
    || vim-tmux-navigator-is-vim.sh #{pane_tty}"

Now the C-h, C-k etc commands should work inside Vim windows running in subshells too.

blueyed commented 6 years ago

https://github.com/christoomey/vim-tmux-navigator/pull/201 solves this.

marcomayer commented 4 years ago

201 solves this.

I just stumbled over this. Are you sure #201 solves this? How is it related to the is_vim function (which is configured in tmux.conf)?

blueyed commented 4 years ago

@marcomayer It uses another mechanism.

marcomayer commented 4 years ago

@blueyed Ah sorry, my fault. I just had looked at master assuming this would be merged by now. I'll play around with your version and see if that helps fix my pipenv/tmux/vim issue ;)

blueyed commented 4 years ago

@marcomayer Ok. For what it's worth, I would recommend to not use it (this plugin) at all - while it seems convenient in the beginning it has its benefits to not mix Vim windows / tmux panes.

marcomayer commented 4 years ago

@blueyed yea if I'd have known how much time I'd spend to get this working in the beginning I'd surely have stopped. It's quite a mess. But now at least it looks like it's working okay thanks to your code. But I don't use the whole plugin, only parts of it trying to keep it simple.

Btw on native vim, for me, this works for the suspend part: nnoremap <silent> <C-z> :RemoveIndicator<CR>:suspend<bar>:SetupIndicator<CR>

danielo515 commented 2 years ago

Hello, sorry for commenting in an old thread, but after of months with the is_vim function working properly it stopped working suddenly. Not sure if it is because an update to zsh or if it is something else, but any help is greatly appreciated. The provided command of ps -o state= -o comm= -t $(tmux display-message -t 1 -p '#{pane_tty}') always returns Ss+ /bin/zsh (figterm)

blueyed commented 2 years ago

@danielo515 tmux was updated recently, which might be related. I've not investigated, and am not using this project/mechanism anymore: I find it more convenient to explicitly move between tmux panes and (Neo)Vim windows.

danielo515 commented 2 years ago

That's a shame, because it can be very convenient to have this kind of integration. Do you know in which version of tmux this broke? I am not sure which version to use

On Thu, Jun 23, 2022 at 6:13 PM Daniel Hahler @.***> wrote:

@danielo515 https://github.com/danielo515 tmux was updated recently, which might be related. I've not investigated, and am not using this project/mechanism anymore: I find it more convenient to explicitly move between tmux panes and (Neo)Vim windows.

— Reply to this email directly, view it on GitHub https://github.com/christoomey/vim-tmux-navigator/issues/195#issuecomment-1164610145, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARKJWITBE5XSVNKXSWAUH3VQSELBANCNFSM4ETME5JA . You are receiving this because you were mentioned.Message ID: @.***>

--

https://danielorodriguez.com

rgeddes commented 6 months ago

The default is_vim was not working for me. Don't know much about processes, but I searched for and found a ps command that lists programs running under the current pane.

is_vim="ps -o args -g $$ | grep -iqE 'n?vim?x?'"

and it seems to work. Even when I send nvim to the background with C-z

Alpine Linux 3.19 Tmux 3.3a Neovim 0.9.4-r0

Baitinq commented 4 months ago

This is also can be a problem if using NixOS with overlays. Using @rgeddes regex fixes this :)