vim-tmux-navigator icon indicating copy to clipboard operation
vim-tmux-navigator copied to clipboard

C-\ not working to switch panes in tmux

Open noahmoss opened this issue 3 years ago • 9 comments

This is the issue I mentioned in #297.

Basically, C-\ is working to switch to the last pane when I'm in vim, but when I'm in a bash pane it doesn't do anything at all. Nothing is even printed or displayed. My .tmux.conf is set up with the exact commands in the readme. Also tried it in zsh and it exhibits the same behavior.

Thanks for any help you can provide! :)

noahmoss avatar Jun 14 '21 21:06 noahmoss

Hey @noahmoss, not sure what the issue is, but I've got some questions that might help debug:

  1. What version of Tmux are you on?
  2. Can you try running select-pane -l directly in the tmux command prompt (prefix: to open the prompt, just to be clear there). Does that work as expected? (It should you bounce you back and forth between current and previous pane)
  3. Can you change the tmux binding command:
  if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \
-    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\'  'select-pane -l'"
+    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\'  'display-panes'"
  if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \
-    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\'  'select-pane -l'"
+    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\'  'display-panes'"

This'll swap out the pane switching for the display-pane. Now if you hit C-\ and things are wired correctly, you should see the pane numbers briefly flash. Hoping to test if it's the key binding that's mixed up.

christoomey avatar Jun 19 '21 14:06 christoomey

Hi @christoomey, thanks for the debugging tips!

I'm on tmux 3.2

select-pane -l in the command prompt works as expected.

Changing the commands still doesn't work. I guess that means the key binding itself isn't working? This might be a case of some other config messing with things...

noahmoss avatar Jun 20 '21 20:06 noahmoss

I also have vi-mode enabled in bash, which I realized was the root cause of #297. But I tried disabling it and I still wasn't able to get C-\ to work properly, so I guess this is a different problem.

noahmoss avatar Jun 20 '21 20:06 noahmoss

One other thing worth checking is the output of tmux list-keys. Is it possible that something else is overriding the C-\ mapping?

Based on your testing, it sounds like you're in the murky world of ' and \ escaping in tmux bindings, which is murky at best. The version of the bindings has an extra layer of complexity due to having some version checking logic, but I'd suggest replace them with just the single link you should need. I believe it's the following:

bind-key -n 'C-\\' if-shell "$is_vim" 'send-keys C-\\\\'  'select-pane -l'

Hopefully you can work from that (might have to tweak some ' and " and \\ escapes).

christoomey avatar Jun 20 '21 21:06 christoomey

I had the same problem and this fixed it for me. Escaping $is_vim was needed to make it work on SSH sessions.

bind-key -n C-\\ if-shell \"$is_vim\" 'send-keys C-\\\\' 'select-pane -l'

wassimk avatar Aug 31 '21 15:08 wassimk

I have the same problem. Looks like it is $tmux_version is storing the expression, not the evaluated version number.

❯ echo $tmux_version
^E$(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")

Hence echo "$tmux_version >= 3.0" never outputs the right expression 3.2 >= 3.0. I tried a few things but no luck.

Not sure if one of the below could cause the problem.

  • OS: MacOS 10.15.7 (Catalina)
  • Shell: zsh 5.8 (x86_64-apple-darwin19.6.0)
  • Tmux: 3.2a

jZhangTk avatar Sep 19 '21 02:09 jZhangTk

Was able to fix this with

if-shell -b '[ "$(echo "$(eval "echo $tmux_version") < 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\'  'select-pane -l'"
if-shell -b '[ "$(echo "$(eval "echo $tmux_version") >= 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\'  'select-pane -l'"

melbaldove avatar Jul 10 '22 16:07 melbaldove

is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?)(diff)?$'"
bind-key -n M-h if-shell "$is_vim" "send-keys M-h" "select-pane -L"
bind-key -n M-j if-shell "$is_vim" "send-keys M-j" "select-pane -D"
bind-key -n M-k if-shell "$is_vim" "send-keys M-k" "select-pane -U"
bind-key -n M-l if-shell "$is_vim" "send-keys M-l" "select-pane -R"
if-shell '[ $(echo $(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p") "<" 3 | bc) -eq 1 ]' \
  "bind-key -n 'M-\\' if-shell \"$is_vim\" 'send-keys M-\\'  'select-pane -l'"
if-shell '[ $(echo $(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p") ">=" 3 | bc) -eq 1 ]' \
  "bind-key -n 'M-\\' if-shell \"$is_vim\" 'send-keys M-\\\\'  'select-pane -l'"

These variables confuse me, maybe writing shell script directly is more intuitive

menghuu avatar Apr 08 '23 19:04 menghuu