Split window on current working directory on tmux

2020-03-14

Update 2020-06-13: @pertho (thanks !!) points out that #{pane_current_path} is back on tmux for OpenBSD, so there's no need for all this. My key bindings now are:

bind | split-window -c '#{pane_current_path}' -h
bind - split-window -c '#{pane_current_path}' -v

This is outdated, then. I leave it here for archive purposes

In 99% of the occasions that I use split-window on tmux(1) I want the working directory to be the same as the pane I was in.

If you use Linux, FreeBSD, MacOSX (and maybe others), this can be achieved really easily with:

tmux split-window -c '#{pane_current_path}'

You can use -v or -h as you need and bind it to a key so the access is easy.

Problem is that #{pane_current_path} is not present on the tmux that ships in base for OpenBSD (the OS I use for everything on a daily basis). This seems to be a deliberate choice, so one has to work around it if one needs this feature.

While talking with the pros a bit about it, they came up with a solution for this that covers all my needs.

It involves calling an external program to get the working directory given the PID. One can do this with ps(1), but the output is limited to 40 characters, which is less than ideal. That's why Stuart Henderson sent a small program that does the job.

Then we need a shell script that executes the getcwd program and composes the tmux command to be executed. It can be as simple as:

#!/bin/sh

[ -z "${TMUX}" -o $# -lt 1 ] && exit 0

panel_cwd=$(getcwd ${1})
shift

exec /usr/bin/tmux split-window -c "${panel_cwd}" "$@"

And finally a couple of bindings to complete the setup:

bind | run-shell -b "~/bin/my-tmux-splitw #{?pane_active,#{pane_pid},} -h"
bind - run-shell -b "~/bin/my-tmux-splitw #{?pane_active,#{pane_pid},} -v"

Those are based on an idea from Sebastien Marie. The bindings are a mnemonic I use since a long time ago. Bar resembles vertical split and the dash horizontal.

The magic here comes from the format passed to the script (which is effectively the PID of the active pane).

This construction is like a ternary operator. If the variable (pane_active in this case) exists and is not zero, the first alternative (after the first comma) will be taken. If not, it will be the second one (empty in this case). Check tmux(1), in particular the FORMATS section for more info.

Have any comments ? Send an email to the comments address.