#!/bin/sh
# TMUXIE - TMUX(1) session manager (wrapper)
#
# 2025/10/26 - Now reads the user's tmux prefix out of .tmux.conf for display
#              in the menu, instead of assuming the default prefix is in use.
#              Now uses a POSIX compatible natural sort for sessions.
#              Also added a -h (and --help) help command.
# 2024/01/08 - adapted to change in tmux \ls output ron@vnetworx.net
# 2012/01/28 - Ported to tmux by Ron Guerin <ron@vnetworx.net>
# 1996/03/28 - Written for GNU screen by Marc O. Gloor <mgloor@fhzh.ch>
#
# Dual-licensed: GPL 2 and later, BSD.  You may choose which license
# your use of tmuxie will comply with.
#
# BSD:
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# GPL:
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA

set -e

#global settings
VERSION='2.0.0'
TMPF=$(mktemp -t .tmuxie.XXXXXX || exit 1)
ACTIVE_TMUXES="tmux \ls 2>/dev/null | awk '{ print \$1, \$10}' | sed 's/://' | awk '{
	line = \$0;
	name = \$1;
	if (match(name, /[0-9]+/)) {
		prefix = substr(name, 1, RSTART-1);
		num = substr(name, RSTART, RLENGTH);
		suffix = substr(name, RSTART+RLENGTH);
		printf \"%s\\t%03d\\t%s\\t%s\\n\", prefix, num, suffix, line;
	} else {
		printf \"zzz\\t000\\t%s\\t%s\\n\", name, line;
	}
}' | sort -k1,1 -k2,2n -k3,3 | cut -f4"

i=0
e=0

get_tmux_prefix() { # Get tmux prefix from ~/.tmux.conf
	prefix="C-b"
	if [ -f "$HOME/.tmux.conf" ]; then
		found=$(grep -E 'set(-option)?[[:space:]]+-g[[:space:]]+prefix' "$HOME/.tmux.conf" | tail -n 1 | awk '{print $NF}')
		[ -n "$found" ] && prefix="$found"
	fi
	echo "$prefix" | sed 's/^C-/CTRL-/'
}

help() {
cat <<EOF

tmuxie - tmux terminal session manager (ported from screenie)

Usage:
  $(basename "$0") [options]

Options:
  -v, --version           Show version
  -h, --help              Show this help message and exit
  -j, --job <name> <cmd>  Start a new tmux session with given name and command

Description:
  This script lists running tmux sessions and allows you to attach or start new ones.

Once you're inside a tmux session, press '$(get_tmux_prefix) d' to detach
and return to the session selection menu.

Further information may be available on the man page.
EOF
}

menu() {
	(
		echo
		echo -n " Use 'a' to add jobs"
		if [ $e = 0 ]; then
			echo "."
		else
			if [ $e = 1 ]; then
				echo " or '1' to choose the"
			else
				echo " or '1'-'$e' to choose a currently"
			fi
			echo " running (tmux) session."
		fi
		echo
		echo " Once you're inside the (tmux) session press "
		echo " '$(get_tmux_prefix) d' to return to the session selection menu."
	) | fmt
}

# starting jobs from commandline
fork_jobs() {
	# start tmux job
	tmux new-session -s $sname -d $pjob
}

# Cleanup
clean_exit() {
	rm $TMPF
	if [ -f $TMPF.status ]; then
		rm $TMPF.status
	fi
	exit 0
}

# Command-line options
case "$1" in
	-h|--help)
		help
		clean_exit
		;;
	-v|--version)
		echo $VERSION
		clean_exit
		;;
	-j|--job)
		sname=$(echo $2) ;
		sname=$(echo $sname | tr " " "_") ;
		pjob=$(echo $3) ;
		pjob=$(echo $pjob) ;
		fork_jobs
		clean_exit
		;;
esac

while :; do
	clear
	echo "" && echo " TMUXIE - tmux terminal session manager ported from screenie" && echo ""
	eval $ACTIVE_TMUXES | (
		while read sessions; do
			e=`expr \( $e + 1 \)`
			if [ $e -lt 10 ]; then
				echo -n "  $e) "
			else
				echo -n " $e) "
			fi
			echo $sessions
		done
		echo ""
		echo " a) add job"
		echo " q) quit"
		menu e
	)
	echo "" ; echo -n " Select: "
	read ANSW
		case $ANSW in
			A|a)
				echo -n " session name: " && read sname
				echo -n " job: " && read pjob
				sname=$(echo $sname | tr " " "_")
				tmux new-session -s $sname -d $pjob ;;
			0|Q|q)
				echo ""; clean_exit ;;
		esac

		eval $ACTIVE_TMUXES | (
			while read pat; do
				# display tmux session menu no. (int)
				i=`expr \( $i + 1 \)` && echo -n " $i) " >/dev/null 2>&1
				# set internal session 'no sessionid' var (string)
				sess_id=$(echo $pat|awk 'split($0, token, ".") {print token[1]}')
				k=$(echo -n  $i" "$sess_id)
				m=$(echo $k | awk '{print $1}')
				n=$(echo $k | awk '{print $2}')
				s=$(echo $k | awk '{print $3}')
				case $ANSW in
					$m) echo $n > $TMPF ; echo $s > $TMPF.status ; break;
				esac
			done
		)

	if [ -f $TMPF.status ]; then
		ATTACH=TRUE
		if [ "$(cat $TMPF.status)" = "(attached)" ]; then
			echo "" ; echo -n " Session is attached, continue (Y/N)? "
			read ATTACHED

			case $ATTACHED in
				Y|y)
					ATTACH=TRUE
					;;
				*)
					ATTACH=FALSE
					;;
			esac
		fi
		if [ $ATTACH = TRUE ]; then
			tmux attach -t $(cat $TMPF) >/dev/null 2>&1
		fi
		rm $TMPF.status
	fi
	cat /dev/null > $TMPF
done

clean_exit
#eof
