Добавлены конфиги tmux и zsh
This commit is contained in:
78
tmux/plugins/tmux-ressurect/scripts/check_tmux_version.sh
Executable file
78
tmux/plugins/tmux-ressurect/scripts/check_tmux_version.sh
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
VERSION="$1"
|
||||
UNSUPPORTED_MSG="$2"
|
||||
|
||||
get_tmux_option() {
|
||||
local option=$1
|
||||
local default_value=$2
|
||||
local option_value=$(tmux show-option -gqv "$option")
|
||||
if [ -z "$option_value" ]; then
|
||||
echo "$default_value"
|
||||
else
|
||||
echo "$option_value"
|
||||
fi
|
||||
}
|
||||
|
||||
# Ensures a message is displayed for 5 seconds in tmux prompt.
|
||||
# Does not override the 'display-time' tmux option.
|
||||
display_message() {
|
||||
local message="$1"
|
||||
|
||||
# display_duration defaults to 5 seconds, if not passed as an argument
|
||||
if [ "$#" -eq 2 ]; then
|
||||
local display_duration="$2"
|
||||
else
|
||||
local display_duration="5000"
|
||||
fi
|
||||
|
||||
# saves user-set 'display-time' option
|
||||
local saved_display_time=$(get_tmux_option "display-time" "750")
|
||||
|
||||
# sets message display time to 5 seconds
|
||||
tmux set-option -gq display-time "$display_duration"
|
||||
|
||||
# displays message
|
||||
tmux display-message "$message"
|
||||
|
||||
# restores original 'display-time' value
|
||||
tmux set-option -gq display-time "$saved_display_time"
|
||||
}
|
||||
|
||||
# this is used to get "clean" integer version number. Examples:
|
||||
# `tmux 1.9` => `19`
|
||||
# `1.9a` => `19`
|
||||
get_digits_from_string() {
|
||||
local string="$1"
|
||||
local only_digits="$(echo "$string" | tr -dC '[:digit:]')"
|
||||
echo "$only_digits"
|
||||
}
|
||||
|
||||
tmux_version_int() {
|
||||
local tmux_version_string=$(tmux -V)
|
||||
echo "$(get_digits_from_string "$tmux_version_string")"
|
||||
}
|
||||
|
||||
unsupported_version_message() {
|
||||
if [ -n "$UNSUPPORTED_MSG" ]; then
|
||||
echo "$UNSUPPORTED_MSG"
|
||||
else
|
||||
echo "Error, Tmux version unsupported! Please install Tmux version $VERSION or greater!"
|
||||
fi
|
||||
}
|
||||
|
||||
exit_if_unsupported_version() {
|
||||
local current_version="$1"
|
||||
local supported_version="$2"
|
||||
if [ "$current_version" -lt "$supported_version" ]; then
|
||||
display_message "$(unsupported_version_message)"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
local supported_version_int="$(get_digits_from_string "$VERSION")"
|
||||
local current_version_int="$(tmux_version_int)"
|
||||
exit_if_unsupported_version "$current_version_int" "$supported_version_int"
|
||||
}
|
||||
main
|
||||
168
tmux/plugins/tmux-ressurect/scripts/helpers.sh
Normal file
168
tmux/plugins/tmux-ressurect/scripts/helpers.sh
Normal file
@@ -0,0 +1,168 @@
|
||||
default_resurrect_dir="$HOME/.tmux/resurrect"
|
||||
resurrect_dir_option="@resurrect-dir"
|
||||
|
||||
SUPPORTED_VERSION="1.9"
|
||||
RESURRECT_FILE_PREFIX="tmux_resurrect"
|
||||
RESURRECT_FILE_EXTENSION="txt"
|
||||
_RESURRECT_DIR=""
|
||||
_RESURRECT_FILE_PATH=""
|
||||
|
||||
d=$'\t'
|
||||
|
||||
# helper functions
|
||||
get_tmux_option() {
|
||||
local option="$1"
|
||||
local default_value="$2"
|
||||
local option_value=$(tmux show-option -gqv "$option")
|
||||
if [ -z "$option_value" ]; then
|
||||
echo "$default_value"
|
||||
else
|
||||
echo "$option_value"
|
||||
fi
|
||||
}
|
||||
|
||||
# Ensures a message is displayed for 5 seconds in tmux prompt.
|
||||
# Does not override the 'display-time' tmux option.
|
||||
display_message() {
|
||||
local message="$1"
|
||||
|
||||
# display_duration defaults to 5 seconds, if not passed as an argument
|
||||
if [ "$#" -eq 2 ]; then
|
||||
local display_duration="$2"
|
||||
else
|
||||
local display_duration="5000"
|
||||
fi
|
||||
|
||||
# saves user-set 'display-time' option
|
||||
local saved_display_time=$(get_tmux_option "display-time" "750")
|
||||
|
||||
# sets message display time to 5 seconds
|
||||
tmux set-option -gq display-time "$display_duration"
|
||||
|
||||
# displays message
|
||||
tmux display-message "$message"
|
||||
|
||||
# restores original 'display-time' value
|
||||
tmux set-option -gq display-time "$saved_display_time"
|
||||
}
|
||||
|
||||
|
||||
supported_tmux_version_ok() {
|
||||
$CURRENT_DIR/check_tmux_version.sh "$SUPPORTED_VERSION"
|
||||
}
|
||||
|
||||
remove_first_char() {
|
||||
echo "$1" | cut -c2-
|
||||
}
|
||||
|
||||
capture_pane_contents_option_on() {
|
||||
local option="$(get_tmux_option "$pane_contents_option" "off")"
|
||||
[ "$option" == "on" ]
|
||||
}
|
||||
|
||||
files_differ() {
|
||||
! cmp -s "$1" "$2"
|
||||
}
|
||||
|
||||
save_shell_history_option_on() {
|
||||
local option_shell="$(get_tmux_option "$shell_history_option" "off")"
|
||||
local option_bash="$(get_tmux_option "$bash_history_option" "off")"
|
||||
|
||||
[ "$option_shell" == "on" ] || [ "$option_bash" == "on" ]
|
||||
}
|
||||
|
||||
get_grouped_sessions() {
|
||||
local grouped_sessions_dump="$1"
|
||||
export GROUPED_SESSIONS="${d}$(echo "$grouped_sessions_dump" | cut -f2 -d"$d" | tr "\\n" "$d")"
|
||||
}
|
||||
|
||||
is_session_grouped() {
|
||||
local session_name="$1"
|
||||
[[ "$GROUPED_SESSIONS" == *"${d}${session_name}${d}"* ]]
|
||||
}
|
||||
|
||||
# pane content file helpers
|
||||
|
||||
pane_contents_create_archive() {
|
||||
tar cf - -C "$(resurrect_dir)/save/" ./pane_contents/ |
|
||||
gzip > "$(pane_contents_archive_file)"
|
||||
}
|
||||
|
||||
pane_content_files_restore_from_archive() {
|
||||
local archive_file="$(pane_contents_archive_file)"
|
||||
if [ -f "$archive_file" ]; then
|
||||
mkdir -p "$(pane_contents_dir "restore")"
|
||||
gzip -d < "$archive_file" |
|
||||
tar xf - -C "$(resurrect_dir)/restore/"
|
||||
fi
|
||||
}
|
||||
|
||||
# path helpers
|
||||
|
||||
resurrect_dir() {
|
||||
if [ -z "$_RESURRECT_DIR" ]; then
|
||||
local path="$(get_tmux_option "$resurrect_dir_option" "$default_resurrect_dir")"
|
||||
# expands tilde, $HOME and $HOSTNAME if used in @resurrect-dir
|
||||
echo "$path" | sed "s,\$HOME,$HOME,g; s,\$HOSTNAME,$(hostname),g; s,\~,$HOME,g"
|
||||
else
|
||||
echo "$_RESURRECT_DIR"
|
||||
fi
|
||||
}
|
||||
_RESURRECT_DIR="$(resurrect_dir)"
|
||||
|
||||
resurrect_file_path() {
|
||||
if [ -z "$_RESURRECT_FILE_PATH" ]; then
|
||||
local timestamp="$(date +"%Y%m%dT%H%M%S")"
|
||||
echo "$(resurrect_dir)/${RESURRECT_FILE_PREFIX}_${timestamp}.${RESURRECT_FILE_EXTENSION}"
|
||||
else
|
||||
echo "$_RESURRECT_FILE_PATH"
|
||||
fi
|
||||
}
|
||||
_RESURRECT_FILE_PATH="$(resurrect_file_path)"
|
||||
|
||||
last_resurrect_file() {
|
||||
echo "$(resurrect_dir)/last"
|
||||
}
|
||||
|
||||
pane_contents_dir() {
|
||||
echo "$(resurrect_dir)/$1/pane_contents/"
|
||||
}
|
||||
|
||||
pane_contents_file() {
|
||||
local save_or_restore="$1"
|
||||
local pane_id="$2"
|
||||
echo "$(pane_contents_dir "$save_or_restore")/pane-${pane_id}"
|
||||
}
|
||||
|
||||
pane_contents_file_exists() {
|
||||
local pane_id="$1"
|
||||
[ -f "$(pane_contents_file "restore" "$pane_id")" ]
|
||||
}
|
||||
|
||||
pane_contents_archive_file() {
|
||||
echo "$(resurrect_dir)/pane_contents.tar.gz"
|
||||
}
|
||||
|
||||
resurrect_history_file() {
|
||||
local pane_id="$1"
|
||||
local shell_name="$2"
|
||||
echo "$(resurrect_dir)/${shell_name}_history-${pane_id}"
|
||||
}
|
||||
|
||||
execute_hook() {
|
||||
local kind="$1"
|
||||
shift
|
||||
local args="" hook=""
|
||||
|
||||
hook=$(get_tmux_option "$hook_prefix$kind" "")
|
||||
|
||||
# If there are any args, pass them to the hook (in a way that preserves/copes
|
||||
# with spaces and unusual characters.
|
||||
if [ "$#" -gt 0 ]; then
|
||||
printf -v args "%q " "$@"
|
||||
fi
|
||||
|
||||
if [ -n "$hook" ]; then
|
||||
eval "$hook $args"
|
||||
fi
|
||||
}
|
||||
172
tmux/plugins/tmux-ressurect/scripts/process_restore_helpers.sh
Normal file
172
tmux/plugins/tmux-ressurect/scripts/process_restore_helpers.sh
Normal file
@@ -0,0 +1,172 @@
|
||||
restore_pane_processes_enabled() {
|
||||
local restore_processes="$(get_tmux_option "$restore_processes_option" "$restore_processes")"
|
||||
if [ "$restore_processes" == "false" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
restore_pane_process() {
|
||||
local pane_full_command="$1"
|
||||
local session_name="$2"
|
||||
local window_number="$3"
|
||||
local pane_index="$4"
|
||||
local dir="$5"
|
||||
local command
|
||||
if _process_should_be_restored "$pane_full_command" "$session_name" "$window_number" "$pane_index"; then
|
||||
tmux switch-client -t "${session_name}:${window_number}"
|
||||
tmux select-pane -t "$pane_index"
|
||||
|
||||
local inline_strategy="$(_get_inline_strategy "$pane_full_command")" # might not be defined
|
||||
if [ -n "$inline_strategy" ]; then
|
||||
# inline strategy exists
|
||||
# check for additional "expansion" of inline strategy, e.g. `vim` to `vim -S`
|
||||
if _strategy_exists "$inline_strategy"; then
|
||||
local strategy_file="$(_get_strategy_file "$inline_strategy")"
|
||||
local inline_strategy="$($strategy_file "$pane_full_command" "$dir")"
|
||||
fi
|
||||
command="$inline_strategy"
|
||||
elif _strategy_exists "$pane_full_command"; then
|
||||
local strategy_file="$(_get_strategy_file "$pane_full_command")"
|
||||
local strategy_command="$($strategy_file "$pane_full_command" "$dir")"
|
||||
command="$strategy_command"
|
||||
else
|
||||
# just invoke the raw command
|
||||
command="$pane_full_command"
|
||||
fi
|
||||
tmux send-keys -t "${session_name}:${window_number}.${pane_index}" "$command" "C-m"
|
||||
fi
|
||||
}
|
||||
|
||||
# private functions below
|
||||
|
||||
_process_should_be_restored() {
|
||||
local pane_full_command="$1"
|
||||
local session_name="$2"
|
||||
local window_number="$3"
|
||||
local pane_index="$4"
|
||||
if is_pane_registered_as_existing "$session_name" "$window_number" "$pane_index"; then
|
||||
# Scenario where pane existed before restoration, so we're not
|
||||
# restoring the proces either.
|
||||
return 1
|
||||
elif ! pane_exists "$session_name" "$window_number" "$pane_index"; then
|
||||
# pane number limit exceeded, pane does not exist
|
||||
return 1
|
||||
elif _restore_all_processes; then
|
||||
return 0
|
||||
elif _process_on_the_restore_list "$pane_full_command"; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
_restore_all_processes() {
|
||||
local restore_processes="$(get_tmux_option "$restore_processes_option" "$restore_processes")"
|
||||
if [ "$restore_processes" == ":all:" ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
_process_on_the_restore_list() {
|
||||
local pane_full_command="$1"
|
||||
# TODO: make this work without eval
|
||||
eval set $(_restore_list)
|
||||
local proc
|
||||
local match
|
||||
for proc in "$@"; do
|
||||
match="$(_get_proc_match_element "$proc")"
|
||||
if _proc_matches_full_command "$pane_full_command" "$match"; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
_proc_matches_full_command() {
|
||||
local pane_full_command="$1"
|
||||
local match="$2"
|
||||
if _proc_starts_with_tildae "$match"; then
|
||||
match="$(remove_first_char "$match")"
|
||||
# regex matching the command makes sure `$match` string is somewhere in the command string
|
||||
if [[ "$pane_full_command" =~ ($match) ]]; then
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
# regex matching the command makes sure process is a "word"
|
||||
if [[ "$pane_full_command" =~ (^${match} ) ]] || [[ "$pane_full_command" =~ (^${match}$) ]]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
_get_proc_match_element() {
|
||||
echo "$1" | sed "s/${inline_strategy_token}.*//"
|
||||
}
|
||||
|
||||
_get_proc_restore_element() {
|
||||
echo "$1" | sed "s/.*${inline_strategy_token}//"
|
||||
}
|
||||
|
||||
_restore_list() {
|
||||
local user_processes="$(get_tmux_option "$restore_processes_option" "$restore_processes")"
|
||||
local default_processes="$(get_tmux_option "$default_proc_list_option" "$default_proc_list")"
|
||||
if [ -z "$user_processes" ]; then
|
||||
# user didn't define any processes
|
||||
echo "$default_processes"
|
||||
else
|
||||
echo "$default_processes $user_processes"
|
||||
fi
|
||||
}
|
||||
|
||||
_proc_starts_with_tildae() {
|
||||
[[ "$1" =~ (^~) ]]
|
||||
}
|
||||
|
||||
_get_inline_strategy() {
|
||||
local pane_full_command="$1"
|
||||
# TODO: make this work without eval
|
||||
eval set $(_restore_list)
|
||||
local proc
|
||||
local match
|
||||
for proc in "$@"; do
|
||||
if [[ "$proc" =~ "$inline_strategy_token" ]]; then
|
||||
match="$(_get_proc_match_element "$proc")"
|
||||
if _proc_matches_full_command "$pane_full_command" "$match"; then
|
||||
echo "$(_get_proc_restore_element "$proc")"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
_strategy_exists() {
|
||||
local pane_full_command="$1"
|
||||
local strategy="$(_get_command_strategy "$pane_full_command")"
|
||||
if [ -n "$strategy" ]; then # strategy set?
|
||||
local strategy_file="$(_get_strategy_file "$pane_full_command")"
|
||||
[ -e "$strategy_file" ] # strategy file exists?
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
_get_command_strategy() {
|
||||
local pane_full_command="$1"
|
||||
local command="$(_just_command "$pane_full_command")"
|
||||
get_tmux_option "${restore_process_strategy_option}${command}" ""
|
||||
}
|
||||
|
||||
_just_command() {
|
||||
echo "$1" | cut -d' ' -f1
|
||||
}
|
||||
|
||||
_get_strategy_file() {
|
||||
local pane_full_command="$1"
|
||||
local strategy="$(_get_command_strategy "$pane_full_command")"
|
||||
local command="$(_just_command "$pane_full_command")"
|
||||
echo "$CURRENT_DIR/../strategies/${command}_${strategy}.sh"
|
||||
}
|
||||
14
tmux/plugins/tmux-ressurect/scripts/restore.exp
Executable file
14
tmux/plugins/tmux-ressurect/scripts/restore.exp
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env expect
|
||||
|
||||
# start tmux
|
||||
spawn tmux -S/tmp/foo
|
||||
|
||||
# delay with sleep to compensate for tmux starting time
|
||||
sleep 2
|
||||
|
||||
# run restore script directly
|
||||
send "~/.tmux/plugins/tmux-resurrect/scripts/restore.sh\r"
|
||||
|
||||
# long wait until tmux restore is complete
|
||||
# (things get messed up if expect client isn't attached)
|
||||
sleep 100
|
||||
369
tmux/plugins/tmux-ressurect/scripts/restore.sh
Executable file
369
tmux/plugins/tmux-ressurect/scripts/restore.sh
Executable file
@@ -0,0 +1,369 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
source "$CURRENT_DIR/variables.sh"
|
||||
source "$CURRENT_DIR/helpers.sh"
|
||||
source "$CURRENT_DIR/process_restore_helpers.sh"
|
||||
source "$CURRENT_DIR/spinner_helpers.sh"
|
||||
|
||||
# delimiter
|
||||
d=$'\t'
|
||||
|
||||
# Global variable.
|
||||
# Used during the restore: if a pane already exists from before, it is
|
||||
# saved in the array in this variable. Later, process running in existing pane
|
||||
# is also not restored. That makes the restoration process more idempotent.
|
||||
EXISTING_PANES_VAR=""
|
||||
|
||||
RESTORING_FROM_SCRATCH="false"
|
||||
|
||||
RESTORE_PANE_CONTENTS="false"
|
||||
|
||||
is_line_type() {
|
||||
local line_type="$1"
|
||||
local line="$2"
|
||||
echo "$line" |
|
||||
\grep -q "^$line_type"
|
||||
}
|
||||
|
||||
check_saved_session_exists() {
|
||||
local resurrect_file="$(last_resurrect_file)"
|
||||
if [ ! -f $resurrect_file ]; then
|
||||
display_message "Tmux resurrect file not found!"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
pane_exists() {
|
||||
local session_name="$1"
|
||||
local window_number="$2"
|
||||
local pane_index="$3"
|
||||
tmux list-panes -t "${session_name}:${window_number}" -F "#{pane_index}" 2>/dev/null |
|
||||
\grep -q "^$pane_index$"
|
||||
}
|
||||
|
||||
register_existing_pane() {
|
||||
local session_name="$1"
|
||||
local window_number="$2"
|
||||
local pane_index="$3"
|
||||
local pane_custom_id="${session_name}:${window_number}:${pane_index}"
|
||||
local delimiter=$'\t'
|
||||
EXISTING_PANES_VAR="${EXISTING_PANES_VAR}${delimiter}${pane_custom_id}"
|
||||
}
|
||||
|
||||
is_pane_registered_as_existing() {
|
||||
local session_name="$1"
|
||||
local window_number="$2"
|
||||
local pane_index="$3"
|
||||
local pane_custom_id="${session_name}:${window_number}:${pane_index}"
|
||||
[[ "$EXISTING_PANES_VAR" =~ "$pane_custom_id" ]]
|
||||
}
|
||||
|
||||
restore_from_scratch_true() {
|
||||
RESTORING_FROM_SCRATCH="true"
|
||||
}
|
||||
|
||||
is_restoring_from_scratch() {
|
||||
[ "$RESTORING_FROM_SCRATCH" == "true" ]
|
||||
}
|
||||
|
||||
restore_pane_contents_true() {
|
||||
RESTORE_PANE_CONTENTS="true"
|
||||
}
|
||||
|
||||
is_restoring_pane_contents() {
|
||||
[ "$RESTORE_PANE_CONTENTS" == "true" ]
|
||||
}
|
||||
|
||||
window_exists() {
|
||||
local session_name="$1"
|
||||
local window_number="$2"
|
||||
tmux list-windows -t "$session_name" -F "#{window_index}" 2>/dev/null |
|
||||
\grep -q "^$window_number$"
|
||||
}
|
||||
|
||||
session_exists() {
|
||||
local session_name="$1"
|
||||
tmux has-session -t "$session_name" 2>/dev/null
|
||||
}
|
||||
|
||||
first_window_num() {
|
||||
tmux show -gv base-index
|
||||
}
|
||||
|
||||
tmux_socket() {
|
||||
echo $TMUX | cut -d',' -f1
|
||||
}
|
||||
|
||||
# Tmux option stored in a global variable so that we don't have to "ask"
|
||||
# tmux server each time.
|
||||
cache_tmux_default_command() {
|
||||
local default_shell="$(get_tmux_option "default-shell" "")"
|
||||
export TMUX_DEFAULT_COMMAND="$(get_tmux_option "default-command" "$default_shell")"
|
||||
}
|
||||
|
||||
tmux_default_command() {
|
||||
echo "$TMUX_DEFAULT_COMMAND"
|
||||
}
|
||||
|
||||
pane_creation_command() {
|
||||
echo "cat '$(pane_contents_file "restore" "${1}:${2}.${3}")'; exec $(tmux_default_command)"
|
||||
}
|
||||
|
||||
new_window() {
|
||||
local session_name="$1"
|
||||
local window_number="$2"
|
||||
local window_name="$3"
|
||||
local dir="$4"
|
||||
local pane_index="$5"
|
||||
local pane_id="${session_name}:${window_number}.${pane_index}"
|
||||
if is_restoring_pane_contents && pane_contents_file_exists "$pane_id"; then
|
||||
local pane_creation_command="$(pane_creation_command "$session_name" "$window_number" "$pane_index")"
|
||||
tmux new-window -d -t "${session_name}:${window_number}" -n "$window_name" -c "$dir" "$pane_creation_command"
|
||||
else
|
||||
tmux new-window -d -t "${session_name}:${window_number}" -n "$window_name" -c "$dir"
|
||||
fi
|
||||
}
|
||||
|
||||
new_session() {
|
||||
local session_name="$1"
|
||||
local window_number="$2"
|
||||
local window_name="$3"
|
||||
local dir="$4"
|
||||
local pane_index="$5"
|
||||
local pane_id="${session_name}:${window_number}.${pane_index}"
|
||||
if is_restoring_pane_contents && pane_contents_file_exists "$pane_id"; then
|
||||
local pane_creation_command="$(pane_creation_command "$session_name" "$window_number" "$pane_index")"
|
||||
TMUX="" tmux -S "$(tmux_socket)" new-session -d -s "$session_name" -n "$window_name" -c "$dir" "$pane_creation_command"
|
||||
else
|
||||
TMUX="" tmux -S "$(tmux_socket)" new-session -d -s "$session_name" -n "$window_name" -c "$dir"
|
||||
fi
|
||||
# change first window number if necessary
|
||||
local created_window_num="$(first_window_num)"
|
||||
if [ $created_window_num -ne $window_number ]; then
|
||||
tmux move-window -s "${session_name}:${created_window_num}" -t "${session_name}:${window_number}"
|
||||
fi
|
||||
}
|
||||
|
||||
new_pane() {
|
||||
local session_name="$1"
|
||||
local window_number="$2"
|
||||
local window_name="$3"
|
||||
local dir="$4"
|
||||
local pane_index="$5"
|
||||
local pane_id="${session_name}:${window_number}.${pane_index}"
|
||||
if is_restoring_pane_contents && pane_contents_file_exists "$pane_id"; then
|
||||
local pane_creation_command="$(pane_creation_command "$session_name" "$window_number" "$pane_index")"
|
||||
tmux split-window -t "${session_name}:${window_number}" -c "$dir" "$pane_creation_command"
|
||||
else
|
||||
tmux split-window -t "${session_name}:${window_number}" -c "$dir"
|
||||
fi
|
||||
# minimize window so more panes can fit
|
||||
tmux resize-pane -t "${session_name}:${window_number}" -U "999"
|
||||
}
|
||||
|
||||
restore_pane() {
|
||||
local pane="$1"
|
||||
while IFS=$d read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_full_command; do
|
||||
dir="$(remove_first_char "$dir")"
|
||||
window_name="$(remove_first_char "$window_name")"
|
||||
pane_full_command="$(remove_first_char "$pane_full_command")"
|
||||
if pane_exists "$session_name" "$window_number" "$pane_index"; then
|
||||
tmux rename-window -t "$window_number" "$window_name"
|
||||
if is_restoring_from_scratch; then
|
||||
# overwrite the pane
|
||||
# happens only for the first pane if it's the only registered pane for the whole tmux server
|
||||
local pane_id="$(tmux display-message -p -F "#{pane_id}" -t "$session_name:$window_number")"
|
||||
new_pane "$session_name" "$window_number" "$window_name" "$dir" "$pane_index"
|
||||
tmux kill-pane -t "$pane_id"
|
||||
else
|
||||
# Pane exists, no need to create it!
|
||||
# Pane existence is registered. Later, its process also won't be restored.
|
||||
register_existing_pane "$session_name" "$window_number" "$pane_index"
|
||||
fi
|
||||
elif window_exists "$session_name" "$window_number"; then
|
||||
tmux rename-window -t "$window_number" "$window_name"
|
||||
new_pane "$session_name" "$window_number" "$window_name" "$dir" "$pane_index"
|
||||
elif session_exists "$session_name"; then
|
||||
new_window "$session_name" "$window_number" "$window_name" "$dir" "$pane_index"
|
||||
else
|
||||
new_session "$session_name" "$window_number" "$window_name" "$dir" "$pane_index"
|
||||
fi
|
||||
done < <(echo "$pane")
|
||||
}
|
||||
|
||||
restore_state() {
|
||||
local state="$1"
|
||||
echo "$state" |
|
||||
while IFS=$d read line_type client_session client_last_session; do
|
||||
tmux switch-client -t "$client_last_session"
|
||||
tmux switch-client -t "$client_session"
|
||||
done
|
||||
}
|
||||
|
||||
restore_grouped_session() {
|
||||
local grouped_session="$1"
|
||||
echo "$grouped_session" |
|
||||
while IFS=$d read line_type grouped_session original_session alternate_window active_window; do
|
||||
TMUX="" tmux -S "$(tmux_socket)" new-session -d -s "$grouped_session" -t "$original_session"
|
||||
done
|
||||
}
|
||||
|
||||
restore_active_and_alternate_windows_for_grouped_sessions() {
|
||||
local grouped_session="$1"
|
||||
echo "$grouped_session" |
|
||||
while IFS=$d read line_type grouped_session original_session alternate_window_index active_window_index; do
|
||||
alternate_window_index="$(remove_first_char "$alternate_window_index")"
|
||||
active_window_index="$(remove_first_char "$active_window_index")"
|
||||
if [ -n "$alternate_window_index" ]; then
|
||||
tmux switch-client -t "${grouped_session}:${alternate_window_index}"
|
||||
fi
|
||||
if [ -n "$active_window_index" ]; then
|
||||
tmux switch-client -t "${grouped_session}:${active_window_index}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
never_ever_overwrite() {
|
||||
local overwrite_option_value="$(get_tmux_option "$overwrite_option" "")"
|
||||
[ -n "$overwrite_option_value" ]
|
||||
}
|
||||
|
||||
detect_if_restoring_from_scratch() {
|
||||
if never_ever_overwrite; then
|
||||
return
|
||||
fi
|
||||
local total_number_of_panes="$(tmux list-panes -a | wc -l | sed 's/ //g')"
|
||||
if [ "$total_number_of_panes" -eq 1 ]; then
|
||||
restore_from_scratch_true
|
||||
fi
|
||||
}
|
||||
|
||||
detect_if_restoring_pane_contents() {
|
||||
if capture_pane_contents_option_on; then
|
||||
cache_tmux_default_command
|
||||
restore_pane_contents_true
|
||||
fi
|
||||
}
|
||||
|
||||
# functions called from main (ordered)
|
||||
|
||||
restore_all_panes() {
|
||||
detect_if_restoring_from_scratch # sets a global variable
|
||||
detect_if_restoring_pane_contents # sets a global variable
|
||||
if is_restoring_pane_contents; then
|
||||
pane_content_files_restore_from_archive
|
||||
fi
|
||||
while read line; do
|
||||
if is_line_type "pane" "$line"; then
|
||||
restore_pane "$line"
|
||||
fi
|
||||
done < $(last_resurrect_file)
|
||||
if is_restoring_pane_contents; then
|
||||
rm "$(pane_contents_dir "restore")"/*
|
||||
fi
|
||||
}
|
||||
|
||||
restore_pane_layout_for_each_window() {
|
||||
\grep '^window' $(last_resurrect_file) |
|
||||
while IFS=$d read line_type session_name window_number window_active window_flags window_layout; do
|
||||
tmux select-layout -t "${session_name}:${window_number}" "$window_layout"
|
||||
done
|
||||
}
|
||||
|
||||
restore_shell_history() {
|
||||
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ { print $2, $3, $7, $10; }' $(last_resurrect_file) |
|
||||
while IFS=$d read session_name window_number pane_index pane_command; do
|
||||
if ! is_pane_registered_as_existing "$session_name" "$window_number" "$pane_index"; then
|
||||
local pane_id="$session_name:$window_number.$pane_index"
|
||||
local history_file="$(resurrect_history_file "$pane_id" "$pane_command")"
|
||||
|
||||
if [ "$pane_command" = "bash" ]; then
|
||||
local read_command="history -r '$history_file'"
|
||||
tmux send-keys -t "$pane_id" "$read_command" C-m
|
||||
elif [ "$pane_command" = "zsh" ]; then
|
||||
local accept_line="$(expr "$(zsh -i -c bindkey | grep -m1 '\saccept-line$')" : '^"\(.*\)".*')"
|
||||
local read_command="fc -R '$history_file'; clear"
|
||||
tmux send-keys -t "$pane_id" "$read_command" "$accept_line"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
restore_all_pane_processes() {
|
||||
if restore_pane_processes_enabled; then
|
||||
local pane_full_command
|
||||
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $11 !~ "^:$" { print $2, $3, $7, $8, $11; }' $(last_resurrect_file) |
|
||||
while IFS=$d read session_name window_number pane_index dir pane_full_command; do
|
||||
dir="$(remove_first_char "$dir")"
|
||||
pane_full_command="$(remove_first_char "$pane_full_command")"
|
||||
restore_pane_process "$pane_full_command" "$session_name" "$window_number" "$pane_index" "$dir"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
restore_active_pane_for_each_window() {
|
||||
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $9 == 1 { print $2, $3, $7; }' $(last_resurrect_file) |
|
||||
while IFS=$d read session_name window_number active_pane; do
|
||||
tmux switch-client -t "${session_name}:${window_number}"
|
||||
tmux select-pane -t "$active_pane"
|
||||
done
|
||||
}
|
||||
|
||||
restore_zoomed_windows() {
|
||||
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $6 ~ /Z/ && $9 == 1 { print $2, $3; }' $(last_resurrect_file) |
|
||||
while IFS=$d read session_name window_number; do
|
||||
tmux resize-pane -t "${session_name}:${window_number}" -Z
|
||||
done
|
||||
}
|
||||
|
||||
restore_grouped_sessions() {
|
||||
while read line; do
|
||||
if is_line_type "grouped_session" "$line"; then
|
||||
restore_grouped_session "$line"
|
||||
restore_active_and_alternate_windows_for_grouped_sessions "$line"
|
||||
fi
|
||||
done < $(last_resurrect_file)
|
||||
}
|
||||
|
||||
restore_active_and_alternate_windows() {
|
||||
awk 'BEGIN { FS="\t"; OFS="\t" } /^window/ && $5 ~ /[*-]/ { print $2, $4, $3; }' $(last_resurrect_file) |
|
||||
sort -u |
|
||||
while IFS=$d read session_name active_window window_number; do
|
||||
tmux switch-client -t "${session_name}:${window_number}"
|
||||
done
|
||||
}
|
||||
|
||||
restore_active_and_alternate_sessions() {
|
||||
while read line; do
|
||||
if is_line_type "state" "$line"; then
|
||||
restore_state "$line"
|
||||
fi
|
||||
done < $(last_resurrect_file)
|
||||
}
|
||||
|
||||
main() {
|
||||
if supported_tmux_version_ok && check_saved_session_exists; then
|
||||
start_spinner "Restoring..." "Tmux restore complete!"
|
||||
execute_hook "pre-restore-all"
|
||||
restore_all_panes
|
||||
restore_pane_layout_for_each_window >/dev/null 2>&1
|
||||
execute_hook "pre-restore-history"
|
||||
if save_shell_history_option_on; then
|
||||
restore_shell_history
|
||||
fi
|
||||
execute_hook "pre-restore-pane-processes"
|
||||
restore_all_pane_processes
|
||||
# below functions restore exact cursor positions
|
||||
restore_active_pane_for_each_window
|
||||
restore_zoomed_windows
|
||||
restore_grouped_sessions # also restores active and alt windows for grouped sessions
|
||||
restore_active_and_alternate_windows
|
||||
restore_active_and_alternate_sessions
|
||||
execute_hook "post-restore-all"
|
||||
stop_spinner
|
||||
display_message "Tmux restore complete!"
|
||||
fi
|
||||
}
|
||||
main
|
||||
322
tmux/plugins/tmux-ressurect/scripts/save.sh
Executable file
322
tmux/plugins/tmux-ressurect/scripts/save.sh
Executable file
@@ -0,0 +1,322 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
source "$CURRENT_DIR/variables.sh"
|
||||
source "$CURRENT_DIR/helpers.sh"
|
||||
source "$CURRENT_DIR/spinner_helpers.sh"
|
||||
|
||||
# delimiters
|
||||
d=$'\t'
|
||||
delimiter=$'\t'
|
||||
|
||||
# if "quiet" script produces no output
|
||||
SCRIPT_OUTPUT="$1"
|
||||
|
||||
grouped_sessions_format() {
|
||||
local format
|
||||
format+="#{session_grouped}"
|
||||
format+="${delimiter}"
|
||||
format+="#{session_group}"
|
||||
format+="${delimiter}"
|
||||
format+="#{session_id}"
|
||||
format+="${delimiter}"
|
||||
format+="#{session_name}"
|
||||
echo "$format"
|
||||
}
|
||||
|
||||
pane_format() {
|
||||
local format
|
||||
format+="pane"
|
||||
format+="${delimiter}"
|
||||
format+="#{session_name}"
|
||||
format+="${delimiter}"
|
||||
format+="#{window_index}"
|
||||
format+="${delimiter}"
|
||||
format+=":#{window_name}"
|
||||
format+="${delimiter}"
|
||||
format+="#{window_active}"
|
||||
format+="${delimiter}"
|
||||
format+=":#{window_flags}"
|
||||
format+="${delimiter}"
|
||||
format+="#{pane_index}"
|
||||
format+="${delimiter}"
|
||||
format+=":#{pane_current_path}"
|
||||
format+="${delimiter}"
|
||||
format+="#{pane_active}"
|
||||
format+="${delimiter}"
|
||||
format+="#{pane_current_command}"
|
||||
format+="${delimiter}"
|
||||
format+="#{pane_pid}"
|
||||
format+="${delimiter}"
|
||||
format+="#{history_size}"
|
||||
echo "$format"
|
||||
}
|
||||
|
||||
window_format() {
|
||||
local format
|
||||
format+="window"
|
||||
format+="${delimiter}"
|
||||
format+="#{session_name}"
|
||||
format+="${delimiter}"
|
||||
format+="#{window_index}"
|
||||
format+="${delimiter}"
|
||||
format+="#{window_active}"
|
||||
format+="${delimiter}"
|
||||
format+=":#{window_flags}"
|
||||
format+="${delimiter}"
|
||||
format+="#{window_layout}"
|
||||
echo "$format"
|
||||
}
|
||||
|
||||
state_format() {
|
||||
local format
|
||||
format+="state"
|
||||
format+="${delimiter}"
|
||||
format+="#{client_session}"
|
||||
format+="${delimiter}"
|
||||
format+="#{client_last_session}"
|
||||
echo "$format"
|
||||
}
|
||||
|
||||
dump_panes_raw() {
|
||||
tmux list-panes -a -F "$(pane_format)"
|
||||
}
|
||||
|
||||
dump_windows_raw(){
|
||||
tmux list-windows -a -F "$(window_format)"
|
||||
}
|
||||
|
||||
toggle_window_zoom() {
|
||||
local target="$1"
|
||||
tmux resize-pane -Z -t "$target"
|
||||
}
|
||||
|
||||
_save_command_strategy_file() {
|
||||
local save_command_strategy="$(get_tmux_option "$save_command_strategy_option" "$default_save_command_strategy")"
|
||||
local strategy_file="$CURRENT_DIR/../save_command_strategies/${save_command_strategy}.sh"
|
||||
local default_strategy_file="$CURRENT_DIR/../save_command_strategies/${default_save_command_strategy}.sh"
|
||||
if [ -e "$strategy_file" ]; then # strategy file exists?
|
||||
echo "$strategy_file"
|
||||
else
|
||||
echo "$default_strategy_file"
|
||||
fi
|
||||
}
|
||||
|
||||
pane_full_command() {
|
||||
local pane_pid="$1"
|
||||
local strategy_file="$(_save_command_strategy_file)"
|
||||
# execute strategy script to get pane full command
|
||||
$strategy_file "$pane_pid"
|
||||
}
|
||||
|
||||
number_nonempty_lines_on_screen() {
|
||||
local pane_id="$1"
|
||||
tmux capture-pane -pJ -t "$pane_id" |
|
||||
sed '/^$/d' |
|
||||
wc -l |
|
||||
sed 's/ //g'
|
||||
}
|
||||
|
||||
# tests if there was any command output in the current pane
|
||||
pane_has_any_content() {
|
||||
local pane_id="$1"
|
||||
local history_size="$(tmux display -p -t "$pane_id" -F "#{history_size}")"
|
||||
local cursor_y="$(tmux display -p -t "$pane_id" -F "#{cursor_y}")"
|
||||
# doing "cheap" tests first
|
||||
[ "$history_size" -gt 0 ] || # history has any content?
|
||||
[ "$cursor_y" -gt 0 ] || # cursor not in first line?
|
||||
[ "$(number_nonempty_lines_on_screen "$pane_id")" -gt 1 ]
|
||||
}
|
||||
|
||||
capture_pane_contents() {
|
||||
local pane_id="$1"
|
||||
local start_line="-$2"
|
||||
local pane_contents_area="$3"
|
||||
if pane_has_any_content "$pane_id"; then
|
||||
if [ "$pane_contents_area" = "visible" ]; then
|
||||
start_line="0"
|
||||
fi
|
||||
# the printf hack below removes *trailing* empty lines
|
||||
printf '%s\n' "$(tmux capture-pane -epJ -S "$start_line" -t "$pane_id")" > "$(pane_contents_file "save" "$pane_id")"
|
||||
fi
|
||||
}
|
||||
|
||||
save_shell_history() {
|
||||
if [ "$pane_command" = "bash" ]; then
|
||||
local history_w='history -w'
|
||||
local history_r='history -r'
|
||||
local accept_line='C-m'
|
||||
local end_of_line='C-e'
|
||||
local backward_kill_line='C-u'
|
||||
elif [ "$pane_command" = "zsh" ]; then
|
||||
# fc -W does not work with -L
|
||||
# fc -l format is different from what's written by fc -W
|
||||
# fc -R either reads the format produced by fc -W or considers
|
||||
# the entire line to be a command. That's why we need -n.
|
||||
# fc -l only list the last 16 items by default, I think 64 is more reasonable.
|
||||
local history_w='fc -lLn -64 >'
|
||||
local history_r='fc -R'
|
||||
|
||||
local zsh_bindkey="$(zsh -i -c bindkey)"
|
||||
local accept_line="$(expr "$(echo "$zsh_bindkey" | grep -m1 '\saccept-line$')" : '^"\(.*\)".*')"
|
||||
local end_of_line="$(expr "$(echo "$zsh_bindkey" | grep -m1 '\send-of-line$')" : '^"\(.*\)".*')"
|
||||
local backward_kill_line="$(expr "$(echo "$zsh_bindkey" | grep -m1 '\sbackward-kill-line$')" : '^"\(.*\)".*')"
|
||||
else
|
||||
return
|
||||
fi
|
||||
|
||||
local pane_id="$1"
|
||||
local pane_command="$2"
|
||||
local full_command="$3"
|
||||
if [ "$full_command" = ":" ]; then
|
||||
# leading space prevents the command from being saved to history
|
||||
# (assuming default HISTCONTROL settings)
|
||||
local write_command=" $history_w '$(resurrect_history_file "$pane_id" "$pane_command")'"
|
||||
local read_command=" $history_r '$(resurrect_history_file "$pane_id" "$pane_command")'"
|
||||
# C-e C-u is a Bash shortcut sequence to clear whole line. It is necessary to
|
||||
# delete any pending input so it does not interfere with our history command.
|
||||
tmux send-keys -t "$pane_id" "$end_of_line" "$backward_kill_line" "$write_command" "$accept_line"
|
||||
# Immediately restore after saving
|
||||
tmux send-keys -t "$pane_id" "$end_of_line" "$backward_kill_line" "$read_command" "$accept_line"
|
||||
fi
|
||||
}
|
||||
|
||||
get_active_window_index() {
|
||||
local session_name="$1"
|
||||
tmux list-windows -t "$session_name" -F "#{window_flags} #{window_index}" |
|
||||
awk '$1 ~ /\*/ { print $2; }'
|
||||
}
|
||||
|
||||
get_alternate_window_index() {
|
||||
local session_name="$1"
|
||||
tmux list-windows -t "$session_name" -F "#{window_flags} #{window_index}" |
|
||||
awk '$1 ~ /-/ { print $2; }'
|
||||
}
|
||||
|
||||
dump_grouped_sessions() {
|
||||
local current_session_group=""
|
||||
local original_session
|
||||
tmux list-sessions -F "$(grouped_sessions_format)" |
|
||||
grep "^1" |
|
||||
cut -c 3- |
|
||||
sort |
|
||||
while IFS=$d read session_group session_id session_name; do
|
||||
if [ "$session_group" != "$current_session_group" ]; then
|
||||
# this session is the original/first session in the group
|
||||
original_session="$session_name"
|
||||
current_session_group="$session_group"
|
||||
else
|
||||
# this session "points" to the original session
|
||||
active_window_index="$(get_active_window_index "$session_name")"
|
||||
alternate_window_index="$(get_alternate_window_index "$session_name")"
|
||||
echo "grouped_session${d}${session_name}${d}${original_session}${d}:${alternate_window_index}${d}:${active_window_index}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
fetch_and_dump_grouped_sessions(){
|
||||
local grouped_sessions_dump="$(dump_grouped_sessions)"
|
||||
get_grouped_sessions "$grouped_sessions_dump"
|
||||
if [ -n "$grouped_sessions_dump" ]; then
|
||||
echo "$grouped_sessions_dump"
|
||||
fi
|
||||
}
|
||||
|
||||
# translates pane pid to process command running inside a pane
|
||||
dump_panes() {
|
||||
local full_command
|
||||
dump_panes_raw |
|
||||
while IFS=$d read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_pid history_size; do
|
||||
# not saving panes from grouped sessions
|
||||
if is_session_grouped "$session_name"; then
|
||||
continue
|
||||
fi
|
||||
full_command="$(pane_full_command $pane_pid)"
|
||||
dir=$(echo $dir | sed 's/ /\\ /') # escape all spaces in directory path
|
||||
echo "${line_type}${d}${session_name}${d}${window_number}${d}${window_name}${d}${window_active}${d}${window_flags}${d}${pane_index}${d}${dir}${d}${pane_active}${d}${pane_command}${d}:${full_command}"
|
||||
done
|
||||
}
|
||||
|
||||
dump_windows() {
|
||||
dump_windows_raw |
|
||||
while IFS=$d read line_type session_name window_index window_active window_flags window_layout; do
|
||||
# not saving windows from grouped sessions
|
||||
if is_session_grouped "$session_name"; then
|
||||
continue
|
||||
fi
|
||||
echo "${line_type}${d}${session_name}${d}${window_index}${d}${window_active}${d}${window_flags}${d}${window_layout}"
|
||||
done
|
||||
}
|
||||
|
||||
dump_state() {
|
||||
tmux display-message -p "$(state_format)"
|
||||
}
|
||||
|
||||
dump_pane_contents() {
|
||||
local pane_contents_area="$(get_tmux_option "$pane_contents_area_option" "$default_pane_contents_area")"
|
||||
dump_panes_raw |
|
||||
while IFS=$d read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_pid history_size; do
|
||||
capture_pane_contents "${session_name}:${window_number}.${pane_index}" "$history_size" "$pane_contents_area"
|
||||
done
|
||||
}
|
||||
|
||||
dump_shell_history() {
|
||||
dump_panes |
|
||||
while IFS=$d read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command full_command; do
|
||||
save_shell_history "$session_name:$window_number.$pane_index" "$pane_command" "$full_command"
|
||||
done
|
||||
}
|
||||
|
||||
remove_old_backups() {
|
||||
# remove resurrect files older than 30 days, but keep at least 5 copies of backup.
|
||||
local -a files
|
||||
files=($(ls -t $(resurrect_dir)/${RESURRECT_FILE_PREFIX}_*.${RESURRECT_FILE_EXTENSION} | tail -n +6))
|
||||
[[ ${#files[@]} -eq 0 ]] ||
|
||||
find "${files[@]}" -type f -mtime +30 -exec rm -v "{}" \;
|
||||
}
|
||||
|
||||
save_all() {
|
||||
local resurrect_file_path="$(resurrect_file_path)"
|
||||
local last_resurrect_file="$(last_resurrect_file)"
|
||||
mkdir -p "$(resurrect_dir)"
|
||||
fetch_and_dump_grouped_sessions > "$resurrect_file_path"
|
||||
dump_panes >> "$resurrect_file_path"
|
||||
dump_windows >> "$resurrect_file_path"
|
||||
dump_state >> "$resurrect_file_path"
|
||||
execute_hook "post-save-layout" "$resurrect_file_path"
|
||||
if files_differ "$resurrect_file_path" "$last_resurrect_file"; then
|
||||
ln -fs "$(basename "$resurrect_file_path")" "$last_resurrect_file"
|
||||
else
|
||||
rm "$resurrect_file_path"
|
||||
fi
|
||||
if capture_pane_contents_option_on; then
|
||||
mkdir -p "$(pane_contents_dir "save")"
|
||||
dump_pane_contents
|
||||
pane_contents_create_archive
|
||||
rm "$(pane_contents_dir "save")"/*
|
||||
fi
|
||||
if save_shell_history_option_on; then
|
||||
dump_shell_history
|
||||
fi
|
||||
remove_old_backups
|
||||
execute_hook "post-save-all"
|
||||
}
|
||||
|
||||
show_output() {
|
||||
[ "$SCRIPT_OUTPUT" != "quiet" ]
|
||||
}
|
||||
|
||||
main() {
|
||||
if supported_tmux_version_ok; then
|
||||
if show_output; then
|
||||
start_spinner "Saving..." "Tmux environment saved!"
|
||||
fi
|
||||
save_all
|
||||
if show_output; then
|
||||
stop_spinner
|
||||
display_message "Tmux environment saved!"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
main
|
||||
8
tmux/plugins/tmux-ressurect/scripts/spinner_helpers.sh
Normal file
8
tmux/plugins/tmux-ressurect/scripts/spinner_helpers.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
start_spinner() {
|
||||
$CURRENT_DIR/tmux_spinner.sh "$1" "$2" &
|
||||
export SPINNER_PID=$!
|
||||
}
|
||||
|
||||
stop_spinner() {
|
||||
kill $SPINNER_PID
|
||||
}
|
||||
29
tmux/plugins/tmux-ressurect/scripts/tmux_spinner.sh
Executable file
29
tmux/plugins/tmux-ressurect/scripts/tmux_spinner.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script shows tmux spinner with a message. It is intended to be running
|
||||
# as a background process which should be `kill`ed at the end.
|
||||
#
|
||||
# Example usage:
|
||||
#
|
||||
# ./tmux_spinner.sh "Working..." "End message!" &
|
||||
# SPINNER_PID=$!
|
||||
# ..
|
||||
# .. execute commands here
|
||||
# ..
|
||||
# kill $SPINNER_PID # Stops spinner and displays 'End message!'
|
||||
|
||||
MESSAGE="$1"
|
||||
END_MESSAGE="$2"
|
||||
SPIN='-\|/'
|
||||
|
||||
trap "tmux display-message '$END_MESSAGE'; exit" SIGINT SIGTERM
|
||||
|
||||
main() {
|
||||
local i=0
|
||||
while true; do
|
||||
i=$(( (i+1) %4 ))
|
||||
tmux display-message " ${SPIN:$i:1} $MESSAGE"
|
||||
sleep 0.1
|
||||
done
|
||||
}
|
||||
main
|
||||
47
tmux/plugins/tmux-ressurect/scripts/variables.sh
Normal file
47
tmux/plugins/tmux-ressurect/scripts/variables.sh
Normal file
@@ -0,0 +1,47 @@
|
||||
# key bindings
|
||||
default_save_key="C-s"
|
||||
save_option="@resurrect-save"
|
||||
save_path_option="@resurrect-save-script-path"
|
||||
|
||||
default_restore_key="C-r"
|
||||
restore_option="@resurrect-restore"
|
||||
restore_path_option="@resurrect-restore-script-path"
|
||||
|
||||
# default processes that are restored
|
||||
default_proc_list_option="@resurrect-default-processes"
|
||||
default_proc_list='vi vim nvim emacs man less more tail top htop irssi weechat mutt'
|
||||
|
||||
# User defined processes that are restored
|
||||
# 'false' - nothing is restored
|
||||
# ':all:' - all processes are restored
|
||||
#
|
||||
# user defined list of programs that are restored:
|
||||
# 'my_program foo another_program'
|
||||
restore_processes_option="@resurrect-processes"
|
||||
restore_processes=""
|
||||
|
||||
# Defines part of the user variable. Example usage:
|
||||
# set -g @resurrect-strategy-vim "session"
|
||||
restore_process_strategy_option="@resurrect-strategy-"
|
||||
|
||||
inline_strategy_token="->"
|
||||
|
||||
save_command_strategy_option="@resurrect-save-command-strategy"
|
||||
default_save_command_strategy="ps"
|
||||
|
||||
# Pane contents capture options.
|
||||
# @resurrect-pane-contents-area option can be:
|
||||
# 'visible' - capture only the visible pane area
|
||||
# 'full' - capture the full pane contents
|
||||
pane_contents_option="@resurrect-capture-pane-contents"
|
||||
pane_contents_area_option="@resurrect-pane-contents-area"
|
||||
default_pane_contents_area="full"
|
||||
|
||||
bash_history_option="@resurrect-save-bash-history" # deprecated
|
||||
shell_history_option="@resurrect-save-shell-history"
|
||||
|
||||
# set to 'on' to ensure panes are never ever overwritten
|
||||
overwrite_option="@resurrect-never-overwrite"
|
||||
|
||||
# Hooks are set via ${hook_prefix}${name}, i.e. "@resurrect-hook-post-save-all"
|
||||
hook_prefix="@resurrect-hook-"
|
||||
Reference in New Issue
Block a user