aboutsummaryrefslogtreecommitdiff
path: root/tmux/.local/bin/tsession
blob: 30a22d4561357535a3489a0b2d4c5ae497711d6b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/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|<session>]"
    echo "    tsession l|load [-d|--detach] {<session> ...}"
    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