diff --git a/README.md b/README.md index f137ad8b..e7e7057c 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Optional: - [restoring vim and neovim sessions](docs/restoring_vim_and_neovim_sessions.md) - [restoring pane contents](docs/restoring_pane_contents.md) +- [restoring paste buffers](docs/restoring_paste_buffers.md) - [restoring a previously saved environment](docs/restoring_previously_saved_environment.md) Requirements / dependencies: `tmux 1.9` or higher, `bash`. diff --git a/docs/restoring_paste_buffers.md b/docs/restoring_paste_buffers.md new file mode 100644 index 00000000..127e6c59 --- /dev/null +++ b/docs/restoring_paste_buffers.md @@ -0,0 +1,7 @@ +# Restoring paste buffers + +This feature saves and restores tmux paste buffers. + +It can be enabled by adding this line to `.tmux.conf`: + + set -g @resurrect-paste-buffers 'on' diff --git a/scripts/helpers.sh b/scripts/helpers.sh index 20d87dcd..6dacf7fa 100644 --- a/scripts/helpers.sh +++ b/scripts/helpers.sh @@ -94,6 +94,34 @@ pane_content_files_restore_from_archive() { fi } +# paste buffers file helpers + +paste_buffers_option_on() { + local option="$(get_tmux_option "$paste_buffers_option" "off")" + [ "$option" == "on" ] +} + +paste_buffers_create_archive() { + tar cf - -C "$(resurrect_dir)/save/" ./paste_buffers/ | + gzip > "$(paste_buffers_archive_file)" +} + +paste_buffers_restore_from_archive() { + local archive_file="$(paste_buffers_archive_file)" + if [ -f "$archive_file" ]; then + restore_dir=$(paste_buffers_dir "restore") + mkdir -p "${restore_dir}" + gzip -d < "$archive_file" | + tar xf - -C "$(resurrect_dir)/restore/" + gzip -d < "$archive_file" | tar t | cut -d / -f 3 | + sort -r | # restore buffers in order (first saved restored last) + while read file_in_arch; do + [ ! -f "${restore_dir}/${file_in_arch}" ] && continue # skip top level dir + echo "${restore_dir}/${file_in_arch}" + done + fi +} + # path helpers resurrect_dir() { @@ -140,6 +168,20 @@ pane_contents_archive_file() { echo "$(resurrect_dir)/pane_contents.tar.gz" } +paste_buffers_dir() { + echo "$(resurrect_dir)/$1/paste_buffers/" +} + +paste_buffer_file() { + local save_or_restore="$1" + local file_name="$2" + echo "$(paste_buffers_dir "${save_or_restore}")/${file_name}" +} + +paste_buffers_archive_file() { + echo "$(resurrect_dir)/paste_buffers.tar.gz" +} + execute_hook() { local kind="$1" shift diff --git a/scripts/restore.sh b/scripts/restore.sh index 1a5e3f98..9cbddcf9 100755 --- a/scripts/restore.sh +++ b/scripts/restore.sh @@ -315,6 +315,24 @@ restore_all_pane_processes() { fi } +clear_paste_buffers() { + tmux list-buffers -F '#{buffer_name}' | + while read bufname; do + tmux delete-buffer -b "${bufname}" + done +} + +restore_paste_buffers() { + if paste_buffers_option_on; then + clear_paste_buffers + paste_buffers_restore_from_archive | while read buffer_file; do + buffer_name=$(basename ${buffer_file##*/} | cut -d _ -f 2) + tmux load-buffer -b "${buffer_name}" "${buffer_file}" + done + rm $(paste_buffers_dir "restore")/* + fi +} + restore_active_pane_for_each_window() { awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $9 == 1 { print $2, $3, $6; }' $(last_resurrect_file) | while IFS=$d read session_name window_number active_pane; do @@ -372,6 +390,7 @@ main() { restore_window_properties >/dev/null 2>&1 execute_hook "pre-restore-pane-processes" restore_all_pane_processes + restore_paste_buffers # below functions restore exact cursor positions restore_active_pane_for_each_window restore_zoomed_windows diff --git a/scripts/save.sh b/scripts/save.sh index 01edcdeb..ec4f003b 100755 --- a/scripts/save.sh +++ b/scripts/save.sh @@ -226,6 +226,17 @@ dump_pane_contents() { done } +dump_paste_buffers() { + tmux list-buffers -F '#{buffer_name}' | + while read bufname; do + # add index prefix to save buffer order + filename=$(printf "buf%04d_%s" "${i}" "${bufname}") + i=$((i+1)) + dst=$(paste_buffer_file "save" "${filename}") + tmux save-buffer -b "${bufname}" "${dst}" + done +} + remove_old_backups() { # remove resurrect files older than 30 days (default), but keep at least 5 copies of backup. local delete_after="$(get_tmux_option "$delete_backup_after_option" "$default_delete_backup_after")" @@ -255,6 +266,12 @@ save_all() { pane_contents_create_archive rm "$(pane_contents_dir "save")"/* fi + if paste_buffers_option_on; then + mkdir -p "$(paste_buffers_dir "save")" + dump_paste_buffers + paste_buffers_create_archive + rm "$(paste_buffers_dir "save")"/* + fi remove_old_backups execute_hook "post-save-all" } diff --git a/scripts/variables.sh b/scripts/variables.sh index 9d42e02a..4136d666 100644 --- a/scripts/variables.sh +++ b/scripts/variables.sh @@ -38,6 +38,9 @@ pane_contents_option="@resurrect-capture-pane-contents" pane_contents_area_option="@resurrect-pane-contents-area" default_pane_contents_area="full" +# Paste buffer restore options +paste_buffers_option="@resurrect-paste-buffers" + # set to 'on' to ensure panes are never ever overwritten overwrite_option="@resurrect-never-overwrite"