Skip to content

Instantly share code, notes, and snippets.

@amiel
Forked from svenfuchs/_readme.md
Last active December 25, 2015 13:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amiel/6982620 to your computer and use it in GitHub Desktop.
Save amiel/6982620 to your computer and use it in GitHub Desktop.

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

My goal was to allow svenfuch's zoom feature to work in any direction. The original implementation relied on pane numbers, which works when you only split in one direction (either only horizontal or only vertical, but not both).

The logic is simple: use a panes width, height, x, and y along with the width width and height to determine if a pane is the top, bottom, leftmost, or rightmost pane. The reason I switched to ruby is that getting the panes x and y requires parsing the window_layout string.

#!/usr/bin/env ruby
# Gratefully adapted from https://gist.github.com/svenfuchs/6146321
Window = Struct.new(:width, :height, :layout)
PaneInfo = Struct.new(:id, :width, :height, :window, :current_command, :x, :y) do
def initialize(*)
super
set_layout
end
def set_layout
matches = window.layout.match(/#{width}x#{height},(\d+),(\d+),#{id}/)
self.x = matches[1].to_i
self.y = matches[2].to_i
end
def vim?
current_command == 'vim'
end
def top?
y.zero?
end
def bottom?
y + height == window.height
end
def left?
x.zero?
end
def right?
x + width == window.width
end
end
class TMUX
def get_tmux_thing(thing)
`tmux display-message -p '\#{#{thing}}'`.strip
end
def window
@_window ||= Window.new(
get_tmux_thing('window_width').to_i,
get_tmux_thing('window_height').to_i,
get_tmux_thing('window_layout'),
)
end
def pane
@_pane ||= PaneInfo.new(
get_tmux_thing('pane_id').gsub(/\%/,'').to_i,
get_tmux_thing('pane_width').to_i,
get_tmux_thing('pane_height').to_i,
window,
current_pane_command,
)
end
def current_pane_command
File.basename get_tmux_thing('pane_current_command')
end
end
tmux = TMUX.new
pane = tmux.pane
arg = ARGV[0]
if arg == '-L' && pane.left? || arg == '-R' && pane.right? || arg == '-U' && pane.top? || arg == '-D' && pane.bottom?
command = 'tmux resize-pane -Z'
else
command = "tmux select-pane #{arg}"
end
if pane.vim?
wincmd = arg.sub('-', '').tr 'lLDUR', 'phjkl'
`tmux send-keys ":let nr = winnr() | wincmd #{wincmd}" C-m`
`tmux send-keys ":if nr == winnr() | silent call system(\\"#{command}\\") | end" C-m`
# `tmux send-keys C-m ':echo "\\r"' C-m`
else
`#{command}`
end
bind -n C-k run-shell 'tmux-vim-select-pane.rb -U'
bind -n C-j run-shell 'tmux-vim-select-pane.rb -D'
bind -n C-h run-shell 'tmux-vim-select-pane.rb -L'
bind -n C-l run-shell 'tmux-vim-select-pane.rb -R'
bind -n C-\ run-shell 'tmux-vim-select-pane.rb -l'
@svenfuchs
Copy link

always cool to see people build on your stuff :) but after having used my own version i agree with @mislav that it sucks having it clutter the vim command history.

@amiel
Copy link
Author

amiel commented Mar 4, 2014

@svenfuchs, I agree, which is why I forked the plugin to support this

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