Compare commits
65 Commits
Author | SHA1 | Date | |
---|---|---|---|
db05b2133b | |||
8368355240 | |||
20c5fc40cc | |||
af3cb5db2e | |||
deb3e9fdce | |||
3682cf6170 | |||
6255154190 | |||
a6eb17f8fd | |||
27b9b41e21 | |||
4d5557d599 | |||
f5cfa2daa7 | |||
f2533ec0ef | |||
d0f6f6ca30 | |||
34a1b4647d | |||
a68a786a73 | |||
19c981545e | |||
571bcb8173 | |||
2b259cf11a | |||
f9ad59900a | |||
beb54b62fb | |||
bd095e739d | |||
e2e55c6faa | |||
cedd1292c1 | |||
05cf790493 | |||
f9ef86d604 | |||
9a6e4a1a2c | |||
bd13c9bae8 | |||
87b2d75794 | |||
54f47a4015 | |||
eca38175ff | |||
b8b87a6e29 | |||
8cbc18e130 | |||
cfe8e7979b | |||
093627ce0a | |||
0da279e4cd | |||
884a5e9c19 | |||
8cb5b21e2f | |||
ee1ab0c728 | |||
18f4d1099e | |||
655bdb9a75 | |||
3da5d61b5b | |||
5509256a02 | |||
cde50d4d92 | |||
07bba0fde7 | |||
1e945c2cac | |||
7f50660918 | |||
cbf58ac613 | |||
2edd3ff98d | |||
bcad7cd1ea | |||
4d5c0a2a0d | |||
8051fb9d36 | |||
a649614a20 | |||
8166fa2602 | |||
ecc42c5a56 | |||
aa8f323b8b | |||
c78a38803a | |||
877780eb02 | |||
8ba7d6d873 | |||
c993e9ff00 | |||
81ed0811b4 | |||
732d53cede | |||
5c2853a55f | |||
70d78e8d73 | |||
1280e659d5 | |||
3dce66acaa |
66
CHANGELOG.md
66
CHANGELOG.md
@ -1,4 +1,68 @@
|
||||
# Changelog
|
||||
|
||||
# master
|
||||
### master
|
||||
|
||||
### v1.2.0, 2014-09-01
|
||||
- new feature: inline strategies when restoring a program
|
||||
|
||||
### v1.1.0, 2014-08-31
|
||||
- bugfix: sourcing `variables.sh` file in save script
|
||||
- add `Ctrl` key mappings, deprecate `Alt` keys mappings.
|
||||
|
||||
### v1.0.0, 2014-08-30
|
||||
- show spinner during the save process
|
||||
- add screencast script
|
||||
- make default program running list even more conservative
|
||||
|
||||
### 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
|
||||
- restore pane processes
|
||||
- user option for disabling pane process restoring
|
||||
- enable whitelisting processes that will be restored
|
||||
- expand readme with configuration options
|
||||
- enable command strategies; enable restoring vim sessions
|
||||
- update readme: explain restoring vim sessions
|
||||
|
||||
### v0.0.4, 2014-08-26
|
||||
- restore pane layout for each window
|
||||
- bugfix: correct pane ordering in a window
|
||||
|
||||
### v0.0.3, 2014-08-26
|
||||
- save and restore current and alternate session
|
||||
- fix a bug with non-existing window names
|
||||
- restore active pane for each window that has multiple panes
|
||||
- restore active and alternate window for each session
|
||||
|
||||
### v0.0.2, 2014-08-26
|
||||
- saving a new session does not remove the previous one
|
||||
- make the directory where sessions are stored configurable
|
||||
- support only Tmux v1.9 or greater
|
||||
- display a nice error message if saved session file does not exist
|
||||
- added README
|
||||
|
||||
### v0.0.1, 2014-08-26
|
||||
- started a project
|
||||
- basic saving and restoring works
|
||||
|
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
|
149
README.md
149
README.md
@ -1,4 +1,151 @@
|
||||
# Tmux Session Saver
|
||||
# Tmux Resurrect
|
||||
|
||||
Restore `tmux` environment after a system restart.
|
||||
|
||||
Tmux is great, except when you have to restart the computer. You lose all the
|
||||
running programs, working directories, pane layouts etc.
|
||||
There are helpful management tools out there, but they require initial
|
||||
configuration and continuous updates as your workflow evolves or you start new
|
||||
projects.
|
||||
|
||||
`tmux-resurrect` saves all the little details from your tmux environment so it
|
||||
can be completely restored after a system restart (or when you feel like it).
|
||||
No configuration is required. You should feel like you never quit tmux.
|
||||
|
||||
It even (optionally) [restores vim sessions](#restoring-vim-sessions)!
|
||||
|
||||
### Screencast
|
||||
|
||||
[](https://vimeo.com/104763018)
|
||||
|
||||
### Key bindings
|
||||
|
||||
- `prefix + Ctrl-s` or `prefix + Alt-s` - save
|
||||
- `prefix + Ctrl-r` or `prefix + Alt-r` - restore
|
||||
|
||||
Some people can't get `Alt` key mappings to work so they are deprecated.
|
||||
|
||||
For custom key bindings, add to `.tmux.conf`:
|
||||
|
||||
set -g @resurrect-save "S"
|
||||
set -g @resurrect-restore "R"
|
||||
|
||||
### About
|
||||
|
||||
This plugin goes to great lengths to save and restore all the details from your
|
||||
`tmux` environment. Here's what's been taken care of:
|
||||
|
||||
- all sessions, windows, panes and their order
|
||||
- current working directory for each pane
|
||||
- **exact pane layouts** within windows
|
||||
- active and alternative session
|
||||
- active and alternative window for each session
|
||||
- windows with focus
|
||||
- active pane for each window
|
||||
- programs running within a pane! More details in the
|
||||
[configuration section](#configuration).
|
||||
- restoring vim sessions (optional). More details in
|
||||
[restoring vim sessions](#restoring-vim-sessions).
|
||||
|
||||
Requirements / dependencies: `tmux 1.9` or higher, `pgrep`
|
||||
|
||||
### Installation with [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm) (recommended)
|
||||
|
||||
Add plugin to the list of TPM plugins in `.tmux.conf`:
|
||||
|
||||
set -g @tpm_plugins " \
|
||||
tmux-plugins/tpm \
|
||||
tmux-plugins/tmux-resurrect \
|
||||
"
|
||||
|
||||
Hit `prefix + I` to fetch the plugin and source it. You should now be able to
|
||||
use the plugin.
|
||||
|
||||
### Manual Installation
|
||||
|
||||
Clone the repo:
|
||||
|
||||
$ git clone https://github.com/tmux-plugins/tmux-resurrect ~/clone/path
|
||||
|
||||
Add this line to the bottom of `.tmux.conf`:
|
||||
|
||||
run-shell ~/clone/path/resurrect.tmux
|
||||
|
||||
Reload TMUX environment:
|
||||
|
||||
# type this in terminal
|
||||
$ tmux source-file ~/.tmux.conf
|
||||
|
||||
You should now be able to use the plugin.
|
||||
|
||||
### Configuration
|
||||
|
||||
Configuration is not required, but it enables extra features.
|
||||
|
||||
Only a conservative list of programs is restored by default:<br/>
|
||||
`vi vim emacs man less more tail top htop irssi`.
|
||||
Open a GitHub issue if you think some other program should be on the default list.
|
||||
|
||||
- Restore additional programs with the setting in `.tmux.conf`:
|
||||
|
||||
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 'irb pry "~rails server" "~rails console"'
|
||||
|
||||
- If the wrong command is restored, try specifying inline strategy for the
|
||||
program with `->`:
|
||||
|
||||
set -g @resurrect-processes 'some_program "grunt->grunt development"'
|
||||
|
||||
- Don't restore any programs:
|
||||
|
||||
set -g @resurrect-processes 'false'
|
||||
|
||||
- Restore **all** programs (be careful with this!):
|
||||
|
||||
set -g @resurrect-processes ':all:'
|
||||
|
||||
#### Restoring vim sessions
|
||||
|
||||
- save vim sessions. I recommend [tpope/vim-obsession](https://github.com/tpope/vim-obsession).
|
||||
- in `.tmux.conf`:
|
||||
|
||||
set -g @resurrect-strategy-vim "session"
|
||||
|
||||
`tmux-resurrect` will now restore vim sessions if `Sessions.vim` file is
|
||||
present.
|
||||
|
||||
### Other goodies
|
||||
|
||||
- [tmux-copycat](https://github.com/tmux-plugins/tmux-copycat) - a plugin for
|
||||
regex searches in tmux and fast match selection
|
||||
- [tmux-yank](https://github.com/tmux-plugins/tmux-yank) - enables copying
|
||||
highlighted text to system clipboard
|
||||
- [tmux-open](https://github.com/tmux-plugins/tmux-open) - a plugin for quickly
|
||||
opening highlighted file or a url
|
||||
|
||||
### Reporting bugs and contributing
|
||||
|
||||
Both contributing and bug reports are welcome. Please check out
|
||||
[contributing guidelines](CONTRIBUTING.md).
|
||||
|
||||
### Credits
|
||||
|
||||
[Mislav Marohnić](https://github.com/mislav) - the idea for the plugin came from his
|
||||
[tmux-session script](https://github.com/mislav/dotfiles/blob/master/bin/tmux-session).
|
||||
|
||||
### Other
|
||||
|
||||
Here's another script that tries to solve the same problem:
|
||||
[link](http://brainscraps.wikia.com/wiki/Resurrecting_tmux_Sessions_After_Reboot).
|
||||
It even has the same name, even though I discovered it only after publishing
|
||||
`v1.0` of this plugin.
|
||||
|
||||
### License
|
||||
[MIT](LICENSE.md)
|
||||
|
@ -2,19 +2,14 @@
|
||||
|
||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
source "$CURRENT_DIR/scripts/variables.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() {
|
||||
local key_bindings=$(get_tmux_option "$save_option" "$default_save_key")
|
||||
local key
|
||||
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
|
||||
}
|
||||
|
||||
@ -22,12 +17,17 @@ set_restore_bindings() {
|
||||
local key_bindings=$(get_tmux_option "$restore_option" "$default_restore_key")
|
||||
local key
|
||||
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
|
||||
}
|
||||
|
||||
set_default_strategies() {
|
||||
tmux set-option -g "${restore_process_strategy_option}irb" "default_strategy"
|
||||
}
|
||||
|
||||
main() {
|
||||
set_save_bindings
|
||||
set_restore_bindings
|
||||
set_default_strategies
|
||||
}
|
||||
main
|
78
scripts/check_tmux_version.sh
Executable file
78
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
|
@ -1,3 +1,9 @@
|
||||
default_resurrect_dir="$HOME/.tmux/resurrect"
|
||||
resurrect_dir_option="@resurrect-dir"
|
||||
|
||||
SUPPORTED_VERSION="1.9"
|
||||
|
||||
# helper functions
|
||||
get_tmux_option() {
|
||||
local option="$1"
|
||||
local default_value="$2"
|
||||
@ -33,3 +39,27 @@ display_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-
|
||||
}
|
||||
|
||||
# path helpers
|
||||
|
||||
resurrect_dir() {
|
||||
echo $(get_tmux_option "$resurrect_dir_option" "$default_resurrect_dir")
|
||||
}
|
||||
|
||||
resurrect_file_path() {
|
||||
local timestamp="$(date +"%Y-%m-%dT%H:%M:%S")"
|
||||
echo "$(resurrect_dir)/tmux_resurrect_${timestamp}.txt"
|
||||
}
|
||||
|
||||
last_resurrect_file() {
|
||||
echo "$(resurrect_dir)/last"
|
||||
}
|
||||
|
162
scripts/process_restore_helpers.sh
Normal file
162
scripts/process_restore_helpers.sh
Normal file
@ -0,0 +1,162 @@
|
||||
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"
|
||||
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
|
||||
tmux send-keys "$inline_strategy" "C-m"
|
||||
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")"
|
||||
tmux send-keys "$strategy_command" "C-m"
|
||||
else
|
||||
# just invoke the command
|
||||
tmux send-keys "$pane_full_command" "C-m"
|
||||
fi
|
||||
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 _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"
|
||||
}
|
208
scripts/restore.sh
Executable file
208
scripts/restore.sh
Executable file
@ -0,0 +1,208 @@
|
||||
#!/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"
|
||||
|
||||
# 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() {
|
||||
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" ]]
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
new_window() {
|
||||
local session_name="$1"
|
||||
local window_number="$2"
|
||||
local window_name="$3"
|
||||
local dir="$4"
|
||||
tmux new-window -d -t "${session_name}:${window_number}" -n "$window_name" -c "$dir"
|
||||
}
|
||||
|
||||
new_session() {
|
||||
local session_name="$1"
|
||||
local window_number="$2"
|
||||
local window_name="$3"
|
||||
local dir="$4"
|
||||
TMUX="" tmux -S "$(tmux_socket)" new-session -d -s "$session_name" -n "$window_name" -c "$dir"
|
||||
# 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"
|
||||
tmux split-window -t "${session_name}:${window_number}" -c "$dir" -h
|
||||
tmux resize-pane -t "${session_name}:${window_number}" -L "999"
|
||||
}
|
||||
|
||||
restore_pane() {
|
||||
local pane="$1"
|
||||
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")"
|
||||
pane_full_command="$(remove_first_char "$pane_full_command")"
|
||||
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"
|
||||
elif session_exists "$session_name"; then
|
||||
new_window "$session_name" "$window_number" "$window_name" "$dir"
|
||||
else
|
||||
new_session "$session_name" "$window_number" "$window_name" "$dir"
|
||||
fi
|
||||
done < <(echo "$pane")
|
||||
}
|
||||
|
||||
restore_state() {
|
||||
local state="$1"
|
||||
echo "$state" |
|
||||
while IFS=$'\t' read line_type client_session client_last_session; do
|
||||
tmux switch-client -t "$client_last_session"
|
||||
tmux switch-client -t "$client_session"
|
||||
done
|
||||
}
|
||||
|
||||
restore_all_panes() {
|
||||
while read line; do
|
||||
if is_line_type "pane" "$line"; then
|
||||
restore_pane "$line"
|
||||
fi
|
||||
done < $(last_resurrect_file)
|
||||
}
|
||||
|
||||
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=$'\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")"
|
||||
restore_pane_process "$pane_full_command" "$session_name" "$window_number" "$pane_index" "$dir"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
restore_pane_layout_for_each_window() {
|
||||
\grep '^window' $(last_resurrect_file) |
|
||||
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"
|
||||
done
|
||||
}
|
||||
|
||||
restore_active_pane_for_each_window() {
|
||||
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
|
||||
tmux switch-client -t "${session_name}:${window_number}"
|
||||
tmux select-pane -t "$active_pane"
|
||||
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() {
|
||||
awk 'BEGIN { FS="\t"; OFS="\t" } /^window/ && $5 ~ /[*-]/ { print $2, $4, $3; }' $(last_resurrect_file) |
|
||||
sort -u |
|
||||
while IFS=$'\t' 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!"
|
||||
restore_all_panes
|
||||
restore_pane_layout_for_each_window >/dev/null 2>&1
|
||||
restore_all_pane_processes
|
||||
# below functions restore exact cursor positions
|
||||
restore_active_pane_for_each_window
|
||||
restore_zoomed_windows
|
||||
restore_active_and_alternate_windows
|
||||
restore_active_and_alternate_sessions
|
||||
stop_spinner
|
||||
display_message "Tmux restore complete!"
|
||||
fi
|
||||
}
|
||||
main
|
110
scripts/save.sh
Executable file
110
scripts/save.sh
Executable file
@ -0,0 +1,110 @@
|
||||
#!/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"
|
||||
|
||||
pane_format() {
|
||||
local delimiter=$'\t'
|
||||
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}"
|
||||
echo "$format"
|
||||
}
|
||||
|
||||
window_format() {
|
||||
local delimiter=$'\t'
|
||||
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 delimiter=$'\t'
|
||||
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)"
|
||||
}
|
||||
|
||||
pane_full_command() {
|
||||
pane_pid="$1"
|
||||
\pgrep -lf -P "$pane_pid" |
|
||||
cut -d' ' -f2-
|
||||
}
|
||||
|
||||
# translates pane pid to process command running inside a pane
|
||||
dump_panes() {
|
||||
local full_command
|
||||
local d=$'\t' # delimiter
|
||||
dump_panes_raw |
|
||||
while IFS=$'\t' read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_pid; do
|
||||
full_command="$(pane_full_command $pane_pid)"
|
||||
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() {
|
||||
tmux list-windows -a -F "$(window_format)"
|
||||
}
|
||||
|
||||
dump_state() {
|
||||
tmux display-message -p "$(state_format)"
|
||||
}
|
||||
|
||||
save_all() {
|
||||
local resurrect_file_path="$(resurrect_file_path)"
|
||||
mkdir -p "$(resurrect_dir)"
|
||||
dump_panes > $resurrect_file_path
|
||||
dump_windows >> $resurrect_file_path
|
||||
dump_state >> $resurrect_file_path
|
||||
ln -fs "$resurrect_file_path" "$(last_resurrect_file)"
|
||||
}
|
||||
|
||||
main() {
|
||||
if supported_tmux_version_ok; then
|
||||
start_spinner "Saving..." "Tmux environment saved!"
|
||||
save_all
|
||||
stop_spinner
|
||||
display_message "Tmux environment saved!"
|
||||
fi
|
||||
}
|
||||
main
|
@ -1,84 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
source "$CURRENT_DIR/helpers.sh"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
new_window() {
|
||||
local session_name="$1"
|
||||
local window_number="$2"
|
||||
local window_name="$3"
|
||||
local dir="$4"
|
||||
tmux new-window -d -t "${session_name}:${window_number}" -n "$window_name" -c "$dir"
|
||||
}
|
||||
|
||||
new_session() {
|
||||
local session_name="$1"
|
||||
local window_number="$2"
|
||||
local window_name="$3"
|
||||
local dir="$4"
|
||||
TMUX="" tmux -S "$(tmux_socket)" new-session -d -s "$session_name" -n "$window_name" -c "$dir"
|
||||
# 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"
|
||||
tmux split-window -d -t "${session_name}:${window_number}" -c "$dir"
|
||||
}
|
||||
|
||||
restore_pane() {
|
||||
local pane="$1"
|
||||
echo "$pane" |
|
||||
while IFS=$'\t' read session_name window_number window_name dir; do
|
||||
# echo "$session_name - $window_number - $window_name - $dir"
|
||||
if window_exists "$session_name" "$window_number"; then
|
||||
echo "new pane $session_name $window_number"
|
||||
new_pane "$session_name" "$window_number" "$window_name" "$dir"
|
||||
elif session_exists "$session_name"; then
|
||||
echo "new window $session_name $window_number"
|
||||
new_window "$session_name" "$window_number" "$window_name" "$dir"
|
||||
else
|
||||
echo "new session $session_name"
|
||||
new_session "$session_name" "$window_number" "$window_name" "$dir"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
restore_all_sessions() {
|
||||
while read line; do
|
||||
restore_pane "$line"
|
||||
done < $HOME/.tmux/session
|
||||
display_message "Restored all Tmux sessions!"
|
||||
}
|
||||
|
||||
main() {
|
||||
restore_all_sessions
|
||||
}
|
||||
main
|
@ -1,33 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
source "$CURRENT_DIR/helpers.sh"
|
||||
|
||||
dump_format() {
|
||||
local delimiter=$'\t'
|
||||
local format
|
||||
format+="#{session_name}"
|
||||
format+="${delimiter}"
|
||||
format+="#{window_index}"
|
||||
format+="${delimiter}"
|
||||
format+="#{window_name}"
|
||||
format+="${delimiter}"
|
||||
format+="#{pane_current_path}"
|
||||
echo "$format"
|
||||
}
|
||||
|
||||
dump() {
|
||||
tmux list-panes -a -F "$(dump_format)"
|
||||
}
|
||||
|
||||
save_all_sessions() {
|
||||
mkdir -p $HOME/.tmux
|
||||
dump > $HOME/.tmux/session
|
||||
display_message "Saved all Tmux sessions!"
|
||||
}
|
||||
|
||||
main() {
|
||||
save_all_sessions
|
||||
}
|
||||
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 "$1" "$2" &
|
||||
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
|
25
scripts/variables.sh
Normal file
25
scripts/variables.sh
Normal file
@ -0,0 +1,25 @@
|
||||
# key bindings
|
||||
default_save_key="M-s C-s"
|
||||
save_option="@resurrect-save"
|
||||
|
||||
default_restore_key="M-r C-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'
|
||||
|
||||
# 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="->"
|
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
|
32
strategies/vim_session.sh
Executable file
32
strategies/vim_session.sh
Executable file
@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# "vim session strategy"
|
||||
#
|
||||
# Restores a vim session from 'Session.vim' file, if it exists.
|
||||
# If 'Session.vim' does not exist, it falls back to invoking the original
|
||||
# command (without the `-S` flag).
|
||||
|
||||
ORIGINAL_COMMAND="$1"
|
||||
DIRECTORY="$2"
|
||||
|
||||
vim_session_file_exists() {
|
||||
[ -e "${DIRECTORY}/Session.vim" ]
|
||||
}
|
||||
|
||||
original_command_contains_session_flag() {
|
||||
[[ "$ORIGINAL_COMMAND" =~ "-S" ]]
|
||||
}
|
||||
|
||||
main() {
|
||||
if vim_session_file_exists; then
|
||||
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
|
||||
echo "$ORIGINAL_COMMAND"
|
||||
fi
|
||||
}
|
||||
main
|
BIN
video/screencast_img.png
Normal file
BIN
video/screencast_img.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 121 KiB |
110
video/script.md
Normal file
110
video/script.md
Normal file
@ -0,0 +1,110 @@
|
||||
# Screencast script
|
||||
|
||||
1. Intro
|
||||
========
|
||||
Let's demo tmux resurrect plugin.
|
||||
|
||||
Tmux resurrect enables persisting tmux sessions, so it can survive the dreaded
|
||||
system restarts.
|
||||
|
||||
The benefit is uninterrupted workflow with no configuration required.
|
||||
|
||||
2. Working session
|
||||
==================
|
||||
Script
|
||||
------
|
||||
Let me show you what I have in this tmux demo session.
|
||||
|
||||
First of all, I have vim open and it has a couple files loaded.
|
||||
|
||||
Then there's a tmux window with a couple splits in various directories across
|
||||
the system.
|
||||
|
||||
Next window contains tmux man page,
|
||||
and then there's `htop` program.
|
||||
|
||||
And this is just one of many projects I'm currently running.
|
||||
|
||||
Actions
|
||||
-------
|
||||
- blank tmux window
|
||||
- vim
|
||||
- `ls` to show open files
|
||||
- multiple pane windows (3)
|
||||
- man tmux
|
||||
- htop
|
||||
- psql
|
||||
- show a list of session
|
||||
|
||||
3. Saving the environment
|
||||
=========================
|
||||
Script
|
||||
------
|
||||
With vanilla tmux, when I restart the computer this whole environment will be
|
||||
lost and I'll have to invest time to restore it.
|
||||
|
||||
tmux resurrect gives you the ability to persist everything with
|
||||
prefix plus alt-s.
|
||||
|
||||
Now tmux environment is saved and I can safely shut down tmux with a
|
||||
kill server command.
|
||||
|
||||
Actions
|
||||
-------
|
||||
- prefix + M-s
|
||||
- :kill-server
|
||||
|
||||
4. Restoring the environment
|
||||
============================
|
||||
Script
|
||||
------
|
||||
At this point restoring everything back is easy.
|
||||
|
||||
I'll fire up tmux again. Notice it's completely empty.
|
||||
|
||||
Now, I'll press prefix plus alt-r and everything will restore.
|
||||
|
||||
Let's see how things look now.
|
||||
First of all, I'm back to the exact same window I was in when the environment
|
||||
was saved. Second - you can see the `htop` program was restored.
|
||||
|
||||
Going back there's tmux man page
|
||||
a window with multiple panes with the exact same layout as before
|
||||
and vim.
|
||||
|
||||
|
||||
tmux resurrect takes special care of vim. By leveraging vim's sessions, it
|
||||
preserves vim's split windows, open files, even the list of files edited before.
|
||||
|
||||
Check out the project readme for more details about special treatment for vim.
|
||||
|
||||
That was just one of the restored tmux sessions. If I open tmux session list you
|
||||
can see all the other projects are restored as well.
|
||||
|
||||
|
||||
When you see all these programs running you might be concerned that this plugin
|
||||
started a lot of potentially destructive processes.
|
||||
|
||||
For example, when you restore tmux you don't want to accidentally start backups,
|
||||
resource intensive or sensitive programs.
|
||||
|
||||
There's no need to be worried though. By default, this plugin starts only a
|
||||
conservative list of programs like vim, less, tail, htop and similar.
|
||||
This list of programs restored by default is in the project readme. Also, you
|
||||
can easily add more programs to it.
|
||||
|
||||
If you feel paranoid, there's an option that prevents restoring any program.
|
||||
|
||||
Actions
|
||||
-------
|
||||
- tmux
|
||||
- prefix + M-r
|
||||
|
||||
- open previous windows
|
||||
- in vim hit :ls
|
||||
|
||||
- prefix + s for a list of panes
|
||||
|
||||
5. Outro
|
||||
========
|
||||
That's it for this demo. I hope you'll find tmux resurrect useful.
|
Reference in New Issue
Block a user