29 Commits

Author SHA1 Message Date
95303946b2 v1.3.0 2014-09-20 22:36:42 +02:00
1d09f07d2b Remove dependency on pgrep; use ps to get process names
Fixes #43
2014-09-20 22:33:14 +02:00
618769b62f Update readme 2014-09-20 13:23:42 +02:00
fac377bf8c Add bash to the dependency list 2014-09-10 21:53:38 +02:00
dc7561df74 Small readme tweak 2014-09-10 13:26:14 +02:00
eb2cd31d4b Update readme
Do not invite people to negotiate default program restore list.
2014-09-07 10:19:03 +02:00
e242ea6d8d v1.2.1 2014-09-02 22:48:50 +02:00
a0a3f2fd56 When a pane is not restored, don't restore it's program 2014-09-02 22:47:38 +02:00
d606106f1c Fix: command prompt not ideal after a restore
Fixes #36
2014-09-02 22:34:00 +02:00
d5598d1c61 Update readme 2014-09-01 21:18:15 +02:00
db05b2133b v1.2.0 2014-09-01 20:32:54 +02:00
8368355240 Enable inline strategies when restoring programs 2014-09-01 20:32:27 +02:00
20c5fc40cc v1.1.0 2014-08-31 11:37:14 +02:00
af3cb5db2e ctrl key mappings; deprecate alt keys 2014-08-31 11:35:58 +02:00
deb3e9fdce Add a reference to other plugins in the readme 2014-08-31 01:38:51 +02:00
3682cf6170 Bugfix: sourcing variables file 2014-08-30 21:43:08 +02:00
6255154190 Readme tweak 2014-08-30 17:30:30 +02:00
a6eb17f8fd Fix a link to tpope/vim-obsession 2014-08-30 17:11:14 +02:00
27b9b41e21 Merge pull request #27 from michaelmior/patch-1
Minor README fixes
2014-08-30 16:25:38 +02:00
4d5557d599 Minor README fixes 2014-08-30 10:24:54 -04:00
f5cfa2daa7 Update readme 2014-08-30 14:41:26 +02:00
f2533ec0ef Mention alternative in the readme 2014-08-30 14:40:38 +02:00
d0f6f6ca30 v1.0.0 2014-08-30 11:18:26 +02:00
34a1b4647d Update screencast image in the readme 2014-08-30 10:51:59 +02:00
a68a786a73 Add screencast link to the readme 2014-08-30 10:48:59 +02:00
19c981545e Make the default program running list even more conservative 2014-08-30 00:15:15 +02:00
571bcb8173 Add screencast script 2014-08-30 00:11:51 +02:00
2b259cf11a Show spinner during the env save process 2014-08-29 19:51:47 +02:00
f9ad59900a Update readme 2014-08-29 19:12:28 +02:00
9 changed files with 250 additions and 36 deletions

View File

@ -2,6 +2,27 @@
### master
### v1.3.0, 2014-09-20
- remove dependency on `pgrep` command. Use `ps` for fetching process names.
### v1.2.1, 2014-09-02
- tweak 'new_pane' creation strategy to fix #36
- when running multiple tmux server and for a large number of panes (120 +) when
doing a restore, some panes might not be created. When that is the case also
don't restore programs for those panes.
### 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.

View File

@ -2,22 +2,33 @@
Restore `tmux` environment after a system restart.
Tmux is great, except when you have to restart the computer. You loose all the
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 tmux environment so it
can be completely restored after a system restart. No configuration is required.
You should feel like you never quit tmux.
`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
[![screencast screenshot](/video/screencast_img.png)](https://vimeo.com/104763018)
### Key bindings
- `prefix + Alt-s` - save
- `prefix + Alt-r` - restore
- `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
@ -36,7 +47,10 @@ This plugin goes to great lengths to save and restore all the details from your
- restoring vim sessions (optional). More details in
[restoring vim sessions](#restoring-vim-sessions).
Requirements / dependencies: `tmux 1.9` or higher, `pgrep`
Requirements / dependencies: `tmux 1.9` or higher, `bash`.
`tmux-resurrect` is idempotent! It will not try to restore panes or windows that
already exist.
### Installation with [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm) (recommended)
@ -69,11 +83,10 @@ You should now be able to use the plugin.
### Configuration
Configuration is not required - but it enables extra features.
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 irb pry "~rails console"`.
Open a github issue if you think some other program should be on the default list.
`vi vim emacs man less more tail top htop irssi`.
- Restore additional programs with the setting in `.tmux.conf`:
@ -85,7 +98,12 @@ Open a github issue if you think some other program should be on the default lis
- Start with tilde to restore a program whose process contains target name:
set -g @resurrect-processes 'some_program "~rails server"'
set -g @resurrect-processes 'irb pry "~rails server" "~rails console"'
- Use `->` to specify a command to be used when restoring a program (useful if
the default restore command fails ):
set -g @resurrect-processes 'some_program "grunt->grunt development"'
- Don't restore any programs:
@ -97,14 +115,23 @@ Open a github issue if you think some other program should be on the default lis
#### Restoring vim sessions
- save vim sessions. I recommend [tpope/vim-obsession](tpope/vim-obsession).
- save vim sessions. I recommend [tpope/vim-obsession](https://github.com/tpope/vim-obsession).
- in `.tmux.conf`:
set -g @resurrect-strategy-vim "session"
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
@ -115,5 +142,12 @@ Both contributing and bug reports are welcome. Please check out
[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)

View File

@ -17,7 +17,11 @@ restore_pane_process() {
tmux switch-client -t "${session_name}:${window_number}"
tmux select-pane -t "$pane_index"
if _strategy_exists "$pane_full_command"; then
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"
@ -39,6 +43,9 @@ _process_should_be_restored() {
# 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
@ -62,23 +69,42 @@ _process_on_the_restore_list() {
# TODO: make this work without eval
eval set $(_restore_list)
local proc
local match
for proc in "$@"; do
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
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
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")"
@ -94,6 +120,22 @@ _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")"

View File

@ -99,8 +99,9 @@ new_pane() {
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"
tmux split-window -t "${session_name}:${window_number}" -c "$dir"
# minimize window so more panes can fit
tmux resize-pane -t "${session_name}:${window_number}" -U "999"
}
restore_pane() {
@ -192,7 +193,7 @@ restore_active_and_alternate_sessions() {
main() {
if supported_tmux_version_ok && check_saved_session_exists; then
start_spinner
start_spinner "Restoring..." "Tmux restore complete!"
restore_all_panes
restore_pane_layout_for_each_window >/dev/null 2>&1
restore_all_pane_processes

View File

@ -2,8 +2,9 @@
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$CURRENT_DIR/scripts/variables.sh"
source "$CURRENT_DIR/variables.sh"
source "$CURRENT_DIR/helpers.sh"
source "$CURRENT_DIR/spinner_helpers.sh"
pane_format() {
local delimiter=$'\t'
@ -65,8 +66,9 @@ dump_panes_raw() {
}
pane_full_command() {
pane_pid="$1"
\pgrep -lf -P "$pane_pid" |
local pane_pid="$1"
ps -eo "ppid command" |
grep "^${pane_pid}" |
cut -d' ' -f2-
}
@ -96,12 +98,14 @@ save_all() {
dump_windows >> $resurrect_file_path
dump_state >> $resurrect_file_path
ln -fs "$resurrect_file_path" "$(last_resurrect_file)"
display_message "Tmux environment saved!"
}
main() {
if supported_tmux_version_ok; then
start_spinner "Saving..." "Tmux environment saved!"
save_all
stop_spinner
display_message "Tmux environment saved!"
fi
}
main

View File

@ -1,5 +1,5 @@
start_spinner() {
$CURRENT_DIR/tmux_spinner.sh "Restoring tmux..." "Tmux restore complete!" &
$CURRENT_DIR/tmux_spinner.sh "$1" "$2" &
export SPINNER_PID=$!
}

View File

@ -1,13 +1,13 @@
# key bindings
default_save_key="M-s"
default_save_key="M-s C-s"
save_option="@resurrect-save"
default_restore_key="M-r"
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 irb pry "~rails console"'
default_proc_list='vi vim emacs man less more tail top htop irssi'
# User defined processes that are restored
# 'false' - nothing is restored
@ -21,3 +21,5 @@ 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="->"

BIN
video/screencast_img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

110
video/script.md Normal file
View 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.