Execute a command in tmux new window
私は普段ターミナルなどのタブ機能ではなく、tmuxのウィンドウを使っている。
メインのウィンドウは常にbashの状態にしておき、vimやtig、manなどは別ウィンドウを開くというようにしている。
これはtmux neww -n vim vim
のようにすればできる。
ただ毎回tmux neww
を実行するのは少し煩わしい。
そこでちょっとしたbash関数を定義して別ウィンドウで実行したいコマンドをラップするようにしている。
以下にその関数を定義したbashスクリプトを示す。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# These codes are licensed under CC0. | |
# https://creativecommons.org/publicdomain/zero/1.0/deed.ja | |
escape_args() { | |
args=() | |
for a in "$@"; do | |
args+=($(printf %q "$a")) | |
done | |
echo "${args[@]}" | |
} | |
wrap_with_neww_in_tmux() { | |
local cmd="${1}" | |
if [[ -z "$(which ${cmd})" ]]; then | |
return | |
fi | |
local window_title="${2:-$cmd}" | |
echo "$(cat <<EOD | |
${cmd}() { | |
if [[ -n "\${TMUX}" ]]; then | |
tmux neww -n "${window_title}" "command ${cmd} \$(escape_args "\$@")" | |
else | |
command ${cmd} "\$@" | |
fi | |
} | |
EOD | |
)" | |
} | |
vim() { | |
# ^/tmp/bash-fc- is bash vi mode on Ubuntu. | |
# /private/*/bash- is bash vi mode on Mac. | |
if [[ -z "${TMUX}" ]] || [[ "$1" =~ ^/.+/bash-fc ]]; then | |
command vim "$@" | |
else | |
if [[ -n "$VIRTUAL_ENV" ]]; then | |
# for some vim plugin, preserve `VIRTUAL_ENV` | |
tmux neww -n vim "VIRTUAL_ENV=$VIRTUAL_ENV command vim $(escape_args "$@")" | |
else | |
tmux neww -n vim "command vim $(escape_args "$@")" | |
fi | |
fi | |
} | |
eval "$(wrap_with_neww_in_tmux man man-\$1)" | |
eval "$(wrap_with_neww_in_tmux tig)" | |
eval "$(wrap_with_neww_in_tmux ssh)" | |
eval "$(wrap_with_neww_in_tmux mycli)" | |
eval "$(wrap_with_neww_in_tmux ipython)" | |
eval "$(wrap_with_neww_in_tmux ipython3)" | |
eval "$(wrap_with_neww_in_tmux less)" | |
eval "$(wrap_with_neww_in_tmux http-prompt)" |
このスクリプト(commands.bash)をHomeディレクトリなどに置き、 .bashrc でsource ~/commands.bash
しておけばよい。
ラップした関数はtmux上で実行されたかどうかを判定し、 tmux上であれば別ウィンドウで実行、 そうでなければ通常通り実行するようになっている。
vimだけ専用の関数を定義しているが、これはbashをviモード実行するため。 bashをviモードで利用していて、実行するコマンドを編集するためにvimを起動することもある。 その際にtmuxの別ウィンドウでvimが起動してしまわないようにするための分岐が必要なので、専用の関数を定義している。 bashをviモードで使わない人は専用の関数を定義する必要はない。
新しいコマンドを同様に別ウィンドウで実行したければ、
スクリプト下部のようにeval "$(wrap_with_neww_in_tmux some-command)"
とすればよい。