Files
zsh/session/session.plugin.zsh

122 lines
3.7 KiB
Bash

session() {
local usage="usage: session [-h] [-H <host>] <name>
session [-H <host>] -p <project>"
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 <project>, 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 <host> via ssh, where <host> is
either a hostname or a shortname defined in ~/.config/session. Combined with -p
the project is resolved on <host>, not locally. Not allowed inside a tmux
session.
"
return 0
;;
-p|--project)
if [[ "$2" == "" ]]; then
echo "$fg[red]error:$reset_color missing <project> argument"
return 1
fi
project=${2%/}
shift 2
;;
-H|--host)
if [[ "$2" == "" ]]; then
echo "$fg[red]error:$reset_color missing <host> 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 <name> 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 <host> 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
}