Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/restore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ cleanup_restored_pane_contents() {

main() {
if supported_tmux_version_ok && check_saved_session_exists; then
start_spinner "Restoring..." "Tmux restore complete!"
start_spinner "restoring..." "Tmux restore complete!"
execute_hook "pre-restore-all"
restore_all_panes
handle_session_0
Expand Down
2 changes: 1 addition & 1 deletion scripts/save.sh
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ show_output() {
main() {
if supported_tmux_version_ok; then
if show_output; then
start_spinner "Saving..." "Tmux environment saved!"
start_spinner "saving..." "Tmux environment saved!"
fi
save_all
if show_output; then
Expand Down
79 changes: 79 additions & 0 deletions scripts/spinner_helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,82 @@ start_spinner() {
stop_spinner() {
kill $SPINNER_PID
}

spinner_wave_label() {
local message="$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')"

case "$message" in
"saving..."|"restoring...")
echo "$message"
;;
*)
echo ""
;;
esac
}

spinner_wave_message() {
local message="$1"
local frame="$2"
local rendered=""
local message_length="${#message}"
local index=0
local char=""

if [ -z "$message" ]; then
return
fi

while [ "$index" -lt "${#message}" ]; do
char="${message:$index:1}"
if [ "$char" = " " ]; then
rendered="${rendered}${char}"
else
local color="$(spinner_wave_color "$frame" "$index" "$message_length")"
rendered="${rendered}#[fg=colour${color}]${char}"
fi
index=$((index + 1))
done

printf '%s#[default]' "$rendered"
}

spinner_wave_color() {
local frame="$1"
local index="$2"
local message_length="$3"
local min_color=240
local max_color=253
local gradient_width=5
local pause_frames=10
local half_width=$((gradient_width / 2))
local pass_frames=$((message_length + gradient_width))
local cycle_frames=$((pass_frames + pause_frames))
local active_frame=0
local center=0
local distance=0

if [ -z "$message_length" ] || [ "$message_length" -le 0 ]; then
echo "$max_color"
return
fi

active_frame=$((frame % cycle_frames))
if [ "$active_frame" -ge "$pass_frames" ]; then
echo "$max_color"
return
fi

center=$((active_frame - half_width))
distance=$((index - center))
if [ "$distance" -lt 0 ]; then
distance=$(( -distance ))
fi

if [ "$distance" -gt "$half_width" ]; then
echo "$max_color"
return
fi

echo $((min_color + (distance * (max_color - min_color) / half_width)))
}
124 changes: 120 additions & 4 deletions scripts/tmux_spinner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,133 @@
# ..
# kill $SPINNER_PID # Stops spinner and displays 'End message!'

CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

source "$CURRENT_DIR/helpers.sh"
source "$CURRENT_DIR/spinner_helpers.sh"
source "$CURRENT_DIR/variables.sh"

MESSAGE="$1"
END_MESSAGE="$2"
SPIN='-\|/'
DEFAULT_SPIN_CHARS='-\|/'
SPIN_CHARS=$( get_tmux_option "$spinner_chars_option" "$DEFAULT_SPIN_CHARS" )
SPIN_CHARS_LENGTH=$( echo -n "$SPIN_CHARS" | wc -m )
WAVE_LABEL="$(spinner_wave_label "$MESSAGE")"
CONTROL_MODE_FIFO=""
CONTROL_MODE_DIR=""
CONTROL_MODE_PID=""
CONTROL_MODE_READY="false"
TARGET_CLIENT_TTY=""

tmux_quote() {
printf "'%s'" "$(printf '%s' "$1" | sed "s/'/'\\\\''/g")"
}

tmux_control_target_client() {
tmux display-message -p -F "#{client_tty}" 2>/dev/null
}

tmux_control_start() {
TARGET_CLIENT_TTY="$(tmux_control_target_client)"

if [ -z "$TARGET_CLIENT_TTY" ]; then
return 1
fi

CONTROL_MODE_DIR="$(mktemp -d "${TMPDIR:-/tmp}/tmux-resurrect-spinner.XXXXXX" 2>/dev/null)"
if [ -z "$CONTROL_MODE_DIR" ]; then
return 1
fi

CONTROL_MODE_FIFO="$CONTROL_MODE_DIR/control-mode"
if ! mkfifo "$CONTROL_MODE_FIFO"; then
rmdir "$CONTROL_MODE_DIR"
CONTROL_MODE_DIR=""
return 1
fi

tmux -C <"$CONTROL_MODE_FIFO" >/dev/null 2>&1 &
CONTROL_MODE_PID="$!"

if ! exec 3>"$CONTROL_MODE_FIFO"; then
kill "$CONTROL_MODE_PID" 2>/dev/null
wait "$CONTROL_MODE_PID" 2>/dev/null
rm -f "$CONTROL_MODE_FIFO"
rmdir "$CONTROL_MODE_DIR"
CONTROL_MODE_FIFO=""
CONTROL_MODE_DIR=""
CONTROL_MODE_PID=""
return 1
fi

CONTROL_MODE_READY="true"
}

tmux_control_send() {
local command="$1"

if [ "$CONTROL_MODE_READY" = "true" ] && [ -n "$CONTROL_MODE_PID" ]; then
printf '%s\n' "$command" >&3 2>/dev/null || return 1
return 0
fi

return 1
}

tmux_send_display_message() {
local message="$1"
local quoted_message="$(tmux_quote "$message")"

if tmux_control_send "display-message -c $(tmux_quote "$TARGET_CLIENT_TTY") $quoted_message"; then
return 0
fi

tmux display-message "$message"
}

cleanup() {
local final_message="$1"

if [ -n "$final_message" ]; then
tmux_send_display_message "$final_message"
fi

if [ "$CONTROL_MODE_READY" = "true" ]; then
exec 3>&-
CONTROL_MODE_READY="false"
fi

if [ -n "$CONTROL_MODE_PID" ]; then
wait "$CONTROL_MODE_PID" 2>/dev/null
fi

if [ -n "$CONTROL_MODE_FIFO" ]; then
rm -f "$CONTROL_MODE_FIFO"
fi

if [ -n "$CONTROL_MODE_DIR" ]; then
rmdir "$CONTROL_MODE_DIR" 2>/dev/null
fi
}

handle_exit() {
cleanup "$END_MESSAGE"
exit
}

trap "tmux display-message '$END_MESSAGE'; exit" SIGINT SIGTERM
trap "handle_exit" SIGINT SIGTERM

main() {
local i=0
tmux_control_start
while true; do
i=$(( (i+1) %4 ))
tmux display-message " ${SPIN:$i:1} $MESSAGE"
if [ -n "$WAVE_LABEL" ]; then
tmux_send_display_message "$(spinner_wave_message "$WAVE_LABEL" "$i")"
i=$((i + 1))
else
i=$(( (i+1) % $SPIN_CHARS_LENGTH ))
tmux_send_display_message " ${SPIN_CHARS:$i:1} $MESSAGE"
fi
sleep 0.1
done
}
Expand Down
2 changes: 2 additions & 0 deletions scripts/variables.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,5 @@ hook_prefix="@resurrect-hook-"

delete_backup_after_option="@resurrect-delete-backup-after"
default_delete_backup_after="30" # days

spinner_chars_option="@resurrect-spinner-chars"