session() { local usage="usage: session [-h] [-H ] session [-H ] -p " local name="" project="" host="" while [[ $# -gt 0 ]]; do case "$1" in -h|--help) echo "$usage Create or attach to a tmux session by name either locally or on a remote host via ssh. With -p create or attach to a session for , a path in ~/Projects with the prefix removed, which must be a git repository. The session is named after the project and holds a home window plus a window at the project, named after its default branch. With -H create or attach to the session on via ssh, where is either a hostname or a shortname defined in ~/.config/session. Combined with -p the project is resolved on , not locally. Not allowed inside a tmux session. " return 0 ;; -p|--project) if [[ "$2" == "" ]]; then echo "$fg[red]error:$reset_color missing argument" return 1 fi project=${2%/} shift 2 ;; -H|--host) if [[ "$2" == "" ]]; then echo "$fg[red]error:$reset_color missing argument" return 1 fi host=$2 shift 2 ;; -*) echo "$fg[red]error:$reset_color unknown option: $1" return 1 ;; *) if [[ "$name" != "" ]]; then echo "$fg[red]error:$reset_color invalid argument: $1" return 1 fi name=$1 shift ;; esac done if [[ "$project" != "" ]] && [[ "$name" != "" ]]; then echo "$fg[red]error:$reset_color not allowed with -p" return 1 fi if [[ "$project" == "" ]] && [[ "$name" == "" ]]; then echo "$usage" return 0 fi if [[ "$host" != "" ]]; then if [[ "$TMUX" != "" ]]; then echo "$fg[red]error:$reset_color not allowed inside tmux session" return 1 fi declare -A hosts if [ -f ~/.config/session ]; then source ~/.config/session fi host=${hosts[$host]:-$host} fi if [[ "$project" != "" ]]; then # tmux rewrites `.` and `:` in session names, so mirror that to keep the # name we create and the name we target in sync. name=${project//[.:]/_} if [[ "$host" != "" ]]; then # The project lives in the remote ~/Projects, so resolve it there rather # than locally. The remote session-created hook reads TMUX_PROJECT back # out of the remote tmux server to build the layout. ssh "$host" -t " repo=\$HOME/Projects/${(q)project} [ -d \"\$repo\" ] || { echo 'error: no such project: ${(q)project}' >&2; exit 1; } git -C \"\$repo\" rev-parse --git-dir >/dev/null 2>&1 || { echo \"error: not a git repository: \$repo\" >&2; exit 1; } exec tmux new-session -As ${(q)name} -c \"\$HOME\" -e TMUX_PROJECT=${(q)project} " return fi local repo=$HOME/Projects/$project if [ ! -d "$repo" ]; then echo "$fg[red]error:$reset_color no such project: $project" return 1 fi if ! git -C "$repo" rev-parse --git-dir &>/dev/null; then echo "$fg[red]error:$reset_color not a git repository: $repo" return 1 fi if [[ "$TMUX" == "" ]]; then tmux new-session -As "$name" -c $HOME -e "TMUX_PROJECT=$project" else tmux has-session -t "=$name" &> /dev/null || \ tmux new-session -Ads "$name" -c $HOME -e "TMUX_PROJECT=$project" tmux switch-client -t "=$name" fi elif [[ "$host" != "" ]]; then ssh "$host" -t tmux new-session -As "$name" elif [[ "$TMUX" == "" ]]; then tmux new-session -As "$name" else tmux has-session -t "=$name" &> /dev/null || \ tmux new-session -Ads "$name" -c $HOME tmux switch-client -t "=$name" fi }