tmux, split-window and pwd
The main differences here are that I can't use /proc to look for the PWD but have to rely on lsof and that ps
doesn't have a forest-rendering. So the resulting script looks like this:
#!/usr/bin/env ruby
=begin
Helper script for tmux' split-window command that retains the original PWD
This script is based on https://wiki.archlinux.org/index.php/Tmux#.2Fproc_method
=end
SHELL = 'reattach-to-user-namespace -l zsh'
session_id, window_id, pane_id = `tmux display-message -p "#S:#I:#P"`.chomp.split(/:/)
tty = nil
in_sessions = false
in_right_session = false
in_right_window = false
in_right_pane = false
# First step is to find our tty
`tmux server-info`.each_line do |line|
break if line.start_with? 'Terminals'
if line.start_with? 'Sessions: '
in_sessions = true
next
end
if in_sessions and line =~ /^\s\d+: #{session_id}: \d+ window..*[flags=.*]/
in_right_session = true
next
end
if in_right_session and line =~ /^\s{3}#{window_id}:/
in_right_window = true
next
end
if in_right_window and line =~ /^\s*#{pane_id}: \/dev\/(\S+) /
tty = $1
break
end
end
raise "No matching tty found" if tty.nil?
# Now let's find the process with this tty
pid = `ps -t #{tty}`.split($/)[1].split(' ')[0]
# ... and now its PWD
pwd = `lsof -a -d cwd -p #{pid} -F n`.split($/)[1][1..-1]
args = ARGV * " "
# Let's put it all together by calling split-window with the shell and the path
`tmux split-window #{args} 'cd #{pwd}; #{SHELL}'`
Gist
Thankfully, getting access to a process' PWD is pretty straight forward with lsof -d cwd and ps has a nice shortcut
for filtering for a specific tty. And yes, I know that the tty-scanning is really rocky up there and this is probably
the one part of this script that will evolve over time. The solution for the missing "--forest" support is also not
perfect yet, but so far it works just fine for me :-)
So, once you've put this script somewhere in your path (for me that ~/.local/bin/split-in-cwd.rb) and made it executable, all that is left to do, is to add it to your split-window bindings:
unbind s bind s run '~/.local/bin/split-in-cwd.rb -v' unbind v bind v run '~/.local/bin/split-in-cwd.rb -h'