Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
beb54b62fb | |||
bd095e739d | |||
e2e55c6faa | |||
cedd1292c1 | |||
05cf790493 | |||
f9ef86d604 | |||
9a6e4a1a2c | |||
bd13c9bae8 | |||
87b2d75794 | |||
54f47a4015 | |||
eca38175ff | |||
b8b87a6e29 | |||
8cbc18e130 | |||
cfe8e7979b | |||
093627ce0a | |||
0da279e4cd | |||
884a5e9c19 | |||
8cb5b21e2f | |||
ee1ab0c728 | |||
18f4d1099e | |||
655bdb9a75 |
24
CHANGELOG.md
24
CHANGELOG.md
@ -2,6 +2,30 @@
|
|||||||
|
|
||||||
### master
|
### master
|
||||||
|
|
||||||
|
### v0.4.0, 2014-08-29
|
||||||
|
- change plugin name to `tmux-resurrect`. Change all the variable names.
|
||||||
|
|
||||||
|
### v0.3.0, 2014-08-29
|
||||||
|
- bugfix: when top is running the pane `$PWD` can't be saved. This was causing
|
||||||
|
issues during the restore and is now fixed.
|
||||||
|
- restoring sessions multiple times messes up the whole environment - new panes
|
||||||
|
are all around. This is now fixed - pane restorations are now idempotent.
|
||||||
|
- if pane exists from before session restore - do not restore the process within
|
||||||
|
it. This makes the restoration process even more idempotent.
|
||||||
|
- more panes within a window can now be restored
|
||||||
|
- restore window zoom state
|
||||||
|
|
||||||
|
### v0.2.0, 2014-08-29
|
||||||
|
- bugfix: with vim 'session' strategy, if the session file does not exist - make
|
||||||
|
sure vim does not contain `-S` flag
|
||||||
|
- enable restoring programs with arguments (e.g. "rails console") and also
|
||||||
|
processes that contain program name
|
||||||
|
- improve `irb` restore strategy
|
||||||
|
|
||||||
|
### v0.1.0, 2014-08-28
|
||||||
|
- refactor checking if saved tmux session exists
|
||||||
|
- spinner while tmux sessions are restored
|
||||||
|
|
||||||
### v0.0.5, 2014-08-28
|
### v0.0.5, 2014-08-28
|
||||||
- restore pane processes
|
- restore pane processes
|
||||||
- user option for disabling pane process restoring
|
- user option for disabling pane process restoring
|
||||||
|
12
CONTRIBUTING.md
Normal file
12
CONTRIBUTING.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
### Contributing
|
||||||
|
|
||||||
|
Code contributions are welcome!
|
||||||
|
|
||||||
|
### Reporting a bug
|
||||||
|
|
||||||
|
If you find a bug please report it in the issues. When reporting a bug please
|
||||||
|
attach:
|
||||||
|
- a file symlinked to `~/.tmux/resurrect/last`.
|
||||||
|
- your `.tmux.conf`
|
||||||
|
- if you're getting an error paste it to a [gist](https://gist.github.com/) and
|
||||||
|
link it in the issue
|
57
README.md
57
README.md
@ -1,17 +1,18 @@
|
|||||||
# Tmux Session Saver
|
# Tmux Resurrect
|
||||||
|
|
||||||
Persists `tmux` environment across system restarts.
|
Restore `tmux` environment after a system restart.
|
||||||
|
|
||||||
Tmux is great, except when you have to restart your computer. You loose all the
|
Tmux is great, except when you have to restart the computer. You loose all the
|
||||||
running programs, working directories, pane layouts etc.
|
running programs, working directories, pane layouts etc.
|
||||||
There are helpful management tools out there, but they require initial
|
There are helpful management tools out there, but they require initial
|
||||||
configuration and continuous updates as your workflow evolves or you start new
|
configuration and continuous updates as your workflow evolves or you start new
|
||||||
projects.
|
projects.
|
||||||
|
|
||||||
Enter `tmux-session-saver`: tmux persistence without configuration so there are
|
`tmux-resurrect` saves all the little details from tmux environment so it
|
||||||
no interruptions in your workflow.
|
can be completely restored after a system restart. No configuration is required.
|
||||||
|
You should feel like you never quit tmux.
|
||||||
|
|
||||||
It will even (optionally) [restore vim sessions](#restoring-vim-sessions)!
|
It even (optionally) [restores vim sessions](#restoring-vim-sessions)!
|
||||||
|
|
||||||
### Key bindings
|
### Key bindings
|
||||||
|
|
||||||
@ -28,8 +29,10 @@ This plugin goes to great lengths to save and restore all the details from your
|
|||||||
- **exact pane layouts** within windows
|
- **exact pane layouts** within windows
|
||||||
- active and alternative session
|
- active and alternative session
|
||||||
- active and alternative window for each session
|
- active and alternative window for each session
|
||||||
|
- windows with focus
|
||||||
- active pane for each window
|
- active pane for each window
|
||||||
- programs running within a pane! More details in the [configuration section](#configuration).
|
- programs running within a pane! More details in the
|
||||||
|
[configuration section](#configuration).
|
||||||
- restoring vim sessions (optional). More details in
|
- restoring vim sessions (optional). More details in
|
||||||
[restoring vim sessions](#restoring-vim-sessions).
|
[restoring vim sessions](#restoring-vim-sessions).
|
||||||
|
|
||||||
@ -41,7 +44,7 @@ Add plugin to the list of TPM plugins in `.tmux.conf`:
|
|||||||
|
|
||||||
set -g @tpm_plugins " \
|
set -g @tpm_plugins " \
|
||||||
tmux-plugins/tpm \
|
tmux-plugins/tpm \
|
||||||
tmux-plugins/tmux-session-saver \
|
tmux-plugins/tmux-resurrect \
|
||||||
"
|
"
|
||||||
|
|
||||||
Hit `prefix + I` to fetch the plugin and source it. You should now be able to
|
Hit `prefix + I` to fetch the plugin and source it. You should now be able to
|
||||||
@ -51,11 +54,11 @@ use the plugin.
|
|||||||
|
|
||||||
Clone the repo:
|
Clone the repo:
|
||||||
|
|
||||||
$ git clone https://github.com/tmux-plugins/tmux-session-saver ~/clone/path
|
$ git clone https://github.com/tmux-plugins/tmux-resurrect ~/clone/path
|
||||||
|
|
||||||
Add this line to the bottom of `.tmux.conf`:
|
Add this line to the bottom of `.tmux.conf`:
|
||||||
|
|
||||||
run-shell ~/clone/path/session_saver.tmux
|
run-shell ~/clone/path/resurrect.tmux
|
||||||
|
|
||||||
Reload TMUX environment:
|
Reload TMUX environment:
|
||||||
|
|
||||||
@ -66,38 +69,46 @@ You should now be able to use the plugin.
|
|||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
By default, only a conservative list of programs is restored:
|
Configuration is not required - but it enables extra features.
|
||||||
`vim emacs man less more tail top htop irssi`.
|
|
||||||
|
Only a conservative list of programs is restored by default:<br/>
|
||||||
|
`vi vim emacs man less more tail top htop irssi irb pry "~rails console"`.
|
||||||
Open a github issue if you think some other program should be on the default list.
|
Open a github issue if you think some other program should be on the default list.
|
||||||
|
|
||||||
- Restore additional programs by putting the following in `.tmux.conf`:
|
- Restore additional programs with the setting in `.tmux.conf`:
|
||||||
|
|
||||||
set -g @session-saver-processes 'ssh telnet myprogram'
|
set -g @resurrect-processes 'ssh psql mysql sqlite3'
|
||||||
|
|
||||||
|
- Programs with arguments should be double quoted:
|
||||||
|
|
||||||
|
set -g @resurrect-processes 'some_program "git log"'
|
||||||
|
|
||||||
|
- Start with tilde to restore a program whose process contains target name:
|
||||||
|
|
||||||
|
set -g @resurrect-processes 'some_program "~rails server"'
|
||||||
|
|
||||||
- Don't restore any programs:
|
- Don't restore any programs:
|
||||||
|
|
||||||
set -g @session-saver-processes 'false'
|
set -g @resurrect-processes 'false'
|
||||||
|
|
||||||
- Restore **all** programs (be careful with this!):
|
- Restore **all** programs (be careful with this!):
|
||||||
|
|
||||||
set -g @session-saver-processes ':all:'
|
set -g @resurrect-processes ':all:'
|
||||||
|
|
||||||
#### Restoring vim sessions
|
#### Restoring vim sessions
|
||||||
|
|
||||||
- save vim sessions - I recommend [tpope/vim-obsession](tpope/vim-obsession)
|
- save vim sessions. I recommend [tpope/vim-obsession](tpope/vim-obsession).
|
||||||
- in `.tmux.conf`:
|
- in `.tmux.conf`:
|
||||||
|
|
||||||
set -g @session-saver-strategy-vim "session"
|
set -g @resurrect-strategy-vim "session"
|
||||||
|
|
||||||
`tmux-session-saver` will now restore vim sessions if `Sessions.vim` file is
|
`tmux-resurrect` will now restore vim sessions if `Sessions.vim` file is
|
||||||
present.
|
present.
|
||||||
|
|
||||||
### Reporting bugs and contributing
|
### Reporting bugs and contributing
|
||||||
|
|
||||||
Code contributions are welcome!
|
Both contributing and bug reports are welcome. Please check out
|
||||||
|
[contributing guidelines](CONTRIBUTING.md).
|
||||||
If you find a bug please report it in the issues. When reporting a bug please
|
|
||||||
attach a file symlinked to `~/.tmux/sessions/last`.
|
|
||||||
|
|
||||||
### Credits
|
### Credits
|
||||||
|
|
||||||
|
@ -2,19 +2,14 @@
|
|||||||
|
|
||||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
source "$CURRENT_DIR/scripts/variables.sh"
|
||||||
source "$CURRENT_DIR/scripts/helpers.sh"
|
source "$CURRENT_DIR/scripts/helpers.sh"
|
||||||
|
|
||||||
default_save_key="M-s"
|
|
||||||
save_option="@session-saver-save"
|
|
||||||
|
|
||||||
default_restore_key="M-r"
|
|
||||||
restore_option="@session-saver-restore"
|
|
||||||
|
|
||||||
set_save_bindings() {
|
set_save_bindings() {
|
||||||
local key_bindings=$(get_tmux_option "$save_option" "$default_save_key")
|
local key_bindings=$(get_tmux_option "$save_option" "$default_save_key")
|
||||||
local key
|
local key
|
||||||
for key in $key_bindings; do
|
for key in $key_bindings; do
|
||||||
tmux bind-key "$key" run-shell "$CURRENT_DIR/scripts/session_saver.sh"
|
tmux bind-key "$key" run-shell "$CURRENT_DIR/scripts/save.sh"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,12 +17,17 @@ set_restore_bindings() {
|
|||||||
local key_bindings=$(get_tmux_option "$restore_option" "$default_restore_key")
|
local key_bindings=$(get_tmux_option "$restore_option" "$default_restore_key")
|
||||||
local key
|
local key
|
||||||
for key in $key_bindings; do
|
for key in $key_bindings; do
|
||||||
tmux bind-key "$key" run-shell "$CURRENT_DIR/scripts/session_restorer.sh"
|
tmux bind-key "$key" run-shell "$CURRENT_DIR/scripts/restore.sh"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_default_strategies() {
|
||||||
|
tmux set-option -g "${restore_process_strategy_option}irb" "default_strategy"
|
||||||
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
set_save_bindings
|
set_save_bindings
|
||||||
set_restore_bindings
|
set_restore_bindings
|
||||||
|
set_default_strategies
|
||||||
}
|
}
|
||||||
main
|
main
|
@ -1,6 +1,5 @@
|
|||||||
# configurable constants
|
default_resurrect_dir="$HOME/.tmux/resurrect"
|
||||||
default_sessions_dir="$HOME/.tmux/sessions"
|
resurrect_dir_option="@resurrect-dir"
|
||||||
sessions_dir_option="@session-saver-dir"
|
|
||||||
|
|
||||||
SUPPORTED_VERSION="1.9"
|
SUPPORTED_VERSION="1.9"
|
||||||
|
|
||||||
@ -46,17 +45,21 @@ supported_tmux_version_ok() {
|
|||||||
$CURRENT_DIR/check_tmux_version.sh "$SUPPORTED_VERSION"
|
$CURRENT_DIR/check_tmux_version.sh "$SUPPORTED_VERSION"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remove_first_char() {
|
||||||
|
echo "$1" | cut -c2-
|
||||||
|
}
|
||||||
|
|
||||||
# path helpers
|
# path helpers
|
||||||
|
|
||||||
sessions_dir() {
|
resurrect_dir() {
|
||||||
echo $(get_tmux_option "$sessions_dir_option" "$default_sessions_dir")
|
echo $(get_tmux_option "$resurrect_dir_option" "$default_resurrect_dir")
|
||||||
}
|
}
|
||||||
|
|
||||||
session_path() {
|
resurrect_file_path() {
|
||||||
local timestamp="$(date +"%Y-%m-%dT%H:%M:%S")"
|
local timestamp="$(date +"%Y-%m-%dT%H:%M:%S")"
|
||||||
echo "$(sessions_dir)/tmux_session_${timestamp}.txt"
|
echo "$(resurrect_dir)/tmux_resurrect_${timestamp}.txt"
|
||||||
}
|
}
|
||||||
|
|
||||||
last_session_path() {
|
last_resurrect_file() {
|
||||||
echo "$(sessions_dir)/last"
|
echo "$(resurrect_dir)/last"
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,3 @@
|
|||||||
# default processes that are restored
|
|
||||||
default_proc_list_option="@session-saver-default-processes"
|
|
||||||
default_proc_list="vim emacs man less more tail top htop irssi"
|
|
||||||
|
|
||||||
# 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="@session-saver-processes"
|
|
||||||
restore_processes=""
|
|
||||||
|
|
||||||
# Defines part of the user variable. Example usage:
|
|
||||||
# set -g @session-saver-strategy-vim "session"
|
|
||||||
restore_process_strategy_option="@session-saver-strategy-"
|
|
||||||
|
|
||||||
restore_pane_processes_enabled() {
|
restore_pane_processes_enabled() {
|
||||||
local restore_processes="$(get_tmux_option "$restore_processes_option" "$restore_processes")"
|
local restore_processes="$(get_tmux_option "$restore_processes_option" "$restore_processes")"
|
||||||
if [ "$restore_processes" == "false" ]; then
|
if [ "$restore_processes" == "false" ]; then
|
||||||
@ -30,7 +13,7 @@ restore_pane_process() {
|
|||||||
local window_number="$3"
|
local window_number="$3"
|
||||||
local pane_index="$4"
|
local pane_index="$4"
|
||||||
local dir="$5"
|
local dir="$5"
|
||||||
if _process_should_be_restored "$pane_full_command"; then
|
if _process_should_be_restored "$pane_full_command" "$session_name" "$window_number" "$pane_index"; then
|
||||||
tmux switch-client -t "${session_name}:${window_number}"
|
tmux switch-client -t "${session_name}:${window_number}"
|
||||||
tmux select-pane -t "$pane_index"
|
tmux select-pane -t "$pane_index"
|
||||||
|
|
||||||
@ -38,8 +21,6 @@ restore_pane_process() {
|
|||||||
local strategy_file="$(_get_strategy_file "$pane_full_command")"
|
local strategy_file="$(_get_strategy_file "$pane_full_command")"
|
||||||
local strategy_command="$($strategy_file "$pane_full_command" "$dir")"
|
local strategy_command="$($strategy_file "$pane_full_command" "$dir")"
|
||||||
tmux send-keys "$strategy_command" "C-m"
|
tmux send-keys "$strategy_command" "C-m"
|
||||||
# tmux send-keys "Strategy! $pane_full_command $strategy_file"
|
|
||||||
# tmux send-keys "Strategy! $strategy_command"
|
|
||||||
else
|
else
|
||||||
# just invoke the command
|
# just invoke the command
|
||||||
tmux send-keys "$pane_full_command" "C-m"
|
tmux send-keys "$pane_full_command" "C-m"
|
||||||
@ -51,7 +32,14 @@ restore_pane_process() {
|
|||||||
|
|
||||||
_process_should_be_restored() {
|
_process_should_be_restored() {
|
||||||
local pane_full_command="$1"
|
local pane_full_command="$1"
|
||||||
if _restore_all_processes; then
|
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 _restore_all_processes; then
|
||||||
return 0
|
return 0
|
||||||
elif _process_on_the_restore_list "$pane_full_command"; then
|
elif _process_on_the_restore_list "$pane_full_command"; then
|
||||||
return 0
|
return 0
|
||||||
@ -71,12 +59,22 @@ _restore_all_processes() {
|
|||||||
|
|
||||||
_process_on_the_restore_list() {
|
_process_on_the_restore_list() {
|
||||||
local pane_full_command="$1"
|
local pane_full_command="$1"
|
||||||
local restore_list="$(_restore_list)"
|
# TODO: make this work without eval
|
||||||
|
eval set $(_restore_list)
|
||||||
local proc
|
local proc
|
||||||
for proc in $restore_list; do
|
for proc in "$@"; do
|
||||||
if [[ "$pane_full_command" =~ (^$proc) ]]; then
|
if _proc_starts_with_tildae "$proc"; then
|
||||||
|
proc="$(remove_first_char "$proc")"
|
||||||
|
# regex matching the command makes sure `$proc` string is somewhere the command string
|
||||||
|
if [[ "$pane_full_command" =~ ($proc) ]]; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
# regex matching the command makes sure process is a "word"
|
||||||
|
if [[ "$pane_full_command" =~ (^${proc} ) ]] || [[ "$pane_full_command" =~ (^${proc}$) ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
@ -92,6 +90,10 @@ _restore_list() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_proc_starts_with_tildae() {
|
||||||
|
[[ "$1" =~ (^~) ]]
|
||||||
|
}
|
||||||
|
|
||||||
_strategy_exists() {
|
_strategy_exists() {
|
||||||
local pane_full_command="$1"
|
local pane_full_command="$1"
|
||||||
local strategy="$(_get_command_strategy "$pane_full_command")"
|
local strategy="$(_get_command_strategy "$pane_full_command")"
|
||||||
|
@ -2,8 +2,16 @@
|
|||||||
|
|
||||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
source "$CURRENT_DIR/variables.sh"
|
||||||
source "$CURRENT_DIR/helpers.sh"
|
source "$CURRENT_DIR/helpers.sh"
|
||||||
source "$CURRENT_DIR/process_restore_helpers.sh"
|
source "$CURRENT_DIR/process_restore_helpers.sh"
|
||||||
|
source "$CURRENT_DIR/spinner_helpers.sh"
|
||||||
|
|
||||||
|
# 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=""
|
||||||
|
|
||||||
is_line_type() {
|
is_line_type() {
|
||||||
local line_type="$1"
|
local line_type="$1"
|
||||||
@ -13,13 +21,38 @@ is_line_type() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_saved_session_exists() {
|
check_saved_session_exists() {
|
||||||
local saved_session="$(last_session_path)"
|
local resurrect_file="$(last_resurrect_file)"
|
||||||
if [ ! -f $saved_session ]; then
|
if [ ! -f $resurrect_file ]; then
|
||||||
display_message "Saved session not found!"
|
display_message "Tmux resurrect file not found!"
|
||||||
exit
|
return 1
|
||||||
fi
|
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" ]]
|
||||||
|
}
|
||||||
|
|
||||||
window_exists() {
|
window_exists() {
|
||||||
local session_name="$1"
|
local session_name="$1"
|
||||||
local window_number="$2"
|
local window_number="$2"
|
||||||
@ -40,10 +73,6 @@ tmux_socket() {
|
|||||||
echo $TMUX | cut -d',' -f1
|
echo $TMUX | cut -d',' -f1
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_first_char() {
|
|
||||||
echo "$1" | cut -c2-
|
|
||||||
}
|
|
||||||
|
|
||||||
new_window() {
|
new_window() {
|
||||||
local session_name="$1"
|
local session_name="$1"
|
||||||
local window_number="$2"
|
local window_number="$2"
|
||||||
@ -70,23 +99,28 @@ new_pane() {
|
|||||||
local window_number="$2"
|
local window_number="$2"
|
||||||
local window_name="$3"
|
local window_name="$3"
|
||||||
local dir="$4"
|
local dir="$4"
|
||||||
tmux split-window -t "${session_name}:${window_number}" -c "$dir"
|
tmux split-window -t "${session_name}:${window_number}" -c "$dir" -h
|
||||||
|
tmux resize-pane -t "${session_name}:${window_number}" -L "999"
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_pane() {
|
restore_pane() {
|
||||||
local pane="$1"
|
local pane="$1"
|
||||||
echo "$pane" |
|
|
||||||
while IFS=$'\t' read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_full_command; do
|
while IFS=$'\t' 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")"
|
window_name="$(remove_first_char "$window_name")"
|
||||||
pane_full_command="$(remove_first_char "$pane_full_command")"
|
pane_full_command="$(remove_first_char "$pane_full_command")"
|
||||||
if window_exists "$session_name" "$window_number"; then
|
if pane_exists "$session_name" "$window_number" "$pane_index"; then
|
||||||
|
# Pane exists, no need to create it!
|
||||||
|
# Pane existence is registered. Later, it's process also isn't restored.
|
||||||
|
register_existing_pane "$session_name" "$window_number" "$pane_index"
|
||||||
|
elif window_exists "$session_name" "$window_number"; then
|
||||||
new_pane "$session_name" "$window_number" "$window_name" "$dir"
|
new_pane "$session_name" "$window_number" "$window_name" "$dir"
|
||||||
elif session_exists "$session_name"; then
|
elif session_exists "$session_name"; then
|
||||||
new_window "$session_name" "$window_number" "$window_name" "$dir"
|
new_window "$session_name" "$window_number" "$window_name" "$dir"
|
||||||
else
|
else
|
||||||
new_session "$session_name" "$window_number" "$window_name" "$dir"
|
new_session "$session_name" "$window_number" "$window_name" "$dir"
|
||||||
fi
|
fi
|
||||||
done
|
done < <(echo "$pane")
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_state() {
|
restore_state() {
|
||||||
@ -98,19 +132,20 @@ restore_state() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_all_sessions() {
|
restore_all_panes() {
|
||||||
while read line; do
|
while read line; do
|
||||||
if is_line_type "pane" "$line"; then
|
if is_line_type "pane" "$line"; then
|
||||||
restore_pane "$line"
|
restore_pane "$line"
|
||||||
fi
|
fi
|
||||||
done < $(last_session_path)
|
done < $(last_resurrect_file)
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_all_pane_processes() {
|
restore_all_pane_processes() {
|
||||||
if restore_pane_processes_enabled; then
|
if restore_pane_processes_enabled; then
|
||||||
local pane_full_command
|
local pane_full_command
|
||||||
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $11 !~ "^:$" { print $2, $3, $7, $8, $11; }' $(last_session_path) |
|
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $11 !~ "^:$" { print $2, $3, $7, $8, $11; }' $(last_resurrect_file) |
|
||||||
while IFS=$'\t' read session_name window_number pane_index dir pane_full_command; do
|
while IFS=$'\t' 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")"
|
pane_full_command="$(remove_first_char "$pane_full_command")"
|
||||||
restore_pane_process "$pane_full_command" "$session_name" "$window_number" "$pane_index" "$dir"
|
restore_pane_process "$pane_full_command" "$session_name" "$window_number" "$pane_index" "$dir"
|
||||||
done
|
done
|
||||||
@ -118,22 +153,29 @@ restore_all_pane_processes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
restore_pane_layout_for_each_window() {
|
restore_pane_layout_for_each_window() {
|
||||||
\grep '^window' $(last_session_path) |
|
\grep '^window' $(last_resurrect_file) |
|
||||||
while IFS=$'\t' read line_type session_name window_number window_active window_flags window_layout; do
|
while IFS=$'\t' read line_type session_name window_number window_active window_flags window_layout; do
|
||||||
tmux select-layout -t "${session_name}:${window_number}" "$window_layout"
|
tmux select-layout -t "${session_name}:${window_number}" "$window_layout"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_active_pane_for_each_window() {
|
restore_active_pane_for_each_window() {
|
||||||
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $7 != 0 && $9 == 1 { print $2, $3, $7; }' $(last_session_path) |
|
awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $9 == 1 { print $2, $3, $7; }' $(last_resurrect_file) |
|
||||||
while IFS=$'\t' read session_name window_number active_pane; do
|
while IFS=$'\t' read session_name window_number active_pane; do
|
||||||
tmux switch-client -t "${session_name}:${window_number}"
|
tmux switch-client -t "${session_name}:${window_number}"
|
||||||
tmux select-pane -t "$active_pane"
|
tmux select-pane -t "$active_pane"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
restore_zoomed_windows() {
|
||||||
|
awk 'BEGIN { FS="\t"; OFS="\t" } /^window/ && $5 ~ /Z/ { print $2, $3; }' $(last_resurrect_file) |
|
||||||
|
while IFS=$'\t' read session_name window_number; do
|
||||||
|
tmux resize-pane -t "${session_name}:${window_number}" -Z
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
restore_active_and_alternate_windows() {
|
restore_active_and_alternate_windows() {
|
||||||
awk 'BEGIN { FS="\t"; OFS="\t" } /^window/ && $5 ~ /[*-]/ { print $2, $4, $3; }' $(last_session_path) |
|
awk 'BEGIN { FS="\t"; OFS="\t" } /^window/ && $5 ~ /[*-]/ { print $2, $4, $3; }' $(last_resurrect_file) |
|
||||||
sort -u |
|
sort -u |
|
||||||
while IFS=$'\t' read session_name active_window window_number; do
|
while IFS=$'\t' read session_name active_window window_number; do
|
||||||
tmux switch-client -t "${session_name}:${window_number}"
|
tmux switch-client -t "${session_name}:${window_number}"
|
||||||
@ -145,20 +187,22 @@ restore_active_and_alternate_sessions() {
|
|||||||
if is_line_type "state" "$line"; then
|
if is_line_type "state" "$line"; then
|
||||||
restore_state "$line"
|
restore_state "$line"
|
||||||
fi
|
fi
|
||||||
done < $(last_session_path)
|
done < $(last_resurrect_file)
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
if supported_tmux_version_ok; then
|
if supported_tmux_version_ok && check_saved_session_exists; then
|
||||||
check_saved_session_exists
|
start_spinner
|
||||||
restore_all_sessions
|
restore_all_panes
|
||||||
restore_all_pane_processes
|
|
||||||
restore_pane_layout_for_each_window >/dev/null 2>&1
|
restore_pane_layout_for_each_window >/dev/null 2>&1
|
||||||
|
restore_all_pane_processes
|
||||||
# below functions restore exact cursor positions
|
# below functions restore exact cursor positions
|
||||||
restore_active_pane_for_each_window
|
restore_active_pane_for_each_window
|
||||||
|
restore_zoomed_windows
|
||||||
restore_active_and_alternate_windows
|
restore_active_and_alternate_windows
|
||||||
restore_active_and_alternate_sessions
|
restore_active_and_alternate_sessions
|
||||||
display_message "Restored all Tmux sessions!"
|
stop_spinner
|
||||||
|
display_message "Tmux restore complete!"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
main
|
main
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
source "$CURRENT_DIR/scripts/variables.sh"
|
||||||
source "$CURRENT_DIR/helpers.sh"
|
source "$CURRENT_DIR/helpers.sh"
|
||||||
|
|
||||||
pane_format() {
|
pane_format() {
|
||||||
@ -21,7 +22,7 @@ pane_format() {
|
|||||||
format+="${delimiter}"
|
format+="${delimiter}"
|
||||||
format+="#{pane_index}"
|
format+="#{pane_index}"
|
||||||
format+="${delimiter}"
|
format+="${delimiter}"
|
||||||
format+="#{pane_current_path}"
|
format+=":#{pane_current_path}"
|
||||||
format+="${delimiter}"
|
format+="${delimiter}"
|
||||||
format+="#{pane_active}"
|
format+="#{pane_active}"
|
||||||
format+="${delimiter}"
|
format+="${delimiter}"
|
||||||
@ -88,19 +89,19 @@ dump_state() {
|
|||||||
tmux display-message -p "$(state_format)"
|
tmux display-message -p "$(state_format)"
|
||||||
}
|
}
|
||||||
|
|
||||||
save_all_sessions() {
|
save_all() {
|
||||||
local session_path="$(session_path)"
|
local resurrect_file_path="$(resurrect_file_path)"
|
||||||
mkdir -p "$(sessions_dir)"
|
mkdir -p "$(resurrect_dir)"
|
||||||
dump_panes > $session_path
|
dump_panes > $resurrect_file_path
|
||||||
dump_windows >> $session_path
|
dump_windows >> $resurrect_file_path
|
||||||
dump_state >> $session_path
|
dump_state >> $resurrect_file_path
|
||||||
ln -fs "$session_path" "$(last_session_path)"
|
ln -fs "$resurrect_file_path" "$(last_resurrect_file)"
|
||||||
display_message "Saved all Tmux sessions!"
|
display_message "Tmux environment saved!"
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
if supported_tmux_version_ok; then
|
if supported_tmux_version_ok; then
|
||||||
save_all_sessions
|
save_all
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
main
|
main
|
8
scripts/spinner_helpers.sh
Normal file
8
scripts/spinner_helpers.sh
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
start_spinner() {
|
||||||
|
$CURRENT_DIR/tmux_spinner.sh "Restoring tmux..." "Tmux restore complete!" &
|
||||||
|
export SPINNER_PID=$!
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_spinner() {
|
||||||
|
kill $SPINNER_PID
|
||||||
|
}
|
29
scripts/tmux_spinner.sh
Executable file
29
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
|
23
scripts/variables.sh
Normal file
23
scripts/variables.sh
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# key bindings
|
||||||
|
default_save_key="M-s"
|
||||||
|
save_option="@resurrect-save"
|
||||||
|
|
||||||
|
default_restore_key="M-r"
|
||||||
|
restore_option="@resurrect-restore"
|
||||||
|
|
||||||
|
# default processes that are restored
|
||||||
|
default_proc_list_option="@resurrect-default-processes"
|
||||||
|
default_proc_list='vi vim emacs man less more tail top htop irssi irb pry "~rails console"'
|
||||||
|
|
||||||
|
# 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-"
|
23
strategies/irb_default_strategy.sh
Executable file
23
strategies/irb_default_strategy.sh
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# "irb default strategy"
|
||||||
|
#
|
||||||
|
# Example irb process with junk variables:
|
||||||
|
# irb RBENV_VERSION=1.9.3-p429 GREP_COLOR=34;47 TERM_PROGRAM=Apple_Terminal
|
||||||
|
#
|
||||||
|
# When executed, the above will fail. This strategy handles that.
|
||||||
|
|
||||||
|
ORIGINAL_COMMAND="$1"
|
||||||
|
DIRECTORY="$2"
|
||||||
|
|
||||||
|
original_command_wo_junk_vars() {
|
||||||
|
echo "$ORIGINAL_COMMAND" |
|
||||||
|
sed 's/RBENV_VERSION[^ ]*//' |
|
||||||
|
sed 's/GREP_COLOR[^ ]*//' |
|
||||||
|
sed 's/TERM_PROGRAM[^ ]*//'
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
echo "$(original_command_wo_junk_vars)"
|
||||||
|
}
|
||||||
|
main
|
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# Restores a vim session from 'Session.vim' file, if it exists.
|
# Restores a vim session from 'Session.vim' file, if it exists.
|
||||||
# If 'Session.vim' does not exist, it falls back to invoking the original
|
# If 'Session.vim' does not exist, it falls back to invoking the original
|
||||||
# command.
|
# command (without the `-S` flag).
|
||||||
|
|
||||||
ORIGINAL_COMMAND="$1"
|
ORIGINAL_COMMAND="$1"
|
||||||
DIRECTORY="$2"
|
DIRECTORY="$2"
|
||||||
@ -13,9 +13,18 @@ vim_session_file_exists() {
|
|||||||
[ -e "${DIRECTORY}/Session.vim" ]
|
[ -e "${DIRECTORY}/Session.vim" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
original_command_contains_session_flag() {
|
||||||
|
[[ "$ORIGINAL_COMMAND" =~ "-S" ]]
|
||||||
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
if vim_session_file_exists; then
|
if vim_session_file_exists; then
|
||||||
echo "vim -S"
|
echo "vim -S"
|
||||||
|
elif original_command_contains_session_flag; then
|
||||||
|
# Session file does not exist, yet the original vim command contains
|
||||||
|
# session flag `-S`. This will cause an error, so we're falling back to
|
||||||
|
# starting plain vim.
|
||||||
|
echo "vim"
|
||||||
else
|
else
|
||||||
echo "$ORIGINAL_COMMAND"
|
echo "$ORIGINAL_COMMAND"
|
||||||
fi
|
fi
|
||||||
|
Reference in New Issue
Block a user