@factiii/runner 0.11.2 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1459 -918
- package/index/image-package.json +1 -1
- package/package.json +6 -4
- package/vendor/tmux-resurrect/COMMIT +1 -0
- package/vendor/tmux-resurrect/LICENSE.md +19 -0
- package/vendor/tmux-resurrect/README.factiii.md +13 -0
- package/vendor/tmux-resurrect/VERSION +1 -0
- package/vendor/tmux-resurrect/save_command_strategies/ps.sh +24 -0
- package/vendor/tmux-resurrect/scripts/check_tmux_version.sh +78 -0
- package/vendor/tmux-resurrect/scripts/helpers.sh +168 -0
- package/vendor/tmux-resurrect/scripts/process_restore_helpers.sh +198 -0
- package/vendor/tmux-resurrect/scripts/restore.sh +410 -0
- package/vendor/tmux-resurrect/scripts/save.sh +328 -0
- package/vendor/tmux-resurrect/scripts/spinner_helpers.sh +8 -0
- package/vendor/tmux-resurrect/scripts/tmux_spinner.sh +29 -0
- package/vendor/tmux-resurrect/scripts/variables.sh +51 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
4
|
+
|
|
5
|
+
source "$CURRENT_DIR/variables.sh"
|
|
6
|
+
source "$CURRENT_DIR/helpers.sh"
|
|
7
|
+
source "$CURRENT_DIR/process_restore_helpers.sh"
|
|
8
|
+
source "$CURRENT_DIR/spinner_helpers.sh"
|
|
9
|
+
|
|
10
|
+
# delimiter
|
|
11
|
+
d=$'\t'
|
|
12
|
+
|
|
13
|
+
# Global variable.
|
|
14
|
+
# Used during the restore: if a pane already exists from before, it is
|
|
15
|
+
# saved in the array in this variable. Later, process running in existing pane
|
|
16
|
+
# is also not restored. That makes the restoration process more idempotent.
|
|
17
|
+
EXISTING_PANES_VAR=""
|
|
18
|
+
|
|
19
|
+
RESTORING_FROM_SCRATCH="false"
|
|
20
|
+
|
|
21
|
+
RESTORE_PANE_CONTENTS="false"
|
|
22
|
+
|
|
23
|
+
is_line_type() {
|
|
24
|
+
local line_type="$1"
|
|
25
|
+
local line="$2"
|
|
26
|
+
echo "$line" |
|
|
27
|
+
\grep -q "^$line_type"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
check_saved_session_exists() {
|
|
31
|
+
local resurrect_file="$(last_resurrect_file)"
|
|
32
|
+
if [ ! -f $resurrect_file ]; then
|
|
33
|
+
display_message "Tmux resurrect file not found!"
|
|
34
|
+
return 1
|
|
35
|
+
fi
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
pane_exists() {
|
|
39
|
+
local session_name="$1"
|
|
40
|
+
local window_number="$2"
|
|
41
|
+
local pane_index="$3"
|
|
42
|
+
tmux list-panes -t "${session_name}:${window_number}" -F "#{pane_index}" 2>/dev/null |
|
|
43
|
+
\grep -q "^$pane_index$"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
register_existing_pane() {
|
|
47
|
+
local session_name="$1"
|
|
48
|
+
local window_number="$2"
|
|
49
|
+
local pane_index="$3"
|
|
50
|
+
local pane_custom_id="${session_name}:${window_number}:${pane_index}"
|
|
51
|
+
local delimiter=$'\t'
|
|
52
|
+
EXISTING_PANES_VAR="${EXISTING_PANES_VAR}${delimiter}${pane_custom_id}"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
is_pane_registered_as_existing() {
|
|
56
|
+
local session_name="$1"
|
|
57
|
+
local window_number="$2"
|
|
58
|
+
local pane_index="$3"
|
|
59
|
+
local pane_custom_id="${session_name}:${window_number}:${pane_index}"
|
|
60
|
+
[[ "$EXISTING_PANES_VAR" =~ "$pane_custom_id" ]]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
restore_from_scratch_true() {
|
|
64
|
+
RESTORING_FROM_SCRATCH="true"
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
is_restoring_from_scratch() {
|
|
68
|
+
[ "$RESTORING_FROM_SCRATCH" == "true" ]
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
restore_pane_contents_true() {
|
|
72
|
+
RESTORE_PANE_CONTENTS="true"
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
is_restoring_pane_contents() {
|
|
76
|
+
[ "$RESTORE_PANE_CONTENTS" == "true" ]
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
restored_session_0_true() {
|
|
80
|
+
RESTORED_SESSION_0="true"
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
has_restored_session_0() {
|
|
84
|
+
[ "$RESTORED_SESSION_0" == "true" ]
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
window_exists() {
|
|
88
|
+
local session_name="$1"
|
|
89
|
+
local window_number="$2"
|
|
90
|
+
tmux list-windows -t "$session_name" -F "#{window_index}" 2>/dev/null |
|
|
91
|
+
\grep -q "^$window_number$"
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
session_exists() {
|
|
95
|
+
local session_name="$1"
|
|
96
|
+
tmux has-session -t "$session_name" 2>/dev/null
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
first_window_num() {
|
|
100
|
+
tmux show -gv base-index
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
tmux_socket() {
|
|
104
|
+
echo $TMUX | cut -d',' -f1
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
# Tmux option stored in a global variable so that we don't have to "ask"
|
|
108
|
+
# tmux server each time.
|
|
109
|
+
cache_tmux_default_command() {
|
|
110
|
+
local default_shell="$(get_tmux_option "default-shell" "")"
|
|
111
|
+
local opt=""
|
|
112
|
+
if [ "$(basename "$default_shell")" == "bash" ]; then
|
|
113
|
+
opt="-l "
|
|
114
|
+
fi
|
|
115
|
+
export TMUX_DEFAULT_COMMAND="$(get_tmux_option "default-command" "$opt$default_shell")"
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
tmux_default_command() {
|
|
119
|
+
echo "$TMUX_DEFAULT_COMMAND"
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
pane_creation_command() {
|
|
123
|
+
echo "cat '$(pane_contents_file "restore" "${1}:${2}.${3}")'; exec $(tmux_default_command)"
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
new_window() {
|
|
127
|
+
local session_name="$1"
|
|
128
|
+
local window_number="$2"
|
|
129
|
+
local dir="$3"
|
|
130
|
+
local pane_index="$4"
|
|
131
|
+
local pane_id="${session_name}:${window_number}.${pane_index}"
|
|
132
|
+
dir="${dir/#\~/$HOME}"
|
|
133
|
+
if is_restoring_pane_contents && pane_contents_file_exists "$pane_id"; then
|
|
134
|
+
local pane_creation_command="$(pane_creation_command "$session_name" "$window_number" "$pane_index")"
|
|
135
|
+
tmux new-window -d -t "${session_name}:${window_number}" -c "$dir" "$pane_creation_command"
|
|
136
|
+
else
|
|
137
|
+
tmux new-window -d -t "${session_name}:${window_number}" -c "$dir"
|
|
138
|
+
fi
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
new_session() {
|
|
142
|
+
local session_name="$1"
|
|
143
|
+
local window_number="$2"
|
|
144
|
+
local dir="$3"
|
|
145
|
+
local pane_index="$4"
|
|
146
|
+
local pane_id="${session_name}:${window_number}.${pane_index}"
|
|
147
|
+
if is_restoring_pane_contents && pane_contents_file_exists "$pane_id"; then
|
|
148
|
+
local pane_creation_command="$(pane_creation_command "$session_name" "$window_number" "$pane_index")"
|
|
149
|
+
TMUX="" tmux -S "$(tmux_socket)" new-session -d -s "$session_name" -c "$dir" "$pane_creation_command"
|
|
150
|
+
else
|
|
151
|
+
TMUX="" tmux -S "$(tmux_socket)" new-session -d -s "$session_name" -c "$dir"
|
|
152
|
+
fi
|
|
153
|
+
# change first window number if necessary
|
|
154
|
+
local created_window_num="$(first_window_num)"
|
|
155
|
+
if [ $created_window_num -ne $window_number ]; then
|
|
156
|
+
tmux move-window -s "${session_name}:${created_window_num}" -t "${session_name}:${window_number}"
|
|
157
|
+
fi
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
new_pane() {
|
|
161
|
+
local session_name="$1"
|
|
162
|
+
local window_number="$2"
|
|
163
|
+
local dir="$3"
|
|
164
|
+
local pane_index="$4"
|
|
165
|
+
local pane_id="${session_name}:${window_number}.${pane_index}"
|
|
166
|
+
if is_restoring_pane_contents && pane_contents_file_exists "$pane_id"; then
|
|
167
|
+
local pane_creation_command="$(pane_creation_command "$session_name" "$window_number" "$pane_index")"
|
|
168
|
+
tmux split-window -t "${session_name}:${window_number}" -c "$dir" "$pane_creation_command"
|
|
169
|
+
else
|
|
170
|
+
tmux split-window -t "${session_name}:${window_number}" -c "$dir"
|
|
171
|
+
fi
|
|
172
|
+
# minimize window so more panes can fit
|
|
173
|
+
tmux resize-pane -t "${session_name}:${window_number}" -U "999"
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
restore_pane() {
|
|
177
|
+
local pane="$1"
|
|
178
|
+
while IFS=$d read line_type session_name window_number window_active window_flags pane_index pane_title dir pane_active pane_command pane_full_command; do
|
|
179
|
+
dir="$(remove_first_char "$dir")"
|
|
180
|
+
pane_full_command="$(remove_first_char "$pane_full_command")"
|
|
181
|
+
if [ "$session_name" == "0" ]; then
|
|
182
|
+
restored_session_0_true
|
|
183
|
+
fi
|
|
184
|
+
if pane_exists "$session_name" "$window_number" "$pane_index"; then
|
|
185
|
+
if is_restoring_from_scratch; then
|
|
186
|
+
# overwrite the pane
|
|
187
|
+
# happens only for the first pane if it's the only registered pane for the whole tmux server
|
|
188
|
+
local pane_id="$(tmux display-message -p -F "#{pane_id}" -t "$session_name:$window_number")"
|
|
189
|
+
new_pane "$session_name" "$window_number" "$dir" "$pane_index"
|
|
190
|
+
tmux kill-pane -t "$pane_id"
|
|
191
|
+
else
|
|
192
|
+
# Pane exists, no need to create it!
|
|
193
|
+
# Pane existence is registered. Later, its process also won't be restored.
|
|
194
|
+
register_existing_pane "$session_name" "$window_number" "$pane_index"
|
|
195
|
+
fi
|
|
196
|
+
elif window_exists "$session_name" "$window_number"; then
|
|
197
|
+
new_pane "$session_name" "$window_number" "$dir" "$pane_index"
|
|
198
|
+
elif session_exists "$session_name"; then
|
|
199
|
+
new_window "$session_name" "$window_number" "$dir" "$pane_index"
|
|
200
|
+
else
|
|
201
|
+
new_session "$session_name" "$window_number" "$dir" "$pane_index"
|
|
202
|
+
fi
|
|
203
|
+
# set pane title
|
|
204
|
+
tmux select-pane -t "$session_name:$window_number.$pane_index" -T "$pane_title"
|
|
205
|
+
done < <(echo "$pane")
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
restore_state() {
|
|
209
|
+
local state="$1"
|
|
210
|
+
echo "$state" |
|
|
211
|
+
while IFS=$d read line_type client_session client_last_session; do
|
|
212
|
+
tmux switch-client -t "$client_last_session"
|
|
213
|
+
tmux switch-client -t "$client_session"
|
|
214
|
+
done
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
restore_grouped_session() {
|
|
218
|
+
local grouped_session="$1"
|
|
219
|
+
echo "$grouped_session" |
|
|
220
|
+
while IFS=$d read line_type grouped_session original_session alternate_window active_window; do
|
|
221
|
+
TMUX="" tmux -S "$(tmux_socket)" new-session -d -s "$grouped_session" -t "$original_session"
|
|
222
|
+
done
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
restore_active_and_alternate_windows_for_grouped_sessions() {
|
|
226
|
+
local grouped_session="$1"
|
|
227
|
+
echo "$grouped_session" |
|
|
228
|
+
while IFS=$d read line_type grouped_session original_session alternate_window_index active_window_index; do
|
|
229
|
+
alternate_window_index="$(remove_first_char "$alternate_window_index")"
|
|
230
|
+
active_window_index="$(remove_first_char "$active_window_index")"
|
|
231
|
+
if [ -n "$alternate_window_index" ]; then
|
|
232
|
+
tmux switch-client -t "${grouped_session}:${alternate_window_index}"
|
|
233
|
+
fi
|
|
234
|
+
if [ -n "$active_window_index" ]; then
|
|
235
|
+
tmux switch-client -t "${grouped_session}:${active_window_index}"
|
|
236
|
+
fi
|
|
237
|
+
done
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
never_ever_overwrite() {
|
|
241
|
+
local overwrite_option_value="$(get_tmux_option "$overwrite_option" "")"
|
|
242
|
+
[ -n "$overwrite_option_value" ]
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
detect_if_restoring_from_scratch() {
|
|
246
|
+
if never_ever_overwrite; then
|
|
247
|
+
return
|
|
248
|
+
fi
|
|
249
|
+
local total_number_of_panes="$(tmux list-panes -a | wc -l | sed 's/ //g')"
|
|
250
|
+
if [ "$total_number_of_panes" -eq 1 ]; then
|
|
251
|
+
restore_from_scratch_true
|
|
252
|
+
fi
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
detect_if_restoring_pane_contents() {
|
|
256
|
+
if capture_pane_contents_option_on; then
|
|
257
|
+
cache_tmux_default_command
|
|
258
|
+
restore_pane_contents_true
|
|
259
|
+
fi
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
# functions called from main (ordered)
|
|
263
|
+
|
|
264
|
+
restore_all_panes() {
|
|
265
|
+
detect_if_restoring_from_scratch # sets a global variable
|
|
266
|
+
detect_if_restoring_pane_contents # sets a global variable
|
|
267
|
+
if is_restoring_pane_contents; then
|
|
268
|
+
pane_content_files_restore_from_archive
|
|
269
|
+
fi
|
|
270
|
+
while read line; do
|
|
271
|
+
if is_line_type "pane" "$line"; then
|
|
272
|
+
restore_pane "$line"
|
|
273
|
+
fi
|
|
274
|
+
done < $(last_resurrect_file)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
handle_session_0() {
|
|
278
|
+
if is_restoring_from_scratch && ! has_restored_session_0; then
|
|
279
|
+
local current_session="$(tmux display -p "#{client_session}")"
|
|
280
|
+
if [ "$current_session" == "0" ]; then
|
|
281
|
+
tmux switch-client -n
|
|
282
|
+
fi
|
|
283
|
+
tmux kill-session -t "0"
|
|
284
|
+
fi
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
restore_window_properties() {
|
|
288
|
+
local window_name
|
|
289
|
+
\grep '^window' $(last_resurrect_file) |
|
|
290
|
+
while IFS=$d read line_type session_name window_number window_name window_active window_flags window_layout automatic_rename; do
|
|
291
|
+
tmux select-layout -t "${session_name}:${window_number}" "$window_layout"
|
|
292
|
+
|
|
293
|
+
# Below steps are properly handling window names and automatic-rename
|
|
294
|
+
# option. `rename-window` is an extra command in some scenarios, but we
|
|
295
|
+
# opted for always doing it to keep the code simple.
|
|
296
|
+
window_name="$(remove_first_char "$window_name")"
|
|
297
|
+
tmux rename-window -t "${session_name}:${window_number}" "$window_name"
|
|
298
|
+
if [ "${automatic_rename}" = ":" ]; then
|
|
299
|
+
tmux set-option -u -t "${session_name}:${window_number}" automatic-rename
|
|
300
|
+
else
|
|
301
|
+
tmux set-option -t "${session_name}:${window_number}" automatic-rename "$automatic_rename"
|
|
302
|
+
fi
|
|
303
|
+
done
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
restore_shell_history() {
|
|
307
|
+
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ { print $2, $3, $6, $9; }' $(last_resurrect_file) |
|
|
308
|
+
while IFS=$d read session_name window_number pane_index pane_command; do
|
|
309
|
+
if ! is_pane_registered_as_existing "$session_name" "$window_number" "$pane_index"; then
|
|
310
|
+
local pane_id="$session_name:$window_number.$pane_index"
|
|
311
|
+
local history_file="$(resurrect_history_file "$pane_id" "$pane_command")"
|
|
312
|
+
|
|
313
|
+
if [ "$pane_command" = "bash" ]; then
|
|
314
|
+
local read_command="history -r '$history_file'"
|
|
315
|
+
tmux send-keys -t "$pane_id" "$read_command" C-m
|
|
316
|
+
elif [ "$pane_command" = "zsh" ]; then
|
|
317
|
+
local accept_line="$(expr "$(zsh -i -c bindkey | grep -m1 '\saccept-line$')" : '^"\(.*\)".*')"
|
|
318
|
+
local read_command="fc -R '$history_file'; clear"
|
|
319
|
+
tmux send-keys -t "$pane_id" "$read_command" "$accept_line"
|
|
320
|
+
fi
|
|
321
|
+
fi
|
|
322
|
+
done
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
restore_all_pane_processes() {
|
|
326
|
+
if restore_pane_processes_enabled; then
|
|
327
|
+
local pane_full_command
|
|
328
|
+
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $11 !~ "^:$" { print $2, $3, $6, $8, $11; }' $(last_resurrect_file) |
|
|
329
|
+
while IFS=$d read -r session_name window_number pane_index dir pane_full_command; do
|
|
330
|
+
dir="$(remove_first_char "$dir")"
|
|
331
|
+
pane_full_command="$(remove_first_char "$pane_full_command")"
|
|
332
|
+
restore_pane_process "$pane_full_command" "$session_name" "$window_number" "$pane_index" "$dir"
|
|
333
|
+
done
|
|
334
|
+
fi
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
restore_active_pane_for_each_window() {
|
|
338
|
+
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $9 == 1 { print $2, $3, $6; }' $(last_resurrect_file) |
|
|
339
|
+
while IFS=$d read session_name window_number active_pane; do
|
|
340
|
+
tmux switch-client -t "${session_name}:${window_number}"
|
|
341
|
+
tmux select-pane -t "$active_pane"
|
|
342
|
+
done
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
restore_zoomed_windows() {
|
|
346
|
+
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $5 ~ /Z/ && $9 == 1 { print $2, $3; }' $(last_resurrect_file) |
|
|
347
|
+
while IFS=$d read session_name window_number; do
|
|
348
|
+
tmux resize-pane -t "${session_name}:${window_number}" -Z
|
|
349
|
+
done
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
restore_grouped_sessions() {
|
|
353
|
+
while read line; do
|
|
354
|
+
if is_line_type "grouped_session" "$line"; then
|
|
355
|
+
restore_grouped_session "$line"
|
|
356
|
+
restore_active_and_alternate_windows_for_grouped_sessions "$line"
|
|
357
|
+
fi
|
|
358
|
+
done < $(last_resurrect_file)
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
restore_active_and_alternate_windows() {
|
|
362
|
+
awk 'BEGIN { FS="\t"; OFS="\t" } /^window/ && $6 ~ /[*-]/ { print $2, $4, $3; }' $(last_resurrect_file) |
|
|
363
|
+
sort -u |
|
|
364
|
+
while IFS=$d read session_name active_window window_number; do
|
|
365
|
+
tmux switch-client -t "${session_name}:${window_number}"
|
|
366
|
+
done
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
restore_active_and_alternate_sessions() {
|
|
370
|
+
while read line; do
|
|
371
|
+
if is_line_type "state" "$line"; then
|
|
372
|
+
restore_state "$line"
|
|
373
|
+
fi
|
|
374
|
+
done < $(last_resurrect_file)
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
# A cleanup that happens after 'restore_all_panes' seems to fix fish shell
|
|
378
|
+
# users' restore problems.
|
|
379
|
+
cleanup_restored_pane_contents() {
|
|
380
|
+
if is_restoring_pane_contents; then
|
|
381
|
+
rm "$(pane_contents_dir "restore")"/*
|
|
382
|
+
fi
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
main() {
|
|
386
|
+
if supported_tmux_version_ok && check_saved_session_exists; then
|
|
387
|
+
start_spinner "Restoring..." "Tmux restore complete!"
|
|
388
|
+
execute_hook "pre-restore-all"
|
|
389
|
+
restore_all_panes
|
|
390
|
+
handle_session_0
|
|
391
|
+
restore_window_properties >/dev/null 2>&1
|
|
392
|
+
execute_hook "pre-restore-history"
|
|
393
|
+
if save_shell_history_option_on; then
|
|
394
|
+
restore_shell_history
|
|
395
|
+
fi
|
|
396
|
+
execute_hook "pre-restore-pane-processes"
|
|
397
|
+
restore_all_pane_processes
|
|
398
|
+
# below functions restore exact cursor positions
|
|
399
|
+
restore_active_pane_for_each_window
|
|
400
|
+
restore_zoomed_windows
|
|
401
|
+
restore_grouped_sessions # also restores active and alt windows for grouped sessions
|
|
402
|
+
restore_active_and_alternate_windows
|
|
403
|
+
restore_active_and_alternate_sessions
|
|
404
|
+
cleanup_restored_pane_contents
|
|
405
|
+
execute_hook "post-restore-all"
|
|
406
|
+
stop_spinner
|
|
407
|
+
display_message "Tmux restore complete!"
|
|
408
|
+
fi
|
|
409
|
+
}
|
|
410
|
+
main
|