#!/bin/bash NC='\033[0m' RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' msg_info() { echo -e "${GREEN}[INFO] $1${NC}" } msg_warn() { echo -e "${YELLOW}[WARN] $1${NC}" } msg_error() { echo -e "${RED}[ERROR] $1${NC}" } print_help() { echo echo "tsession - a poor man's session handler for tmux" echo echo "USAGE:" echo " tsession [ls|list]" echo " tsession a|attach [-m|--dmenu|]" echo " tsession l|load [-d|--detach] { ...}" echo " tsession h|help" echo echo "where:" echo " ls | list:" echo " list available sessions (default if no argument is" echo " provided)" echo " a | attach:" echo " attach to an existing session (compatible with" echo " 'target-session' syntax defined in the TMux manual)." echo " If the -m|--dmenu flag is used sessions can be" echo " selected with dmenu. Defaults to dmenu if no argument" echo " is provided." echo " l | load:" echo " start list of sessions. Terminal attaches to last" echo " sessions provided (use -d|--detach to detach from all" echo " provided sessions)" echo " h | help:" echo " print this help" echo } COMMAND=${1:-list} shift mkdir -p "$TMUX_SESSIONS" case $COMMAND in ls|list) ls "$TMUX_SESSIONS" | sed 's|\.tmux$||' ;; a|attach) # Defaults to dmenu prompt. arg=${1:-'--dmenu'} case $arg in -m|--dmenu) # Retrieve existing sessions sessions=$(tmux ls -F "#S" 2>/dev/null) # Choose one with dmenu # It seems like the windowid changes between pipe # commands; this means that WINDOWID needs to be # computed exacly when dmenu is called. session=$(echo -e "TERM\nNEW\n$sessions" | WINDOWID=`xdotool getwindowfocus` dmenu -i -l 10 -h 16 -p "Session:" -e $WINDOWID) # Attach to selected session case $session in "") # Do nothing... command aborted. ;; "TERM") # Open a simple term window without Tmux. bash ;; "NEW") # Create a new tmux session tmux new -s `date +'S%m%d%H%M%S'` -n main 2>$HOME/ciaone ;; *) # Attach to an existing Tmux session # TODO: forcing the shell to be interactive # seems to be the only way to make Base16 colors # work properly when attaching to an existing # session. There might be a better way... bash -ic "tmux attach -t $session" ;; esac ;; *) tmux has-session -t "$arg" && \ bash -ic "tmux attach -t $arg" || \ bash ;; esac ;; l|load) if [ -d "$TMUX_SESSIONS" ]; then sessions=() attach="true" # Collect requested sessions while [[ $# -gt 0 ]] do case $1 in -d|--detach) attach="false" ;; *) sessions+=("$1") ;; esac shift done # Tmux digest file path. dpath="$TMUX_SESSIONS/.tmux.digests" for s in "${sessions[@]}" do # Tmux session file path. spath="$TMUX_SESSIONS/$s.tmux" if [ -x "$spath" ]; then # If a tmux session file exists, check if it is # genuine comparing its digest with a set of # approved digests. If the file is not among the # approved ones, prompt the user for approval; # execute the file otherwise. # Code inspired by: # https://github.com/wincent/wincent/blob/f7c51dfd808ea78ec10d6501eaa28f0a5b4796e9/roles/dotfiles/files/.zsh/functions#L41-L80 digest="$(openssl sha512 "$spath")" if ! grep -qs "$digest" "$dpath" ; then cat "$spath" echo read -n 1 -p \ "Trust this tmux session file? [y/N] " \ reply echo if [[ ! $reply =~ ^[yY]$ ]]; then msg_error "$spath not trusted" continue fi echo "$digest" >> "$dpath" fi # Execute the TMux config file "$spath" && \ last_session=$(awk -F "=" '/^SESSION/{ print $NF }' $spath) ; \ last_window=$(awk -F "=" '/^WINDOW/{ print $NF }' $spath) else msg_warn "session \"$s\" not found" fi done # Attach to the latest session created. if [ "$attach" = "true" ] && [ -z "$TMUX" ]; then tmux attach -t "$last_session:$last_window" fi fi ;; h|help) print_help ;; *) msg_error "$COMMAND: invalid command" print_help exit 1 ;; esac