Permalink
Browse files

Ctrl+arrows across Vim and tmux.

Based on https://gist.github.com/mislav/5189704 and adapted for arrows instead of hjkl.

I want ctrl+l for clearing bash.
  • Loading branch information...
1 parent e84b9af commit 24ddbd90f75a2383400ef2c912b9ab8a5d5e9fc8 @henrik committed Mar 23, 2013
Showing with 60 additions and 10 deletions.
  1. +21 −0 bin/tmux-vim-select-pane
  2. +6 −0 tmux.conf
  3. +0 −9 vim/config/mappings.vim
  4. +1 −1 vim/plugin/bubbling.vim
  5. +32 −0 vim/plugin/tmux_vim_select_pane.vim
View
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+# Like `tmux select-pane`, but if Vim is running in the current pane it sends a
+# keystroke to Vim instead to let it decide whether it's going to switch windows
+# internally or switch tmux panes.
+#
+# https://gist.github.com/mislav/5189704
+
+set -e
+
+# gets the tty of active tmux pane
+active_tty="$(tmux list-panes -F '#{pane_active}#{pane_tty}' | grep '^1')"
+
+# checks if there's a foreground Vim process in attached to that tty
+if ps c -o 'state=,command=' -t "${active_tty#1}" | grep '+' | grep -iE '\bvim?\b' >/dev/null ; then
+ direction="$(echo "${1#-}" | sed -e 's/D/Down/' -e 's/U/Up/' -e 's/L/Left/' -e 's/R/Right/')";
+ # forward the keystroke to Vim
+ tmux send-keys C-$direction
+else
+ tmux select-pane "$@"
+fi
View
@@ -39,3 +39,9 @@ bind r source-file ~/.tmux.conf\; display "Reloaded conf."
# Use C-l in bash to clear the shell:
# http://stackoverflow.com/questions/10543684/how-can-i-clear-scrollback-buffer-in-tmux
bind -n C-k clear-history
+
+# Smart pane switching with awareness of vim splits.
+bind -n C-Up run-shell 'tmux-vim-select-pane -U'
+bind -n C-Down run-shell 'tmux-vim-select-pane -D'
+bind -n C-Left run-shell 'tmux-vim-select-pane -L'
+bind -n C-Right run-shell 'tmux-vim-select-pane -R'
View
@@ -40,15 +40,6 @@ inoremap <Up> <C-o>gk
noremap <S-Left> :tabp<CR>
noremap <S-Right> :tabn<CR>
-" Ctrl + arrows to jump between windows.
-" OS X may overload these; uncheck them in OS X prefs.
-" You may also need to map them in iTerm2 prefs to escape
-" sequences [1;5A (up) B (down) C (right) and D (left).
-noremap <C-Up> <C-w><Up>
-noremap <C-Down> <C-w><Down>
-noremap <C-Left> <C-w><Left>
-noremap <C-Right> <C-w><Right>
-
" Un-highlight search matches
nnoremap <leader><leader> :noh<CR>
View
@@ -1,6 +1,6 @@
" These rely on the vim-unimpaired plugin.
-" Move single lines.
@henrik

henrik Mar 23, 2013

Owner

Oops. Fixed.

+ Move single lines.
nmap <C-k> [e
nmap <C-j> ]e
" Move multiple lines.
@@ -0,0 +1,32 @@
+" https://gist.github.com/mislav/5189704
+
+let g:tmux_is_last_pane = 0
+au WinEnter * let g:tmux_is_last_pane = 0
+
+" Like `wincmd` but also change tmux panes instead of vim windows when needed.
+function! TmuxWinCmd(direction)
+ let nr = winnr()
+ let tmux_last_pane = (a:direction == 'p' && g:tmux_is_last_pane)
+ if !tmux_last_pane
+ " try to switch windows within vim
+ exec 'wincmd ' . a:direction
+ endif
+ " Forward the switch panes command to tmux if:
+ " a) we're toggling between the last tmux pane;
+ " b) we tried switching windows in vim but it didn't have effect.
+ if tmux_last_pane || nr == winnr()
+ let cmd = 'tmux select-pane -' . tr(a:direction, 'phjkl', 'lLDUR')
+ exec 'silent !'.cmd
+ redraw! " because `exec` fucked up the screen. why is this needed?? arrghh
+ let g:tmux_is_last_pane = 1
+ else
+ let g:tmux_is_last_pane = 0
+ endif
+endfunction
+
+" Ctrl + arrows to jump between windows.
+" Can also jump to adjacent tmux panes.
+noremap <c-up> :call TmuxWinCmd('k')<cr>
+noremap <c-down> :call TmuxWinCmd('j')<cr>
+noremap <c-right> :call TmuxWinCmd('l')<cr>
+noremap <c-left> :call TmuxWinCmd('h')<cr>

0 comments on commit 24ddbd9

Please sign in to comment.