cmux workspace をディレクトリ指定して開くようにする
やりたかったこと
作業を始めるとき、「このディレクトリで作業したい」と思ったら、fzf でディレクトリを選ぶだけでワークスペースが立ち上がってほしい、というのがイメージでした。
ディレクトリを選ぶ → ワークスペースができる → そこに切り替わる、という流れを 1 コマンドで完結させたいというのが出発点です。
前提として、ディレクトリ名はリポジトリ名と一致していて、そのままワークスペース名として使える状態を想定しています。
細かい要件を整理すると:
- fzf でディレクトリを選んでワークスペースを作りたい
$ dir=$(fzf) $ cmux new-workspace --cwd "$dir" $ cmux rename-workspace --workspace workspace:1 "$dir" - 同名ワークスペースが既にあれば、作らずに切り替えるだけにしたい
$ cmux list-workspaces | grep myproject $ cmux select-workspace --workspace workspace:1
作ったもの
~/.zshrc
# cwn: create new cmux workspace in specified directory
# usage: cwn [directory] [name]
function cwn() {
local dir=$1
if [[ -z "$dir" ]]; then
dir=$( (
for src in "${DIR_SOURCES[@]}"; do
eval "$src" 2>/dev/null
done
) | sed 's#/$##' | awk '!a[$0]++' | fzf --height 40% --reverse --no-sort --prompt "Select directory: " )
[[ -z "$dir" ]] && return
fi
[[ ! -d "$dir" ]] && echo "Error: Directory '$dir' not found." && return 1
local abs_dir=$(cd "$dir" && pwd)
local name="${2:-$(basename "$abs_dir")}"
local existing_ws=$(cmux list-workspaces 2>/dev/null | awk -v name="$name" '$NF == name || ($NF == "[selected]" && $(NF-1) == name) {print}' | grep -o 'workspace:[0-9]*' | head -1)
if [[ -n "$existing_ws" ]]; then
cmux select-workspace --workspace "$existing_ws"
return
fi
local ws=$(cmux new-workspace --cwd "$abs_dir" 2>&1 | grep -o 'workspace:[0-9]*')
if [[ -z "$ws" ]]; then
echo "Failed to create workspace" >&2
return 1
fi
cmux rename-workspace --workspace "$ws" "$name"
cmux select-workspace --workspace "$ws"
}
function _cwn() {
_arguments '1:directory:_directories'
}
compdef _cwn cwn
合わせて、ディレクトリ候補の取得元を配列で定義しています。
~/.zshrc
# ディレクトリ候補を列挙する関数を登録する配列
function __dir_source_projects() { find ~/work -maxdepth 2 -type d; }
DIR_SOURCES=("__dir_source_projects")
DIR_SOURCES に関数を追加すれば候補ソースを増やせます。重複は awk '!a[$0]++' で除去されます。
動作
引数なし:fzf でディレクトリを選ぶ
$ cwn
DIR_SOURCES に登録した関数からディレクトリ候補を収集し、fzf で選択します。選択後、そのディレクトリ名でワークスペースを作成して切り替えます。
引数あり:直接指定
$ cwn ~/work/myproject
# → myproject という名前でワークスペースを作成
$ cwn ~/work/myproject custom-name
# → custom-name という名前でワークスペースを作成
既存ワークスペースの場合は切り替えのみ
同名のワークスペースがすでに存在する場合は、新規作成せずに既存のものに切り替えます。「もう開いてたっけ?」を気にせず cwn を連打できます。