Skip to content

Instantly share code, notes, and snippets.

@svenfuchs
Last active May 21, 2021 19:19
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save svenfuchs/6146321 to your computer and use it in GitHub Desktop.
Save svenfuchs/6146321 to your computer and use it in GitHub Desktop.
tmux-vim integration to transparently switch between tmux panes and vim split windows tmux based version that does not require a vim plugin

Based on Mislav's gist and vim-tmux-navigator.

Since tmux hosts vim I disliked that I had to install a vim plugin for this. Instead I think it's cleaner to control vim from tmux.

My actual goal was to achive the following behaviour though (I have a default setup similar to the one Mislav shows in the gist. Two vertically split tmux panes, where the left one hosts vim, which has two vertically split windows):

  • On the leftmost window in vim: when I hit C-h (do not wrap to the rightmost tmux pane, but) zoom the left tmux pane.
  • On the rightmost tmux pane: when I hit C-l (do not wrap to the leftmost tmux pane, but) zoom the right tmux pane.
  • All other navigation: work as given in Mislav's gist

I guess the toggle between last active panes behaviour has slightly changed, but I'm not sure how it's supposed to work exactly and I don't use it much anyway.

#!/usr/bin/env bash
cmd="$(tmux display -p '#{pane_current_command}' | xargs basename | tr A-Z a-z)"
[ "${cmd%m}" = "vi" ] && vim=true || vim=false
pane="$(tmux display -p '#{pane_index}')"
pane=$[ pane + 1 ]
panes="$(tmux display -p '#{window_panes}')"
if [[ "$@" = "-L" && $pane == 1 || "$@" = '-R' && $pane == $panes ]]; then
cmd="tmux resize-pane -Z"
else
cmd="tmux select-pane $@"
fi
if $vim; then
wincmd="$(echo "${1#-}" | tr 'lLDUR' 'phjkl')"
tmux send-keys ":let nr = winnr() | wincmd $wincmd" C-m
tmux send-keys ":if nr == winnr() | silent call system(\"$cmd\") | end"
tmux send-keys C-m ':echo "\r"' C-m
else
$cmd
fi
bind -n C-k run-shell 'tmux-vim-select-pane -U'
bind -n C-j run-shell 'tmux-vim-select-pane -D'
bind -n C-h run-shell 'tmux-vim-select-pane -L'
bind -n C-l run-shell 'tmux-vim-select-pane -R'
bind -n C-\ run-shell 'tmux-vim-select-pane -l'
@svenfuchs
Copy link
Author

There's one oddity on lines 19 and 20. If I send C-m at the end of line 19 then it will mess up my vim view. Sending it at the beginning of line 20 works. Pretty curious.

@amiel
Copy link

amiel commented Apr 25, 2014

@svenfuchs thanks for this!

I just thought I'd note here that I forked christoomey/vim-tmux-navigator to include this zoom functionality (see amiel/vim-tmux-navigator). My fork requires ruby, but sends the commands to vim without using :, which makes it work in insert mode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment