diff --git a/.local/bin/tm b/.local/bin/tm index 21f0250..02193f5 100755 --- a/.local/bin/tm +++ b/.local/bin/tm @@ -2,42 +2,153 @@ # # Attach to a tmux session, or create it if it doesnt exist -if [ -e $XDG_CONFIG_HOME/tmux/tmux.conf ]; then - start="tmux -f $XDG_CONFIG_HOME/tmux/tmux.conf" -else - start=tmux +if [ "$1" = '-h' ] || [ "$1" = '--help' ]; then +cat <<-EOF + Usage: $0 [FILE] [NAME] + Attach to an existing tmux session, or bootstrap a new session. + + If no session exists which fits the criteria, this will create a new one and + load it up obeying the commands contained in the FILE argument passed in. It + must contain commands which are tmux-command compatible since they will be + passed to tmux unmodified. If a session exists and a valid configuration FILE is + passed, it will attach itself to the session and execute the session setup inside. + + It will load the default tmux.conf in the following order: + - XDG_CONFIG_HOME/tmux/tmux.conf (usually ~/.config/tmux/tmux.conf) + - ~/.tmux.conf + - /etc/tmux.conf + Afterwards, it will apply the contents of the FILE argument passed into the command. + + If no FILE argument is passed it will create an empty session, or attach itself to + the session specified. + + If no NAME argument is passed it will automatically create a session name from the + FILE argument passed. + + If creating a new session without passing in a FILE argument, and the current directory + contains a .tmux.session file, it will automatically use that to set up the session. + + By default, it also looks for valid session files in XDG_CONFIG_HOME/tmux/sessions/ + This path can be changed by setting the TM_SESSION_PATH environment variable. +EOF + exit 0 fi -path_name="$(basename "$PWD" | tr . -)" -curr_dir=${1-$path_name} -session_name=${1:-$curr_dir} +# Make tmux obey the XDG specification on startup +if [ -e "$XDG_CONFIG_HOME/tmux/tmux.conf" ]; then + start="tmux -f $XDG_CONFIG_HOME/tmux/tmux.conf" +else + start=tmux +fi + +_file_exists() { + if [ -f "$1" ]; then + true + else + false + fi +} _not_in_tmux() { [ -z "$TMUX" ] } _session_exists() { - $start has-session -t "$session_name" -} - -_create_detached_session() { - (TMUX='' $start new-session -Ad -s "$session_name") -} - -_get_session_name() { - #${1:-$session_name} - return "blubb" -} - -_attach_or_create() { - if _not_in_tmux; then - $start new-session -As "$session_name" + if tmux has-session -t "$session_name" > /dev/null 2>&1; then + true else - if ! _session_exists; then - _create_detached_session - fi - $start switch-client -t "$session_name" + false fi } +_create_detached_session() { + ($start new-session -d -s "$session_name") +} + +_load_env_session_file() { + if [ -f ./.tmux.session ]; then + xargs -L1 tmux < ./.tmux.session + fi +} + +_load_session_file() { + if [ -f "$session_file" ]; then + xargs -L1 tmux < "$session_file" + fi +} + +_set_session_file_path() { + # Prefer local dir if file exists there, fall back to root dir + if _file_exists "${1}"; then + session_file="${1}" + elif _file_exists "${session_dir}${1}"; then + session_file="${session_dir}${1}" + fi +} + +_set_session_vars() { + session_dir=${TM_SESSION_DIR:-"$XDG_CONFIG_HOME/tmux/sessions/"} + + # set up session name and config file - if passed in as arguments + if [ "$#" -eq 2 ]; then + if ! _file_exists "$1" && ! _file_exists "${session_dir}${1}"; then + echo "sess dir: ${session_dir}${1}" + echo "$0: can not source configuration file: '${1}' does not exist." + exit 1 + fi + _set_session_file_path "$1" + session_name=${2} + elif [ "$#" -eq 1 ]; then + _set_session_file_path "$1" + if ! _file_exists "$session_file"; then + session_name=${1} + fi + fi + + # set default session name if none was passed + if [ -z "$session_name" ]; then + # only if we have a filename should we append it to the session name + if [ -n "$session_file" ]; then + fname=/$(basename "$session_file" .conf) + fi + # default to parent directory name / config file name for the session + session_name=$(basename "$PWD" | sed 's/[^a-zA-Z0-9\-]//g' | tr . -)"$fname" + fi +} + +_attach_or_create() { + # first create a new session if one doesn't exist + if ! _session_exists; then + _create_detached_session + # look for .tmux.session file if no file has been explicitly passed in + if ! _file_exists "$session_file"; then + _load_env_session_file + fi + fi + + _load_session_file + + # then attach or switch to the session + if _not_in_tmux; then + $start attach -t "$session_name" + else + $start switch-client -t "$session_name" + fi + + _unset_functions +} + +_unset_functions() { + unset _set_session_vars + unset _set_session_file_path + unset _attach_or_create + unset _load_session_file + unset _create_detached_session + unset _session_exists + unset _not_in_tmux + unset _file_exists +} + +_set_session_vars "$@" _attach_or_create +exit 0