Skip to content

Instantly share code, notes, and snippets.

@kljohann
Created March 26, 2018 19:55
Show Gist options
  • Save kljohann/87bc4f7e8dc327fde902625a56a19af0 to your computer and use it in GitHub Desktop.
Save kljohann/87bc4f7e8dc327fde902625a56a19af0 to your computer and use it in GitHub Desktop.
#!/bin/zsh
setopt local_options err_exit warn_create_global
this_cmd=$0:t
usage () {
echo -e "Usage: $this_cmd [OPTION]... [NAME] [--] [COMMANDS]...\n" 1>&2
cat 1>&2 <<END
Arguments:
NAME Name of the (parent) session to attach to.
If no name or "-" is provided the name of the git worktree
or the current directory will be used. Use "." to force
using the current directory instead of the git worktree.
COMMANDS Optional tmux commands to be invoked after attaching.
Options:
--no-switch Do not switch sessions when already in a tmux session.
--no-kill Do not kill the current pane when switching.
-L socket-name See `man tmux`.
END
}
(( ${+commands[tmux]} )) || err "tmux not found."
local -A opts
zparseopts -D -A opts -help h -no-switch -no-kill L:
(( ${+opts[--help]} || ${+opts[-h]} )) && { usage; exit }
(( ${+opts[-L]} )) || opts[-L]=default
worktree=${$(git rev-parse --show-toplevel 2> /dev/null || true):-$PWD}
session=${worktree:t}
socket=$opts[-L]
case "$1" in
-) ;;
.) session=${PWD:t} ;;
ls) tmux -L "$socket" ls -F '#S' | grep -vE "#[0-9]+\$"; exit ;;
?*) session=$1 ;;
esac
(( $# < 1 )) || shift;
# check if we are already attached to another session
if [[ -z "$TMUX" ]]; then
cmd=attach-session
else
cmd=switch-client
(( ${+opts[--no-switch]} )) && exit 1
# check if it is a grouped session
[[ $(tmux -L "$socket" display-message -p '#{client_session}') != *#<-> ]] && {
echo "Not switching from non-grouped session." 1>&2
exit 1
}
# kill current pane if it is the only one in this window
tmux -L "$socket" list-panes -F "#{pane_active}" | grep -q "0" || {
# but only if we do not loose too much history
histlen=$(tmux -L "$socket" display-message -p "#{cursor_y} + #{history_size}")
if (( ! ${+opts[--no-kill]} && $histlen < 10)); then
set -- kill-pane -t $(tmux -L "$socket" display-message -p "#{pane_id}") \; "$@"
fi
}
fi
# check if session argument is path to a directory
[[ "$(basename $session)" != "$session" ]] && {
cd $session
session=$(basename $session)
}
tmux -L "$socket" has-session -t "$session" > /dev/null 2>&1 || {
TMUX= tmux -L "$socket" new-session -d -s $session
}
tmux -L "$socket" set-option -q -t $session destroy-unattached off
client=$session#$(tmux -L "$socket" ls -F '#S' | awk -F# \
"/^$session#[0-9]+/ { max=(+\$NF > +max) ? \$NF : max } END { print max+1 }")
TMUX= tmux -L "$socket" new-session -d -t $session -s $client
tmux -L "$socket" $cmd -t $client \
\; set-option -q -t $client destroy-unattached on \
\; "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment