From 4fdc60b6a221e0c39d41a68492af55ec9cde1689 Mon Sep 17 00:00:00 2001 From: Kaj Forney Date: Thu, 27 Sep 2018 17:40:01 -0600 Subject: [PATCH] Add autologin and custom tmux config. Former-commit-id: 9f5a64d37241454e9674aa90c8be5775a81fe74d Former-commit-id: 89d8a1302bd2a72239fbe9ad9820be4ecda76cab --- ...ilio-sync_2.6.0-1_amd64.deb.REMOVED.git-id | 1 + filesystem/etc/gdm3/daemon.conf | 33 ++ filesystem/root/.tmux.conf | 79 ++++ .../.tmux/plugins/tmux-battery/CHANGELOG.md | 41 ++ .../.tmux/plugins/tmux-battery/LICENSE.md | 19 + .../root/.tmux/plugins/tmux-battery/README.md | 128 +++++++ .../.tmux/plugins/tmux-battery/battery.tmux | 49 +++ .../screenshots/battery_charging.png | Bin 0 -> 10484 bytes .../screenshots/battery_discharging.png | Bin 0 -> 10447 bytes .../tmux-battery/screenshots/battery_full.png | Bin 0 -> 10287 bytes .../screenshots/battery_remain.png | Bin 0 -> 18457 bytes .../screenshots/battery_status_bg_green.png | Bin 0 -> 5831 bytes .../screenshots/battery_status_bg_orange.png | Bin 0 -> 5943 bytes .../screenshots/battery_status_bg_red.png | Bin 0 -> 5873 bytes .../screenshots/battery_status_bg_yellow.png | Bin 0 -> 6192 bytes .../tmux-battery/scripts/battery_graph.sh | 27 ++ .../tmux-battery/scripts/battery_icon.sh | 53 +++ .../scripts/battery_percentage.sh | 28 ++ .../tmux-battery/scripts/battery_remain.sh | 49 +++ .../tmux-battery/scripts/battery_status_bg.sh | 42 ++ .../tmux-battery/scripts/battery_status_fg.sh | 42 ++ .../plugins/tmux-battery/scripts/helpers.sh | 41 ++ .../.tmux/plugins/tmux-continuum/CHANGELOG.md | 42 ++ .../plugins/tmux-continuum/CONTRIBUTING.md | 15 + .../.tmux/plugins/tmux-continuum/LICENSE.md | 19 + .../.tmux/plugins/tmux-continuum/README.md | 101 +++++ .../plugins/tmux-continuum/continuum.tmux | 92 +++++ .../tmux-continuum/docs/automatic_start.md | 35 ++ .../tmux-continuum/docs/continuum_status.md | 17 + .../.tmux/plugins/tmux-continuum/docs/faq.md | 57 +++ .../docs/multiple_tmux_servers.md | 20 + .../tmux-continuum/docs/systemd_details.md | 13 + .../scripts/check_tmux_version.sh | 33 ++ .../scripts/continuum_restore.sh | 29 ++ .../tmux-continuum/scripts/continuum_save.sh | 42 ++ .../scripts/continuum_status.sh | 25 ++ .../scripts/handle_tmux_automatic_start.sh | 36 ++ .../handle_tmux_automatic_start/README.md | 1 + .../osx_disable.sh | 10 + .../handle_tmux_automatic_start/osx_enable.sh | 66 ++++ .../osx_iterm_start_tmux.sh | 66 ++++ .../osx_terminal_start_tmux.sh | 52 +++ .../systemd_disable.sh | 10 + .../systemd_enable.sh | 55 +++ .../plugins/tmux-continuum/scripts/helpers.sh | 48 +++ .../plugins/tmux-continuum/scripts/shared.sh | 7 + .../tmux-continuum/scripts/variables.sh | 40 ++ .../root/.tmux/plugins/tmux-cpu/CHANGELOG.md | 22 ++ .../root/.tmux/plugins/tmux-cpu/LICENSE | 22 ++ .../root/.tmux/plugins/tmux-cpu/README.md | 85 +++++ .../root/.tmux/plugins/tmux-cpu/cpu.tmux | 36 ++ .../plugins/tmux-cpu/scripts/cpu_icon.sh | 21 + .../tmux-cpu/scripts/cpu_percentage.sh | 36 ++ .../.tmux/plugins/tmux-cpu/scripts/helpers.sh | 48 +++ .../root/.tmux/plugins/tmux-net-speed/LICENSE | 22 ++ .../.tmux/plugins/tmux-net-speed/README.md | 81 ++++ .../root/.tmux/plugins/tmux-net-speed/init.sh | 13 + .../plugins/tmux-net-speed/net_speed.tmux | 36 ++ .../.tmux/plugins/tmux-net-speed/run-tests.sh | 6 + .../tmux-net-speed/scripts/download_speed.sh | 28 ++ .../plugins/tmux-net-speed/scripts/helpers.sh | 129 +++++++ .../tmux-net-speed/scripts/net_speed.sh | 15 + .../tmux-net-speed/scripts/upload_speed.sh | 28 ++ .../tests/suites/helpers.test.sh | 132 +++++++ .../tmux-net-speed/tests/test_utils.sh | 91 +++++ .../plugins/tmux-prefix-highlight/LICENSE | 22 ++ .../plugins/tmux-prefix-highlight/README.md | 86 +++++ .../prefix_highlight.tmux | 92 +++++ .../screenshots/prefix_off.png | Bin 0 -> 12039 bytes .../screenshots/prefix_on.png | Bin 0 -> 12665 bytes .../.tmux/plugins/tmux-resurrect/.travis.yml | 14 + .../.tmux/plugins/tmux-resurrect/CHANGELOG.md | 140 +++++++ .../plugins/tmux-resurrect/CONTRIBUTING.md | 12 + .../.tmux/plugins/tmux-resurrect/LICENSE.md | 19 + .../.tmux/plugins/tmux-resurrect/README.md | 135 +++++++ .../docs/custom_key_bindings.md | 11 + .../docs/migrating_from_tmuxinator.md | 72 ++++ .../docs/restoring_bash_history.md | 12 + .../docs/restoring_pane_contents.md | 31 ++ .../tmux-resurrect/docs/restoring_programs.md | 100 +++++ .../docs/restoring_vim_and_neovim_sessions.md | 15 + .../plugins/tmux-resurrect/docs/save_dir.md | 6 + .../tmux-resurrect/lib/tmux-test/.gitignore | 2 + .../tmux-resurrect/lib/tmux-test/.travis.yml | 14 + .../tmux-resurrect/lib/tmux-test/CHANGELOG.md | 38 ++ .../tmux-resurrect/lib/tmux-test/LICENSE.md | 19 + .../tmux-resurrect/lib/tmux-test/README.md | 134 +++++++ .../tmux-resurrect/lib/tmux-test/Vagrantfile | 17 + .../lib/tmux-test/run_framework_tests | 17 + .../tmux-resurrect/lib/tmux-test/run_tests | 91 +++++ .../tmux-resurrect/lib/tmux-test/setup | 93 +++++ .../lib/tmux-test/tests/helpers/helpers.sh | 60 +++ .../tmux-test/tests/run_tests_in_isolation | 42 ++ .../tests/test_basic_script_execution.sh | 3 + .../tests/test_default_session_name.sh | 24 ++ .../tmux-test/tests/test_tmux_scripting.sh | 24 ++ .../tmux-test/vagrant_centos_provisioning.sh | 30 ++ .../tmux-test/vagrant_ubuntu_provisioning.sh | 10 + .../plugins/tmux-resurrect/resurrect.tmux | 39 ++ .../.tmux/plugins/tmux-resurrect/run_tests | 1 + .../save_command_strategies/gdb.sh | 22 ++ .../save_command_strategies/pgrep.sh | 22 ++ .../save_command_strategies/ps.sh | 32 ++ .../scripts/check_tmux_version.sh | 78 ++++ .../plugins/tmux-resurrect/scripts/helpers.sh | 130 +++++++ .../scripts/process_restore_helpers.sh | 170 +++++++++ .../tmux-resurrect/scripts/restore.exp | 14 + .../plugins/tmux-resurrect/scripts/restore.sh | 359 ++++++++++++++++++ .../plugins/tmux-resurrect/scripts/save.sh | 290 ++++++++++++++ .../tmux-resurrect/scripts/spinner_helpers.sh | 8 + .../tmux-resurrect/scripts/tmux_spinner.sh | 29 ++ .../tmux-resurrect/scripts/variables.sh | 43 +++ .../strategies/irb_default_strategy.sh | 23 ++ .../tmux-resurrect/strategies/nvim_session.sh | 30 ++ .../tmux-resurrect/strategies/vim_session.sh | 32 ++ .../tests/fixtures/restore_file.txt | 21 + .../tests/fixtures/save_file.txt | 21 + .../create_and_save_tmux_test_environment.exp | 41 ++ .../tests/helpers/expect_helpers.exp | 65 ++++ .../tmux-resurrect/tests/helpers/helpers.sh | 1 + ...restore_and_save_tmux_test_environment.exp | 18 + .../tests/helpers/resurrect_helpers.sh | 11 + .../tests/run_tests_in_isolation | 1 + .../tests/test_resurrect_restore.sh | 33 ++ .../tests/test_resurrect_save.sh | 23 ++ .../tmux-resurrect/video/issue_vid.png | Bin 0 -> 63584 bytes .../tmux-resurrect/video/screencast_img.png | Bin 0 -> 124253 bytes .../plugins/tmux-resurrect/video/script.md | 110 ++++++ .../.tmux/plugins/tmux-sensible/CHANGELOG.md | 43 +++ .../.tmux/plugins/tmux-sensible/LICENSE.md | 19 + .../.tmux/plugins/tmux-sensible/README.md | 114 ++++++ .../.tmux/plugins/tmux-sensible/sensible.tmux | 161 ++++++++ filesystem/root/.tmux/plugins/tpm/.travis.yml | 19 + .../root/.tmux/plugins/tpm/CHANGELOG.md | 83 ++++ .../root/.tmux/plugins/tpm/HOW_TO_PLUGIN.md | 2 + filesystem/root/.tmux/plugins/tpm/LICENSE.md | 20 + filesystem/root/.tmux/plugins/tpm/README.md | 107 ++++++ .../root/.tmux/plugins/tpm/bin/clean_plugins | 14 + .../.tmux/plugins/tpm/bin/install_plugins | 14 + .../root/.tmux/plugins/tpm/bin/update_plugins | 24 ++ .../.tmux/plugins/tpm/bindings/clean_plugins | 19 + .../plugins/tpm/bindings/install_plugins | 19 + .../.tmux/plugins/tpm/bindings/update_plugins | 49 +++ .../tpm/docs/automatic_tpm_installation.md | 12 + .../tpm/docs/changing_plugins_install_dir.md | 14 + .../plugins/tpm/docs/how_to_create_plugin.md | 108 ++++++ .../tpm/docs/managing_plugins_via_cmd_line.md | 36 ++ .../.tmux/plugins/tpm/docs/tpm_not_working.md | 80 ++++ .../plugins/tpm/scripts/check_tmux_version.sh | 78 ++++ .../plugins/tpm/scripts/clean_plugins.sh | 41 ++ .../tpm/scripts/helpers/plugin_functions.sh | 86 +++++ .../scripts/helpers/shell_echo_functions.sh | 7 + .../scripts/helpers/tmux_echo_functions.sh | 28 ++ .../plugins/tpm/scripts/helpers/tmux_utils.sh | 3 + .../plugins/tpm/scripts/helpers/utility.sh | 17 + .../plugins/tpm/scripts/install_plugins.sh | 66 ++++ .../plugins/tpm/scripts/source_plugins.sh | 41 ++ .../plugins/tpm/scripts/update_plugin.sh | 71 ++++ .../scripts/update_plugin_prompt_handler.sh | 18 + .../.tmux/plugins/tpm/scripts/variables.sh | 13 + .../tpm/tests/expect_failed_plugin_download | 36 ++ .../tpm/tests/expect_successful_clean_plugins | 35 ++ ...xpect_successful_multiple_plugins_download | 44 +++ .../tests/expect_successful_plugin_download | 50 +++ ...xpect_successful_update_of_a_single_plugin | 55 +++ .../expect_successful_update_of_all_plugins | 59 +++ .../.tmux/plugins/tpm/tests/helpers/tpm.sh | 13 + .../plugins/tpm/tests/test_plugin_clean.sh | 67 ++++ .../tpm/tests/test_plugin_installation.sh | 284 ++++++++++++++ .../tests/test_plugin_installation_legacy.sh | 100 +++++ .../plugins/tpm/tests/test_plugin_sourcing.sh | 78 ++++ .../plugins/tpm/tests/test_plugin_update.sh | 60 +++ filesystem/root/.tmux/plugins/tpm/tpm | 72 ++++ 173 files changed, 7845 insertions(+) create mode 100644 debs/resilio-sync_2.6.0-1_amd64.deb.REMOVED.git-id create mode 100644 filesystem/etc/gdm3/daemon.conf create mode 100644 filesystem/root/.tmux.conf create mode 100644 filesystem/root/.tmux/plugins/tmux-battery/CHANGELOG.md create mode 100644 filesystem/root/.tmux/plugins/tmux-battery/LICENSE.md create mode 100644 filesystem/root/.tmux/plugins/tmux-battery/README.md create mode 100755 filesystem/root/.tmux/plugins/tmux-battery/battery.tmux create mode 100644 filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_charging.png create mode 100644 filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_discharging.png create mode 100644 filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_full.png create mode 100644 filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_remain.png create mode 100644 filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_green.png create mode 100644 filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_orange.png create mode 100644 filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_red.png create mode 100644 filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_yellow.png create mode 100755 filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_graph.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_icon.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_percentage.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_remain.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_status_bg.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_status_fg.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-battery/scripts/helpers.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-continuum/CHANGELOG.md create mode 100644 filesystem/root/.tmux/plugins/tmux-continuum/CONTRIBUTING.md create mode 100644 filesystem/root/.tmux/plugins/tmux-continuum/LICENSE.md create mode 100644 filesystem/root/.tmux/plugins/tmux-continuum/README.md create mode 100755 filesystem/root/.tmux/plugins/tmux-continuum/continuum.tmux create mode 100644 filesystem/root/.tmux/plugins/tmux-continuum/docs/automatic_start.md create mode 100644 filesystem/root/.tmux/plugins/tmux-continuum/docs/continuum_status.md create mode 100644 filesystem/root/.tmux/plugins/tmux-continuum/docs/faq.md create mode 100644 filesystem/root/.tmux/plugins/tmux-continuum/docs/multiple_tmux_servers.md create mode 100644 filesystem/root/.tmux/plugins/tmux-continuum/docs/systemd_details.md create mode 100755 filesystem/root/.tmux/plugins/tmux-continuum/scripts/check_tmux_version.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-continuum/scripts/continuum_restore.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-continuum/scripts/continuum_save.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-continuum/scripts/continuum_status.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start.sh create mode 120000 filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/README.md create mode 100755 filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_disable.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_enable.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_iterm_start_tmux.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_terminal_start_tmux.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/systemd_disable.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/systemd_enable.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-continuum/scripts/helpers.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-continuum/scripts/shared.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-continuum/scripts/variables.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-cpu/CHANGELOG.md create mode 100644 filesystem/root/.tmux/plugins/tmux-cpu/LICENSE create mode 100644 filesystem/root/.tmux/plugins/tmux-cpu/README.md create mode 100755 filesystem/root/.tmux/plugins/tmux-cpu/cpu.tmux create mode 100755 filesystem/root/.tmux/plugins/tmux-cpu/scripts/cpu_icon.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-cpu/scripts/cpu_percentage.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-cpu/scripts/helpers.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-net-speed/LICENSE create mode 100644 filesystem/root/.tmux/plugins/tmux-net-speed/README.md create mode 100755 filesystem/root/.tmux/plugins/tmux-net-speed/init.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-net-speed/net_speed.tmux create mode 100755 filesystem/root/.tmux/plugins/tmux-net-speed/run-tests.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-net-speed/scripts/download_speed.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-net-speed/scripts/helpers.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-net-speed/scripts/net_speed.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-net-speed/scripts/upload_speed.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-net-speed/tests/suites/helpers.test.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-net-speed/tests/test_utils.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-prefix-highlight/LICENSE create mode 100644 filesystem/root/.tmux/plugins/tmux-prefix-highlight/README.md create mode 100755 filesystem/root/.tmux/plugins/tmux-prefix-highlight/prefix_highlight.tmux create mode 100644 filesystem/root/.tmux/plugins/tmux-prefix-highlight/screenshots/prefix_off.png create mode 100644 filesystem/root/.tmux/plugins/tmux-prefix-highlight/screenshots/prefix_on.png create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/.travis.yml create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/CHANGELOG.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/CONTRIBUTING.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/LICENSE.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/README.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/docs/custom_key_bindings.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/docs/migrating_from_tmuxinator.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_bash_history.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_pane_contents.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_programs.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_vim_and_neovim_sessions.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/docs/save_dir.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/.gitignore create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/.travis.yml create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/CHANGELOG.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/LICENSE.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/README.md create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/Vagrantfile create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/run_framework_tests create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/run_tests create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/setup create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/helpers/helpers.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/run_tests_in_isolation create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/test_basic_script_execution.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/test_default_session_name.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/test_tmux_scripting.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/vagrant_centos_provisioning.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/vagrant_ubuntu_provisioning.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/resurrect.tmux create mode 120000 filesystem/root/.tmux/plugins/tmux-resurrect/run_tests create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/save_command_strategies/gdb.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/save_command_strategies/pgrep.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/save_command_strategies/ps.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/scripts/check_tmux_version.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/scripts/helpers.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/scripts/process_restore_helpers.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/scripts/restore.exp create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/scripts/restore.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/scripts/save.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/scripts/spinner_helpers.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/scripts/tmux_spinner.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/scripts/variables.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/strategies/irb_default_strategy.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/strategies/nvim_session.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/strategies/vim_session.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/tests/fixtures/restore_file.txt create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/tests/fixtures/save_file.txt create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/create_and_save_tmux_test_environment.exp create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/expect_helpers.exp create mode 120000 filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/helpers.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/restore_and_save_tmux_test_environment.exp create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/resurrect_helpers.sh create mode 120000 filesystem/root/.tmux/plugins/tmux-resurrect/tests/run_tests_in_isolation create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/tests/test_resurrect_restore.sh create mode 100755 filesystem/root/.tmux/plugins/tmux-resurrect/tests/test_resurrect_save.sh create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/video/issue_vid.png create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/video/screencast_img.png create mode 100644 filesystem/root/.tmux/plugins/tmux-resurrect/video/script.md create mode 100644 filesystem/root/.tmux/plugins/tmux-sensible/CHANGELOG.md create mode 100644 filesystem/root/.tmux/plugins/tmux-sensible/LICENSE.md create mode 100644 filesystem/root/.tmux/plugins/tmux-sensible/README.md create mode 100755 filesystem/root/.tmux/plugins/tmux-sensible/sensible.tmux create mode 100644 filesystem/root/.tmux/plugins/tpm/.travis.yml create mode 100644 filesystem/root/.tmux/plugins/tpm/CHANGELOG.md create mode 100644 filesystem/root/.tmux/plugins/tpm/HOW_TO_PLUGIN.md create mode 100644 filesystem/root/.tmux/plugins/tpm/LICENSE.md create mode 100644 filesystem/root/.tmux/plugins/tpm/README.md create mode 100755 filesystem/root/.tmux/plugins/tpm/bin/clean_plugins create mode 100755 filesystem/root/.tmux/plugins/tpm/bin/install_plugins create mode 100755 filesystem/root/.tmux/plugins/tpm/bin/update_plugins create mode 100755 filesystem/root/.tmux/plugins/tpm/bindings/clean_plugins create mode 100755 filesystem/root/.tmux/plugins/tpm/bindings/install_plugins create mode 100755 filesystem/root/.tmux/plugins/tpm/bindings/update_plugins create mode 100644 filesystem/root/.tmux/plugins/tpm/docs/automatic_tpm_installation.md create mode 100644 filesystem/root/.tmux/plugins/tpm/docs/changing_plugins_install_dir.md create mode 100644 filesystem/root/.tmux/plugins/tpm/docs/how_to_create_plugin.md create mode 100644 filesystem/root/.tmux/plugins/tpm/docs/managing_plugins_via_cmd_line.md create mode 100644 filesystem/root/.tmux/plugins/tpm/docs/tpm_not_working.md create mode 100755 filesystem/root/.tmux/plugins/tpm/scripts/check_tmux_version.sh create mode 100755 filesystem/root/.tmux/plugins/tpm/scripts/clean_plugins.sh create mode 100644 filesystem/root/.tmux/plugins/tpm/scripts/helpers/plugin_functions.sh create mode 100644 filesystem/root/.tmux/plugins/tpm/scripts/helpers/shell_echo_functions.sh create mode 100644 filesystem/root/.tmux/plugins/tpm/scripts/helpers/tmux_echo_functions.sh create mode 100644 filesystem/root/.tmux/plugins/tpm/scripts/helpers/tmux_utils.sh create mode 100644 filesystem/root/.tmux/plugins/tpm/scripts/helpers/utility.sh create mode 100755 filesystem/root/.tmux/plugins/tpm/scripts/install_plugins.sh create mode 100755 filesystem/root/.tmux/plugins/tpm/scripts/source_plugins.sh create mode 100755 filesystem/root/.tmux/plugins/tpm/scripts/update_plugin.sh create mode 100755 filesystem/root/.tmux/plugins/tpm/scripts/update_plugin_prompt_handler.sh create mode 100644 filesystem/root/.tmux/plugins/tpm/scripts/variables.sh create mode 100755 filesystem/root/.tmux/plugins/tpm/tests/expect_failed_plugin_download create mode 100755 filesystem/root/.tmux/plugins/tpm/tests/expect_successful_clean_plugins create mode 100755 filesystem/root/.tmux/plugins/tpm/tests/expect_successful_multiple_plugins_download create mode 100755 filesystem/root/.tmux/plugins/tpm/tests/expect_successful_plugin_download create mode 100755 filesystem/root/.tmux/plugins/tpm/tests/expect_successful_update_of_a_single_plugin create mode 100755 filesystem/root/.tmux/plugins/tpm/tests/expect_successful_update_of_all_plugins create mode 100644 filesystem/root/.tmux/plugins/tpm/tests/helpers/tpm.sh create mode 100755 filesystem/root/.tmux/plugins/tpm/tests/test_plugin_clean.sh create mode 100755 filesystem/root/.tmux/plugins/tpm/tests/test_plugin_installation.sh create mode 100755 filesystem/root/.tmux/plugins/tpm/tests/test_plugin_installation_legacy.sh create mode 100755 filesystem/root/.tmux/plugins/tpm/tests/test_plugin_sourcing.sh create mode 100755 filesystem/root/.tmux/plugins/tpm/tests/test_plugin_update.sh create mode 100755 filesystem/root/.tmux/plugins/tpm/tpm diff --git a/debs/resilio-sync_2.6.0-1_amd64.deb.REMOVED.git-id b/debs/resilio-sync_2.6.0-1_amd64.deb.REMOVED.git-id new file mode 100644 index 00000000..4fed5131 --- /dev/null +++ b/debs/resilio-sync_2.6.0-1_amd64.deb.REMOVED.git-id @@ -0,0 +1 @@ +63afacef10d1b276bb5627477bc6d03ebd15e708 \ No newline at end of file diff --git a/filesystem/etc/gdm3/daemon.conf b/filesystem/etc/gdm3/daemon.conf new file mode 100644 index 00000000..ce951a85 --- /dev/null +++ b/filesystem/etc/gdm3/daemon.conf @@ -0,0 +1,33 @@ +# GDM configuration storage - modified by kali-root-login +# +# See /usr/share/gdm/gdm.schemas for a list of available options. + +[daemon] +# Enabling automatic login +AutomaticLoginEnable = true +AutomaticLogin = root + +# Enabling timed login +# TimedLoginEnable = true +# TimedLogin = user1 +# TimedLoginDelay = 10 + +# Reserving more VTs for test consoles (default is 7) +# FirstVT = 9 + +[security] +AllowRoot = true + +[xdmcp] + +[greeter] +# Only include selected logins in the greeter +# IncludeAll = false +# Include = user1,user2 + +[chooser] + +[debug] +# More verbose logs +# Additionally lets the X server dump core if it crashes +# Enable = true diff --git a/filesystem/root/.tmux.conf b/filesystem/root/.tmux.conf new file mode 100644 index 00000000..a8280e87 --- /dev/null +++ b/filesystem/root/.tmux.conf @@ -0,0 +1,79 @@ +# List of plugins +set -g @plugin 'tmux-plugins/tpm' +set -g @plugin 'tmux-plugins/tmux-sensible' +set -g @plugin 'tmux-plugins/tmux-cpu' +set -g @plugin 'tmux-plugins/tmux-net-speed' +#set -g @plugin 'tmux-plugins/tmux-battery' +set -g @plugin 'tmux-plugins/tmux-prefix-highlight' + +#If you don't want TMUX Resurrect, comment these three out... +set -g @plugin 'tmux-plugins/tmux-resurrect' +set -g @plugin 'tmux-plugins/tmux-continuum' +set -g @continuum-restore 'on' + +set -g mouse off + +# panes +set -g pane-border-fg black +set -g pane-active-border-fg brightred + +## Status bar design +# status line +# set -g status-utf8 on +set -g status-justify left +set -g status-interval 2 + + +# Info on left (I don't have a session display for now) +set -g status-left '' + +# loud or quiet? +set-option -g visual-activity off +set-option -g visual-bell off +set-option -g visual-silence off +set-window-option -g monitor-activity off +set-option -g bell-action none + +set -g default-terminal "screen-256color" + +# The modes { +setw -g clock-mode-colour colour135 +setw -g mode-attr bold + +# } +# The panes { + +# } +# The statusbar { + +set -g @net_speed_interfaces "enp3s0f2 wlp2s0" +set -g @download_speed_format "%10s" +set -g @upload_speed_format "%10s" +set -g @net_speed_format "D:%10s U:%10s" + +set -g status-position bottom +set -g status-attr dim +set -g status-left '#{prefix_highlight}' +set -g status-right 'CPU: #{cpu_percentage} | #[fg=colour233,bg=colour245,bold] #H | %H:%M:%S ' +set -g status-right-length 50 +set -g status-left-length 20 + +setw -g window-status-current-attr bold + + +setw -g window-status-attr none +setw -g window-status-format ' #I#[fg=colour237]:#[fg=colour250]#W#[fg=colour244]#F ' +setw -g window-status-bell-attr bold +setw -g window-status-bell-fg colour255 +setw -g window-status-bell-bg colour1 + +# } +# The messages { + +set -g message-attr bold + +# } + + +# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) +run '~/.tmux/plugins/tpm/tpm' diff --git a/filesystem/root/.tmux/plugins/tmux-battery/CHANGELOG.md b/filesystem/root/.tmux/plugins/tmux-battery/CHANGELOG.md new file mode 100644 index 00000000..6962b902 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-battery/CHANGELOG.md @@ -0,0 +1,41 @@ +# Changelog + +### master +- Added `#{battery_status_bg}` feature (@RyanFrantz) +- Added multibattery output support for `upower` (@futuro) +- Added Chromebook support (@forkjoseph) +- Added battery graph, simplify interpolation (@levens) + +### v1.2.0, 2016-09-24 +- show output for `#{battery_remain}` interpolation only if the battery is + discharging +- prevent displaying "(No" for `#{battery_remain}` interpolation (when battery + status is "No estimate" +- display all batteries that upower knows about (@JanAhrens) +- acpi battery status (@cpb) +- fix issue with status-right and status-left whitespace being cut out +- fix issue with the `pmset -g batt` command output for macOS Sierra and further + +### v1.1.0, 2015-03-14 +- change the default icon for "attached" battery state from :snail: to :warning: +- add support for OS X "attached" battery state (@m1foley) +- add `#{battery_remain}` feature (@asethwright) + +### v1.0.0, 2014-08-31 +- update readme to reflect github organization change +- bring in linux support +- small refactoring +- rename plugin to tmux-battery +- add contributors to the readme + +### v0.0.2, 2014-06-03 +- switch to tab indentation +- do not automatically prepend battery status +- change format interpolation strings to more Tmux-idiomatic + `#{battery_percentage}` and `#{battery_icon}` +- refactoring for simplicity +- support interpolation in `status-left` option too +- README update + +### v0.0.1, 2014-06-03 +- tag version 0.0.1 diff --git a/filesystem/root/.tmux/plugins/tmux-battery/LICENSE.md b/filesystem/root/.tmux/plugins/tmux-battery/LICENSE.md new file mode 100644 index 00000000..40f6dddd --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-battery/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (C) 2014 Bruno Sutic + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/filesystem/root/.tmux/plugins/tmux-battery/README.md b/filesystem/root/.tmux/plugins/tmux-battery/README.md new file mode 100644 index 00000000..7cbcc0c6 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-battery/README.md @@ -0,0 +1,128 @@ +# Tmux battery status + +Enables displaying battery percentage and status icon in tmux status-right. + +## Installation +### Intallation with [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm) (recommended) + +Add plugin to the list of TPM plugins in `.tmux.conf`: + + set -g @plugin 'tmux-plugins/tmux-battery' + +Hit `prefix + I` to fetch the plugin and source it. + +If format strings are added to `status-right`, they should now be visible. + +### Manual Installation + +Clone the repo: + + $ git clone https://github.com/tmux-plugins/tmux-battery ~/clone/path + +Add this line to the bottom of `.tmux.conf`: + + run-shell ~/clone/path/battery.tmux + +Reload TMUX environment: + + # type this in terminal + $ tmux source-file ~/.tmux.conf + +If format strings are added to `status-right`, they should now be visible. + +## Usage + +Add `#{battery_icon}`, `#{battery_percentage}` `#{battery_remain}`, or +`#{battery_status_bg}` format strings to existing `status-right` tmux option. +Example: + + # in .tmux.conf + set -g status-right '#{battery_status_bg} Batt: #{battery_icon} #{battery_percentage} #{battery_remain} | %a %h-%d %H:%M ' + + +## Examples +Battery full (for OS X):
+![battery full](/screenshots/battery_full.png) + +Battery discharging, custom discharge icon:
+![battery discharging, custom icon](/screenshots/battery_discharging.png) + +Battery charging:
+![battery charging](/screenshots/battery_charging.png) + +Battery remain:
+![battery remain](/screenshots/battery_remain.png) + +Battery fully charged:
+![battery_status_bg_green](/screenshots/battery_status_bg_green.png) + +Battery between 99% and 51% charged:
+![battery_status_bg_yellow](/screenshots/battery_status_bg_yellow.png) + +Battery between 50% and 16% charged:
+![battery_status_bg_orange](/screenshots/battery_status_bg_orange.png) + +Battery between 15% and dead:
+![battery_status_bg_red](/screenshots/battery_status_bg_red.png) + +This is done by introducing 4 new format strings that can be added to +`status-right` option: +- `#{battery_icon}` - will display a battery status icon +- `#{battery_percentage}` - will show battery percentage +- `#{battery_remain}` - will show remaining time of battery charge +- `#{battery_status_bg}` - will set the background color of the status bar based on the battery percentage +- `#{battery_status_fg}` - will set the foreground color of the status bar based on the battery percentage +- `#{battery_graph}` - will show battery percentage as a bar graph ▁▂▃▅▇ + +## Changing icons + +By default, these icons are displayed: + + - charged: ":battery:" ("❇ " when not on OS X) + - charging: ":zap:" + - discharging: (nothing shown) + - attached but not charging: ":warning:" + +You can change these defaults by adding the following to `.tmux.conf` (the +following lines are not in the code block so that emojis can be seen): + + - set -g @batt_charged_icon ":sunglasses:" + - set -g @batt_charging_icon ":+1:" + - set -g @batt_discharging_icon ":thumbsdown:" + - set -g @batt_attached_icon ":neutral_face:" + +Don't forget to reload tmux environment (`$ tmux source-file ~/.tmux.conf`) +after you do this. + +*Warning*: The battery icon change most likely will not be instant. When you un-plug the power cord, it will take some time (15 - 60 seconds) for the icon to change. This depends on the `status-interval` tmux option. Setting it to 15 seconds should be good enough. + +### Tmux Plugins + +This plugin is part of the [tmux-plugins](https://github.com/tmux-plugins) organisation. Checkout plugins as [resurrect](https://github.com/tmux-plugins/tmux-resurrect), [logging](https://github.com/tmux-plugins/tmux-logging), [online status](https://github.com/tmux-plugins/tmux-online-status), and many more over at the [tmux-plugins](https://github.com/tmux-plugins) organisation page. + +You might want to follow [@brunosutic](https://twitter.com/brunosutic) on +twitter if you want to hear about new tmux plugins or feature updates. + +### Maintainer + + - [Martin Beentjes](https://github.com/martinbeentjes) + +### Contributors + + - Adam Biggs + - Aleksandar Djurdjic + - Bruno Sutic + - Caleb + - Evan N-D + - Jan Ahrens + - Joey Geralnik + - Joseph + - Martin Beentjes + - Mike Foley + - Ryan Frantz + - Seth Wright + - Tom Levens + +### License + +[MIT](LICENSE.md) diff --git a/filesystem/root/.tmux/plugins/tmux-battery/battery.tmux b/filesystem/root/.tmux/plugins/tmux-battery/battery.tmux new file mode 100755 index 00000000..bbed7e4a --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-battery/battery.tmux @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/scripts/helpers.sh" + +battery_interpolation=( + "\#{battery_percentage}" + "\#{battery_remain}" + "\#{battery_icon}" + "\#{battery_status_bg}" + "\#{battery_status_fg}" + "\#{battery_graph}" +) +battery_commands=( + "#($CURRENT_DIR/scripts/battery_percentage.sh)" + "#($CURRENT_DIR/scripts/battery_remain.sh)" + "#($CURRENT_DIR/scripts/battery_icon.sh)" + "#($CURRENT_DIR/scripts/battery_status_bg.sh)" + "#($CURRENT_DIR/scripts/battery_status_fg.sh)" + "#($CURRENT_DIR/scripts/battery_graph.sh)" +) + +set_tmux_option() { + local option="$1" + local value="$2" + tmux set-option -gq "$option" "$value" +} + +do_interpolation() { + local all_interpolated="$1" + for ((i=0; i<${#battery_commands[@]}; i++)); do + all_interpolated=${all_interpolated/${battery_interpolation[$i]}/${battery_commands[$i]}} + done + echo "$all_interpolated" +} + +update_tmux_option() { + local option="$1" + local option_value="$(get_tmux_option "$option")" + local new_option_value="$(do_interpolation "$option_value")" + set_tmux_option "$option" "$new_option_value" +} + +main() { + update_tmux_option "status-right" + update_tmux_option "status-left" +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_charging.png b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_charging.png new file mode 100644 index 0000000000000000000000000000000000000000..7695ad494aa5d36f6a2cf6e61f49fe6f33dd48ba GIT binary patch literal 10484 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 literal 0 HcmV?d00001 diff --git a/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_discharging.png b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_discharging.png new file mode 100644 index 0000000000000000000000000000000000000000..53c6134d40a0bec30b2ccc764397713a2c47208a GIT binary patch literal 10447 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 literal 0 HcmV?d00001 diff --git a/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_full.png b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_full.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3cd82b63c72f82e294867dc9468f2f979e5565 GIT binary patch literal 10287 zcmcI}V~}Re((TipwmEIvdfJ-SG^cIbwr$(CZBF;JZQHi*yyyGwIVa-&zB^*?s-3x3 zW@ScHMr2i(oQxPe3=Rwc0DzYe7y0#fy!rbwd;|Ua?aJx^0RXUM&4h*JB!qcEGpTvYDA3N*VxiTpcTg z1BpDMEQ9An_@(%E1#kHY!sHDgM5tX^ z;vZrF-K7C+r+(y{)d9A-b2WL0*wdpa2oDPd{gD`E?53&71s;9po-mVD7wqhqA$@b< z0bx=_v;F{Gc0c{Juk z@Dhl+kxnd35Sh3KrHQ5swpzJ4C;QR$+do5fBAFt|wu7HL_!kCo^aTNOL#>P|16!)$ zk^!bl1Z*&2O^z>78>aFyJr@OeaXZfUFCZ7WYXM-iU)v-gOvRIO2*BJtKO*B~q=7o2 ziueGnb)sONnb&6|4(`x2qRUWdhhm4^wG&wc_Tn)WCsR8a$4L}9K4fv0g12u@jP@dM zA{CEyY~J$=CO1ND?v}L?5QzibsZl<@VN`?HZK+}cg=aQ=sGCvV~G z|Yav=gm-;QWZ>p%y zc%k}qs=SLq8-;sYnG?zdsP|81G8M@10epe)GxF8)*^1h)cV{&f&;?m8C?QL0}?uBp+x?;pNm7rCxzswZbv%m+z={}o9N0w5*xeb@A+=X~dwgJ+#abvvUED$tKJ){n0YR5}+H z&X=kd^syJh)qjHVw2u(9UIwt%M;{AP->Vmk7#;9S4xzl)%@$e{N_rck6%5~3`x=}l z#9@!_8Bp9ut15yN7%GQ^5QvB@NQ&$xf<7b4PFNfYzZ>XE%qNb75;jP*7PldeVGj+!x-oQ~0&S?F&>L1lH*Nhv8Jq~j6Vm2u*sc0!8sWPb` zDa_PMrY>W3!iI!{KSPE#_P8%dFK}&1?~(6OLV4oyaFp7Ks-r}bY(-hjQfVfKy2^&l zhL0wjBbtMrQEfRdsIXuWq!C18#>s}spvhyjytE3HaFxF*hbk2p(H4mpAr}P~vDp#W z(b+wkzcqtdnyg$lNY|pS6fH}ye5}l^jIFG#hyfW9><|nP_@g&)(Q#XVoAxN2ML;^B zFtCAh%E8$|#-Yxk%%RPW%pTotV;^T{sI{n-u5F;Lp^d=~(e`T_d6#J)dV6I`VQg-S zWtgVdqW61m#)!u7Ti_E^4rLCN4weqWmQ#1iJEu3$TkI436ZO62r39Q4!V%&foEd^1 z8V)+&-`-!we+_&Lq66F{FfeF5C_g9~x(QYq+5z_aw-A^kXbxD}aNAHzBxvLjR5N5Z zhEXzeN*sE1%2gsRI&w;5A`A*=$x01NyQq7dB{nmQ)5T6S6SO4^M6@YX8`Qu1Hm){l znO>fRiFAapj1HUDP4TvRKQpm0v14Al?CclnZ0Bt9?8q$JEQ28>^DDE4(WoK*7>Z$& z(SYGkLyrSFAbgu{8*v-Ho1(S?pGdbzw+)?l)#U1*CL;?d^gl4cFgGx4Fg56H=vHWR zXf-t6zvAU?e~rqwSKKS82?I6TgkIWUI>M7A(j>IP-_|&eMFkUb0X%289g@B@!lj zS%>Y*PAQ9Ci%Qe*bG#MYb=vM;y|3X91@0F2rS2v7qU@p8*DJR61EJlid`dl1Ur~Oo zem#OkeXV(wdZjzS0a?*eQPzSAQHPPA2D8Q=R#lb`RyxZP zt3Ot?TA&`2AKM-o@Cxyoxz=q-Ik`A7fZYzi>{c%wm(m8@BJR|V)G$d>EK`oEnXB!p zt*mLSH?0?}9WKc)#n#1m5_z0md9L@L;BG3Ph~3-Vl-wsQSvOL9ZmL>>U4ox_$xo!i zGA?Znw{W{(4l$DH=IK(ruK6zcOuUjyALp4*BWsFm>aH4d>bB&25I-S5-98gQ+(E=Z zhrk{{W58v=PaqB;r6JFtFu`SmutIPVUr@}E)p58mjR~B|Ey>n-JL&z=c2H-KM)0vQ zR*=bXldu*r=?JordF!1v7T>GpSS{3z;7}TZ`fu60|yo#6#@%M=k(byHb!|8^<9^2{*LR&R>1 zQ(3MKF&i}#o9(`G-r7i|Ps~o|YajNMm44eIsp{22fPz5mIG9)M@MOVgtu& zZT7Kqqu|3X#6axH>TK=lGIhhO$HKMcAbYc``0ebH!_nMD+b8#BTRlZ|X(0p$vBufL zS?6r#wCrl(#OhpQYiYe^%jYa^q<}kyj)31)|EbWX*J=AC_i6i&!dD6ERDX^ab~u5$ zXZ9=T7x5k0*_gjx-%hBsJ^=g*6fW5fsrY=RX&44?QH$AgBxqiVC5lNKFQ9p!HP=b@*IahHcHD;5Nn zfd=G;2#2&g&pRd9Rah6F)-Nm_DOF;6bow!Rj?c!=7kx5)BeK86q}m%+_c|OB67>23 z4uB>L;B?>NfViv4v`_-`CMJ=C(&rFCe(`nI?Xa741@mW(%NZOa>@OWQ6hkP$HMZ7G z(^t?%+@?IjJxJb@*tOa*LAJ%LM0zE!*Jjl^&*RJpOxPDJgJKp?mZq2cJYJOv0+L}H zi6tp6;51R-lop3Cl3z$=S)6ItlpLGcT+eLT*v?!BF^!1K%}<@zx^?}oMc1d(GqC<{ zo?_+md#7x#lcgmhy`oDa@J%pAeF{puhC{|<%1V75)Dx@Bvm3@c_)`W%0~E}^v~QB= zO!&t@Y;D|ia%e(aM}dCy%D zic|XArSJVRuLtw(qw;x2XAfHgjm36vMZjJNpRo@wPXddFA-N0rl^Dn+rOM8#!Qt>n zxHAT3@_e=_m6z@9O<7)j-0evCRnjtcHFcYLLBl2+^wI64PWeT}n|<6x{HoCr4U-C@ zPDS^os!v5;SKY%JR8MA?M~BEG+shdL|u63*Prk0AQr&_){<=< zfi_LF%w08qE%@&CS_xkEjS}t0mQ8Qg4qcyy=Knb_Z8Tj~wn-O^6d%_=PiVcn!G`V* zE0!1?L0JoIzPs3#)Z36)24=h(tC+0*-gr5I_Fy+sy}y;)ZVtbf`OAtO#nj<1QH9f1)1L4#sdKsAUX-aAO^v=$UuIcXTXM~*J=|2P zP82)*KFV3J)2{7kMXc6_RY9+L(P1dRvKicxvstxwkaaNnsbFze)nFB}=Hf`YF4L9Z z)v~Ys@`0KafRg~d|kc|+w;BBU7x!*@d$C|LG;vnkN-ND zw;ibHBEhdg-;CYt{BA`+#c2TX1oyDPp!#OTD}`#jbnW5MZ~qJ(iHnrOHm_GZzxzR0xQ%@lglp)@(LuT&u2!L z9;bKa+?uOJmVCO(@da&M2iQI=19XK^NvI5zQFU)89M>&---Cbn8Tlp^E`&PeMRn25 zG;dh9bQOWs40sG1muMd8Vrr>`pVh9pJzd}{XKQBHbe6M=_I>#1%}q>{X+(O7^Lfqd zZ!z{fd>Ve``Lg(F1T+RD`)dgO5{B;=P_=lj{&iTZ>sOGL394J*TQ|B+g6E+S4CkS(pTHj&v?#kCx}Ws~qp*4>x@jIgnX7>~LYc zQ$A();V(}8s*57CVjVRNu+jH7UrHVYSJ2?n0DHac6KACC1i-!~l)xz@fF}~bDF?8f z0Xg1O_f1~{CAFN|`Tzsr6z~U9a8$~Tf;y#|tpXTQffW89j0HSU>4N-~0klNtp|tvd zy8*0y!f_}Yk^)Nq@I28{{&q}bw~u2)DcpwN@paUeNMij}13$J$?WV5JT`f}MnoyDa zL5Py3MF&xR{yP zlcESgueCP9Gq^K6)8jDc8OfWli*mp-;Z8waqIAJU^egdI32(`sinj6h$?*;EE!8cH zt*Pz2?)-x{0wllUY5wIzKfU4LQk6a@{1fxKpGv4h0CME6ucUAuiEd!@_mZOM3(56L!^=1pmG zU_Ir9CMbW{DcnlN5}2mwT(5r|DfBSnFxo_dDXX>OnN^n8Y^D(5neoS}!NW*vA3v>o zWf&O1JoT!b>FRVZ{l%R#5)^ZuGvx)bm1N>{sEonvGta=M-Cn2p$>RRQ!s$am*#hBQ z03hC{9>7-%v02+33u-R_VG7`_wXTh{C6Nq8NBKqrYE%nz4f#87wiI4cIHus@*hC7c zVW`=_X&I|B5x7%t+j8?w8?gu82dqbAn&O;%ouVFvH>@N~MTa-f#%A({W_v+ z^R4}z_MXGO$8Zj*0CFi3D-tg1C~`B39)=s0yW075I+7g;w00O`JVz12PpDC>5y{cI zv4q84bn)GDx0(nxk^^ipw91tzmi?LuR~ z>C))p0+u($xVl_(Yx6octZ1b$X;FEF$!+QQvxq+Fa(6T3V~fBC8_S1_i}hyrjb@*1 zkMc+(%r0WYpQ>sqZHxM-AF~~EE@d^P=Sx!+&j+ph!?Jd@5Wo%)Q~g>8f$4>qhS(&5 zt7SKgn2r@HM0bm^FCaIiRS!eZvrHvRj&9N)t7T4zv>2q@fxk(67WAjp!`vaW1FMS^ zA^s7E&vML|$e3S?aT_=icmk;w;u*0k;5M8&L_9P*dOE>1=A5eK_dz5^N)gl$J{Ecg z;erywD9dq0#HZs;0s<72>HCqF(*Hm#CPFf3xkwptCy7LgLE0nkmHbKGKs!v!P`4=1 zC&r{yCeo&T5O>Pq0xV zq5LkkB1I!5B7!{v=|-gJxNQyt{DAY5OE5ca?*iDiMny_33PrLCrikY@Z> zvn&;QnM4QV-&2Aa-a@#=F7r42NB&8BUPd?5Exq5FCT(xGPO#l*$^=`Qif8*1 z%pbRlbL2@`N(c)v7Mha}i|Gq&nu%?W_b?}?(H1`+-o6)E-)~A;%vfew(p=W|1ax@p zd5?p=RM%aicHw_y#=PbjBC7LhVRJq8e;y20w8kB9m>DduHQG7qKY6T&WGUqErFqGu z)4$kXTdZ>=*f?xWO)gLH|YS(c5-IZ}>AUrK7YzlniX40w=qB{U>a^~Tj!dm)Da+D=+cC5L|!f|A-lg3I7FgwBRLHm6jtE zwy`%NWTR)LXC&r>AtWT^u{Sj4`XwUzzx2OMztJ!}%Sv&l1Sbqa#_(#LQM9;|ZZ`*&VJpV|!p8rYKzodV&#RtQ~@bAp?!9*!gx&FNx zx|0wQRCEQo(1cY?5W~PH6%aykg8`4@5QL}wg)aoH!o~7QXQi%7*Q!Vu6_(d8!Fz1qAG7W2zrYYdrjV##Se`YPe9q&Om1@MdOPJ~ za+$@w_3@d;y$3Ayd+7$C2l~PgF-iv=`WO2n^&$ymit@;@fg_bD(dC=+h0cY7l?MZM z8_R#7O+eY<*a}36b?N6qwt7~LrW(J*`&tc_Ipqg)UZdPV7_Dt|_ur)Q!?8AZ!p~R%& z*vs1;)*{)k4I-%m#O9~8b2=`i^i0Q^4VKpq=tQRDTp|7$Q951NI%rC|WVZ$vwEMaB zGb@!p0RLG3%uEV{$9t7IEv~p;=FNj18j%T#prnMRsTD`u#3Rj7PN%@owwVrb*wOlVW4;(8sb>|Z^2YyF5Nwxu01p1 ziB5^ytMPAdtnoP>a&G9@HaxJn!z& zTc~4I3v1;=mkIFm20%i(qet$*hF)$)7Y5VHQLaVOBwjGueQ4|;ZpEL%L54~>2}4Dx z;caN~MhPSKHOQ9R0EjfHp#?zUm7&1>gXihdi5GibLjhh$$#!^4zOD%;7M=GDTzHgwAo^LT z1>R&Ln<+C|HucIiW2H*Nw44Muee~%)02xbs8IqHF(sG<0Qr14+qXY+A0KWe{jf_iH zb`z@%g@3`v{j5!+;`{BV_@sIY0(18+tkcrJJ=_f>r#XJ^fHjU=$h#|2p?|R(1w^UE zoj-h}5$Nc2B~}+~E?m!LN98zN2jh*A1MGJ=H|nmnl0}W4lOrJXxyK0~i`a_GG@dA^ zFHu~lS5|QRS2M41`R1efl^a)CQn5p&!H21Moa{JoIDo1xJ^)iQgc_z)RlZCAbh$WrNHVpSwZvM#P`=QU@Jcs~NV0Efi0v#E&+(A=h|fP2+njo(fMmcIa^ zMzV<&$^#P~UA|Ij)s*uXe8)@cw$4jE%BiT1m6?t>kJeHI%}fsz7=OHT&-OoI7%3 z)K*2Q9zzTZsB1)4u+HSp3-EU$lk5nN0+gT_jy`t7)95m2s@N+Z`;8#kT!1hS_KtY& zXwSqAruHvYyAT~M`&>6n1{y_U4qeC}WUk*8JsmtNc^%BpSc@0b<9^6)3sD~xkulSn zjuSp{zzO_b5$3}ZcgG*w*p9{_=wZR1hN(U$)s(q$jpNyYsZ+E672|kk?6j5ST~I(# zeGU2Y?)mK=w%eTQX3nl0`MM472}BPmRGV}ThU=GK)z~Pfiuufrto6&eE7&)(NCLX^ zFWa*dj+JV|>Af>Eh;Ku6W&}Y=nh`vTz8&n5Y_Xl1u=8jirl%LUbuV_9hLh+E7l`RZ@Cr@ns1%20?zl+zPm~VMp$UM z4}BeP60Kp`^GRKzSC@6Y&uUEcnuV2IHh63)ISG6Dw__aJRK}{C_uS=T9%D`Z#$t(0 zgM)^LMGozy<^E}>^$E3991U&F`Akvo4aqebrd{}qp3S(y<%P~1(Apbv(vyl!`FYf{ zJcnnE;!5^LZSvw5N$ib?^&aG~?JCnSP6bi(Wr|Hl-;XSbJMekKNC#eh6UpH+@6|;j z&y_5+uH{evyA|5v4%0^BXaq}g15f`O&ZGX;ORCW?9h_|RRZ9)J>6ypzNt8>|i+HUl z?8g2uKzVHesWRaSwCymSmTgc$htxAUs4#KlpnC(5?f_(!#V?&4so&6@bS73E$s}|3 zb?*>g*G5;|lnc!V9grSUMQ&Edo6kR)jBexM%X<*gQA<&6frtHfr-7G8Wzuzl5!k2mULP%hl^xd9eAiuRYzQ~ zd6ScwuWU80B2a(r#CEaGUs`Ijv!@d|8{yIrI?>W)Acl-H?U|fj!9Oy=1soN7NuhF3 z_e$pGZFD;H(C~K>97dk3LMi^fwnO}qySqB_Yo5q9?InuVyVzH?c z{CH)hZR$nue}}f_h&4f%b4W~nD0_64j40X0RY59t$DmlU3-}`%OIT0cq z5s)^gz>iPC&x6F7qh0I*UQZS3X?8o+0^8H2KtiM3)+AsR54?PGHEX2>{}_ND)WJ#0 zp7U6tx`YEWF7o#TknC*k^6q+ykXXZ3%F5Q`FYK?5#W7KIv*M)PtFzT;1>bnHik8$1=B}H-e4t6-E$> zP?vGrc68gN6vf(!li$1%j{-7&(uWjF)VLh%PF~xW46xk{za9wkSqws}91YwSa$iIO zS*QdOGZ3f5_mb>GU|FH7r$6PuI10SGo7nUN0eoi88uza?H#zaR1sL< zf0N_z_h@=Cj@xZfMIPg!V*~bBtC5z|!=^$-QFD+(d{?tienwFxl1!|h$LE{#W~WrE zMeh?8hF>~NI9m!&ZQTKwWu9>h zZx(IPNZ{V#<5}yvPUAt;#d+JsA@BCpS-dgPZI=%tP{5(x$dp4D&>l2uuG2}?ca=5A|QHl*zIAY7Y1ZGLk=rP?9jrt0CMo zX7OdVJ0mB-mDX(otD}MF#@R117w6olr8Mj;RdjfCQBG_fcMjCBXc;B+X(H@!|AGkS b);xU?qzvI&@8&oD(~L{}kP)dC()Is8Qtr)B literal 0 HcmV?d00001 diff --git a/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_remain.png b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_remain.png new file mode 100644 index 0000000000000000000000000000000000000000..c8731f756fef127793f6b75a28679061df580601 GIT binary patch literal 18457 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 literal 0 HcmV?d00001 diff --git a/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_green.png b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_green.png new file mode 100644 index 0000000000000000000000000000000000000000..30359c61800236edf38dd6e65470f84a70ade6ba GIT binary patch literal 5831 zcmV;&7C7mNP)4Tx07!|IR|i;A$rhelQV2;Xfe1(my$RB*^j-v{gN={`2qlIAjpmgAC9v$gBLP_H}UcUVn%Gz_<V?ZJJ6CxhS8};**jq*SN)PEV(%AZysO*UE}^T+~EAkM+Ha8KMF z4~I{0*z9l@+;zl{r8F`tF@We#3?>E=%}04~AnR<{M1cQqbYZaP!R(}51S2_oi${1u z=q5ZQTq8&bw?I62EQ>O1HJx81`hhtMOau}bEpRxyR2Z{�EEktQ~P*+ynB5+;JwZ z1*~ufn28VW1#@$R+V2^PN4b5g<&X18S%06;u%2!~cN}JsI{Ie(My-B~;`d#RxUdiV z(GpvV?ZeJs$FXzRA*>a!u%lQTb`d))#iJ|Xv1}!b%oZ)`7tbFN)@S7o=E#jwV7n#Qj5pb->vFvPYodA%2-{qf=H%!@g8)2UR zrprABfNLpKrhn714FNd#1OUdnZ#u)*aC@x;;BXg5EGm%eaOr~p|2350&d>z9zz~?h zoa}%Ta0lKX0EB`_5DSvPG+6ZvkONuI1arY6Py))pO0X7GgUw(Ys0X{jUeF2-f#cvb zxB$AqHE;*6jUMm<^n-U`5J3G^ zF;a$9Al1lLqyhOAIfxub&LQ2%E#v{xi@ZiYp%_X<)lePO1RamMpgw3A8jDUv)6rbC z5G_WRqg7}vx(jVVkE0jRYp4W$fev5*Q^c5&cSo>`FJ^Ajo0HX_(}W<{s8aCzY=H!ZGt7ijSxae zB%~8&5=sb_gdKzfgi~LD9wT-W9}x#gB$6h{ zlH@^(B(X{Pq!QA4(k{|b(q&Q)=>u7jtVgyZ2a=P?0&)?#lDw0AgnXI&lsu@QtYEC* zrVy#XRhX@?LSef?yTT=f9)&@Q3dNM-L5ZbgQWjCFC{2`8l)IESii(N`imr;26#0q^ z6{{5YD4tb(p!kuhO0}T+QKwMF)aBGV>M`mq>Khu3Wci^p{EsO2$e)O4F1Il`56?DP2JIAh>a)~q)DNpmm>AQ98N$qFu3+wEUT1z9qcg^53~$V`F->DG zk9n^#R>NC^r%|fWtZ_}_lO{_uKr>5om1e8vJuO_zLTi%NOs!2?r?mRUs*QCY%Nbib zcJJ8R+NidLcC_{!?QPl@wFh)`b%Jz+I_q^#==A9_b-i^nb=T+~(e2e^=y~e#_15Se z)qBoTXZf(QSyil)tbToM{a}5u{#N}?{Xqj$gE)gCgJy$!h7>~=!!*M+h8>3eMtVjQ zjpiCP8r?QlFm^G{FkWYT#`wL7sY!y#5|dVwXQmpaA*O|zC%Uye5#pFDom_%q|b+Bn)|+ibVFW2Jg(-;3>4>-Esv z(3|VM!~3a^xlg9gE}xgaHohX?1HSM5-2CSG9rMThgZxYVI|Eb$;sUAz?gttKrUy0# z_6Ioz%?UadOb8AOUKM;JL??t3(h$-g>Kr;R^kf({EGDcv>|wY?xG21RB04d2;_8Wa zBa9;i5v`FRG9+?!}oiXoXePdU|-ib4d z6UTMLE5%QVZ-{@N;Ga;DAW0mbI4|)+l2#HwsV$k59G|=+d0=wDC{smObt8bfxL+>HAU$DG4b%Q$DjJ*|qF})R5E-sr?*3&N|Kut~YlLx0mO^ ztKdCN^GK^mdzS8zzB;`(!z-gQqmS>$ujaqX49?t~`93Q$t1fFOJ0ZI{hn$m=b5Niv z$P%2Kp*v&NjBcT&utX@yb<16w+b;?e?Z`v&rslQftHGnrMX{OqC-H*<&w`qQ4>RLu z?wh4DOEBx=Y>U~;WW3K+(MROm_^O?7GJ~BUbe#ZjC1;q<`76vV> zUqo4ywdnUEo1%)Mw~G@Nw-@UaFD!oaQ_xS1CG-+e$&DrMOExdXm-3f(F0)^@e%aSj zZt3|lo3hHX&*hx*^FQ1ET=nzN^0eihE1XtrT1i|fSb2Sw*Q)vom5RcON2@2UZdt=x zQ@ZBu+UaZ0RXS8|UPoCcUMHyvuWDOww0`CK&(#^#*J^xgnm1@~ShnH)M()PTo4hwQ zZPwXbw)xW*{+63tgSNKRn$%WqBW^3$_GEkf_A|e@{L-*PYe(6RFLi=CNquzv$p+_! zhMn3wS2UuH;>O-xQ+9Rj_TSysWYx5_nb};n2ka5=dH!q4uh;j6?d{m-vae~s@%{}5 z7zavQke1mk{jC|TlD4F_?t`HRJKEjb5Bz5RTiqf3Lp6uh53e{vIZ}LN=xE{5fn&mB zeaF*}KkAs?apy$hiK{0ko$NdncIxcuz|$wr_?$U<*5mATW>+~nST zb}ReVtJ?*)2k$JrOSoHlPx)TueeL_Tf0+N#EOC+?e&GM$;=`DScOG#by?C7W_;XM3 z6WWu?r+QBtp4mM+)En5_^?dU4o)^LwgMB4`s{Fa(rP<584d_40h;nUN>nV(6YtG<|jY5yAb_3lv4(2$TV zV#|&K7;I=-8UU~B0H7tovje=xQRwpfmrM}(ol%Csf5P%RnoQuyrOq3GxP<_O!!ybz z*o+~j!d`m(j`aqpz5Qq#mb^53J9#WByu}bc3=O@}0f5vFz!%Zb(BQ_Qp)cDZ*;@b{ z%az~zq(X#e{4I1TI@ejg5d0wj0*7dAQGoE2s{jBBX-PyuRA>e5S_^PgR~i29WA8qb zCGS8&2s8wORA?O#6&gB}M-?d`4z#sMMOv-4VkwOjr?j>NON&ZDYwHxIXa`253Rpi3(sT0$zMgA26SKP4Ey2dqEPt2ox>1QXzUg+~F5H@O{@_($pc@?_N@xBRpL z?Pq+T3OVg5!g3KyrxaZrGI_(_sJpiUgRN7bSYO`ZP@2e+wxu z7xd*OxVQWYzD$i8)_~-NY4b*~RuQn-z%RNV&bz-9qouu8m^N+zjcmYfgMayBa8DT% zgC}$XcBHM_jIJ$}WHBQU1^zL5-U;&$*MJ&d4*U1+iw&phsB$n-k}!NjF>-FzK=KKw zfAR`i4sa;A$C!$D0!(uG(fE5uuMVaJPhd94FOtQL=6x>YEH$I;ELp^E&9=7yAFRk;U5Lyg0q0k@BX@=tEr;AF*-CibpcW`!2-~c$ zg`}~y$B_1u?eOn>0YW5yVXW2AANml1`SZY?xA$2qC3@P`0@JoP;C|*M_;bR0Cc3xP z2-Cg26O8FLbXF{e#JiEcb~W@RW$=v643X>Jcomqq5cZ|BKs#HJ{`dy)Wn_+~o(`-% zb{InWS7UPzGEm|l)lvWF9guFF0?O}?4k

r-+e#M`;-tOZDJeWTBWBVLfO?{qxPJ zsc1yo;jRS1zW2M(_!}#P1`isywV`oq8wg3PDZ!(N9edhfJLQeO4%(B-HlTFV2$%|c zE=W*_{fGm(_h*FVu?+G^^s-kuV)9eMquEgCNx`@=17ft!_e_=ehqaVlM@s0rPJLlk=Gc`U$ zxGM1vBGZm~Xis|KD=(GNDtA>yupk@P83!0Ui$IePos9xUt&gWjl81-LuqaqP9B}$^ z=?4v9igd{SOnAd;Cg_o^6JV{8kiBpiSrLGdZ7?NxbQ*#+05M=LQy)b!AZfK=YFmL(C805)FazABf0O>?7*4Rm)_nk~XbSv>_<;iz{DZXm*I$M2 z;WZG2WR4reNZwRC7=JYYuOLFO1whMA#2{NLjYIaAxv&J24mo$4;HxE<(TIc5X)N@G z9D>nLKT_L66D4?*Aor2NX!piF$^A-j5pm>#Uc0IhRCxx*uh2t^MgRr4X0!?8eqn@2 z&IQ}<7G&H5il>2T^Wj`FfviV7272y&0BMykf@&c5GTs5rzfMCcyQ_z; z+JjZ_Em)H{u7W>Xa~v9R66_^e&|F9)S9(+JVCDr`$e9#A_FRW7xct&Jlsy|S1~}fe z!*<#Qze_}*!3*=fBvSo9G>QVPCCvpbdyKQBEH^&XWLO zwBy2`$l*imH2TFNa5pfRvFDDGLcthx%`Cg2DbC7XsrW1?aC z^;P&{(3`wNvoMSm;cXLPo*ll2IS-T5v^WxpmEe)-x9_-y>=ij^skC6in}z7y-G=s~ z9u(ZIzaa)Tn`{*3JknC1=`H#~t* zdB#Qdy+cHX%LiM--xd$=o*F+)(@Y`f61xJhycfBj z$T^URE(PLYT@DKMmEZ))`(GEl9sNmedPqw?K;}rvPR1ybc~%;(y%njhk(BV-9~~HW zSNtSYf{Ru!?9D7P$1xBiei;&z${tbSgYcxgT4CC`7p}GIQ{TOU2Qw92=$?W#HRqwR zrMQFjLhqaV6|hx%$alDKVNCPSvk(f4dkRQ8LL)H!i{Pq`hM|%V+N$I5PoI$#o4t6F zR6==pr;mxlgES`_;kzSQfg&}3A)^$wU9Z8m_2tmdxpoz#^0}&N9}pqW~9S#&6VM3yF!jaj?=GWdKQ z7(qbVf;{BSl;uZCaH4G8s*9kfMkY>)`?m%HjieM;1n}j8qkaQWfB>8ylg2U09O|mDi)1;z6jcM z_31{k399+4l<}44z@4rq=~LL=6e;1lE4RXz5l;CTdo9w}Z2|nGGU^r~We!7N*&4WJ z+#(YxA-&?8!0jvHSXwR{C)t|{dhMwy=zq5#Qb7)=b`H)>>%i+|#fAiq-CjiU9c<%M z#QM3ANJNpQE=Jd~Ik8G4_rY7_JKtGISvt@S4mh8F8iD+Hipc%rZRn~QIKDNn8{^2U z0)IJ?=E89pk6c#$tx%PN$p!S<50JYT37wiul6CgBXGoOd?L6o-h7?MYASuB=!Qw!0 z-aM&dQhFAQK8fzB;ACEMoA9=v4On7>AlHF4H4Zi~32|zg=OK~1XmC3HX|&G`#vK5k zVeS_XmV88p&PW_HQc#mA5&CzAkB5++4zb(vFmCeMNMj_?yZ7iEWR;4)OjMt`gRsOA zc|>_lR_X}^HyN9eLZlKrnN#*@x&uRI75;h9E4(ZhIllSk9Y5<;@=%t?Yn|UsAV&RH)Me!3na6^{{ZN6Sw8Qr RWy$~m002ovPDHLkV1mqj8gBpq literal 0 HcmV?d00001 diff --git a/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_orange.png b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_orange.png new file mode 100644 index 0000000000000000000000000000000000000000..0ccf4567a85cf8becf86315664841c9f728babe0 GIT binary patch literal 5943 zcmV-77s%*|P)4Tx07!|IR|i;A$rhelQV2;Xfe1(my$RB*^j-v{gN={`2qlIAjpmgAC9v$gBLP_H}UcUVn%Gz_<V?ZJJ6CxhS8};**jq*SN)PEV(%AZysO*UE}^T+~EAkM+Ha8KMF z4~I{0*z9l@+;zl{r8F`tF@We#3?>E=%}04~AnR<{M1cQqbYZaP!R(}51S2_oi${1u z=q5ZQTq8&bw?I62EQ>O1HJx81`hhtMOau}bEpRxyR2Z{�EEktQ~P*+ynB5+;JwZ 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 Ze*xH?B~v6z2kig=002ovPDHLkV1g@>hi?D? literal 0 HcmV?d00001 diff --git a/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_red.png b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_red.png new file mode 100644 index 0000000000000000000000000000000000000000..ed184b0a3e57c368d3fbe81e8134ee04ccb6637a GIT binary patch literal 5873 zcmV4Tx07!|IR|i;A$rhelQV2;Xfe1(my$RB*^j-v{gN={`2qlIAjpmgAC9v$gBLP_H}UcUVn%Gz_<V?ZJJ6CxhS8};**jq*SN)PEV(%AZysO*UE}^T+~EAkM+Ha8KMF z4~I{0*z9l@+;zl{r8F`tF@We#3?>E=%}04~AnR<{M1cQqbYZaP!R(}51S2_oi${1u z=q5ZQTq8&bw?I62EQ>O1HJx81`hhtMOau}bEpRxyR2Z{�EEktQ~P*+ynB5+;JwZ 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 Hu0mjfG)ik1 literal 0 HcmV?d00001 diff --git a/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_yellow.png b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..386ee63b5b7be8a5af5abc465dff96aed3ede936 GIT binary patch literal 6192 zcmV-07|-X4P)4Tx07!|IR|i;A$rhelQV2;Xfe1(my$RB*^j-v{gN={`2qlIAjpmgAC9v$gBLP_H}UcUVn%Gz_<V?ZJJ6CxhS8};**jq*SN)PEV(%AZysO*UE}^T+~EAkM+Ha8KMF z4~I{0*z9l@+;zl{r8F`tF@We#3?>E=%}04~AnR<{M1cQqbYZaP!R(}51S2_oi${1u z=q5ZQTq8&bw?I62EQ>O1HJx81`hhtMOau}bEpRxyR2Z{�EEktQ~P*+ynB5+;JwZ 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 O0000/dev/null 2>&1 +} + +battery_status() { + if command_exists "pmset"; then + pmset -g batt | awk -F '; *' 'NR==2 { print $2 }' + elif command_exists "upower"; then + # sort order: attached, charging, discharging + for battery in $(upower -e | grep battery); do + upower -i $battery | grep state | awk '{print $2}' + done | sort | head -1 + elif command_exists "acpi"; then + acpi -b | grep -oi 'discharging' | awk '{print tolower($0)}' + fi +} diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/CHANGELOG.md b/filesystem/root/.tmux/plugins/tmux-continuum/CHANGELOG.md new file mode 100644 index 00000000..b9516f14 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/CHANGELOG.md @@ -0,0 +1,42 @@ +# Changelog + +### master + +### v3.1.0, 2015-03-14 +- properly quote scripts +- bugfix: "auto restore" feature does not work on tmux `1.9a` +- bugfix: do not count `tmux source-file .tmux.conf` as a tmux process (when + checking if other tmux server is running). Previously, this caused + interpolation command not to be inserted into `status-right` because `tmux + source-file` was falsely detected as another tmux server. +- add `#{continuum_status}` status line interpolation + +### v3.0.0, 2015-02-20 +- rename the plugin from `tmux-resurrect-auto` to `tmux-continuum` + +### v2.2.0, 2015-02-20 +- document tmux multi-server behavior in the readme +- do not auto-restore tmux environment if another tmux server is already running + (we don't want to duplicate stuff) +- bugfixes for 'tmux auto start' OS X Terminal.app and iTerm scripts +- prevent saving for the first 15 minutes only when plugin is sourced the first + time (not on subsequent sources or tmux.conf reloads) +- do not start auto-saving if there's another tmux server running (we don't want + for save files from various tmux environments to override each other) + +### v2.1.0, 2015-02-18 +- enable "tmux auto start" for OS X +- enable customizing "tmux auto start" for OS X +- fix errors when creating a launchd plist file for auto-start on OS X + +### v2.0.0, 2015-02-15 +- enable automatic environment restore when tmux is started + +### v1.0.0, 2015-02-12 +- first working version +- run the save script in the background +- do not start saving right after tmux is started +- add a check for tmux version to the initializer script +- when interval is set to '0' autosave is disabled +- bugfix: helper files not loaded +- update readme with the instructions how to disable auto saving diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/CONTRIBUTING.md b/filesystem/root/.tmux/plugins/tmux-continuum/CONTRIBUTING.md new file mode 100644 index 00000000..21c18fd0 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/CONTRIBUTING.md @@ -0,0 +1,15 @@ +### Contributing + +Code contributions are welcome! + +If you wanna contribute a bigger feature, please open a github issue so we can +discuss it together first. + +### 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 diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/LICENSE.md b/filesystem/root/.tmux/plugins/tmux-continuum/LICENSE.md new file mode 100644 index 00000000..e6e73501 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (C) Bruno Sutic + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/README.md b/filesystem/root/.tmux/plugins/tmux-continuum/README.md new file mode 100644 index 00000000..445fc131 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/README.md @@ -0,0 +1,101 @@ +# tmux-continuum + +Features: + +- continuous saving of tmux environment +- automatic tmux start when computer/server is turned on +- automatic restore when tmux is started + +Together these features enable uninterrupted tmux usage. No matter the computer +or server restarts, if the machine is on, tmux will be there how you left it off +the last time it was used. + +Tested and working on Linux, OSX and Cygwin. + +#### Continuous saving + +Tmux environment will be saved at the interval of 15 minutes. All the saving +happens in the background without the impact to your workflow. + +This action starts automatically when the plugin is installed. + +#### Automatic tmux start + +Tmux is automatically started after the computer/server is turned on. + +See the [instructions](docs/automatic_start.md) how to enable this for your +system. + +#### Automatic restore + +Last saved environment is automatically restored when tmux is started. + +Put `set -g @continuum-restore 'on'` in `tmux.conf` to enable this. + +Note: automatic restore happens **exclusively** on tmux server start. No other +action (e.g. sourcing `tmux.conf`) triggers this. + +#### Dependencies + +`tmux 1.9` or higher, `bash`, +[tmux-resurrect](https://github.com/tmux-plugins/tmux-resurrect) plugin. + +### Installation with [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm) (recommended) + +Please make sure you have +[tmux-resurrect](https://github.com/tmux-plugins/tmux-resurrect) installed. + +Add plugin to the list of TPM plugins in `.tmux.conf`: + + set -g @plugin 'tmux-plugins/tmux-resurrect' + set -g @plugin 'tmux-plugins/tmux-continuum' + +Hit `prefix + I` to fetch the plugin and source it. The plugin will +automatically start "working" in the background, no action required. + +### Manual Installation + +Please make sure you have +[tmux-resurrect](https://github.com/tmux-plugins/tmux-resurrect) installed. + +Clone the repo: + + $ git clone https://github.com/tmux-plugins/tmux-continuum ~/clone/path + +Add this line to the bottom of `.tmux.conf`: + + run-shell ~/clone/path/continuum.tmux + +Reload TMUX environment with: `$ tmux source-file ~/.tmux.conf` + +The plugin will automatically start "working" in the background, no action +required. + +### Docs + +- [frequently asked questions](docs/faq.md) +- [behavior when running multiple tmux servers](docs/multiple_tmux_servers.md) - + this doc is safe to skip, but you might want to read it if you're using tmux + with `-L` or `-S` flags +- [automatically start tmux after the computer is turned on](docs/automatic_start.md) +- [continuum status in tmux status line](docs/continuum_status.md) + +### 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 + +You might want to follow [@brunosutic](https://twitter.com/brunosutic) on +twitter if you want to hear about new tmux plugins or feature updates. + +### Reporting bugs and contributing + +Both contributing and bug reports are welcome. Please check out +[contributing guidelines](CONTRIBUTING.md). + +### License +[MIT](LICENSE.md) diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/continuum.tmux b/filesystem/root/.tmux/plugins/tmux-continuum/continuum.tmux new file mode 100755 index 00000000..e8d60e38 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/continuum.tmux @@ -0,0 +1,92 @@ +#!/usr/bin/env bash + +set -x + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/scripts/helpers.sh" +source "$CURRENT_DIR/scripts/variables.sh" +source "$CURRENT_DIR/scripts/shared.sh" + +save_command_interpolation="#($CURRENT_DIR/scripts/continuum_save.sh)" + +supported_tmux_version_ok() { + "$CURRENT_DIR/scripts/check_tmux_version.sh" "$SUPPORTED_VERSION" +} + +handle_tmux_automatic_start() { + "$CURRENT_DIR/scripts/handle_tmux_automatic_start.sh" +} + +another_tmux_server_running() { + if just_started_tmux_server; then + another_tmux_server_running_on_startup + else + # script loaded after tmux server start can have multiple clients attached + [ "$(number_tmux_processes_except_current_server)" -gt "$(number_current_server_client_processes)" ] + fi +} + +delay_saving_environment_on_first_plugin_load() { + if [ -z "$(get_tmux_option "$last_auto_save_option" "")" ]; then + # last save option not set, this is first time plugin load + set_last_save_timestamp + fi +} + +add_resurrect_save_interpolation() { + local status_right_value="$(get_tmux_option "status-right" "")" + # check interpolation not already added + if ! [[ "$status_right_value" == *"$save_command_interpolation"* ]]; then + local new_value="${save_command_interpolation}${status_right_value}" + set_tmux_option "status-right" "$new_value" + fi +} + +number_of_sessions() { + tmux list-sessions | + wc -l | + sed "s/ //g" +} + +# when tmux server is first started, number of sessions is 0 +just_started_tmux_server() { + [ "$(number_of_sessions)" -eq 0 ] +} + +start_auto_restore_in_background() { + "$CURRENT_DIR/scripts/continuum_restore.sh" & +} + +update_tmux_option() { + local option="$1" + local option_value="$(get_tmux_option "$option")" + # replace interpolation string with a script to execute + local new_option_value="${option_value/$status_interpolation_string/$status_script}" + set_tmux_option "$option" "$new_option_value" +} + +main() { + if supported_tmux_version_ok; then + handle_tmux_automatic_start + + # Advanced edge case handling: start auto-saving only if this is the + # only tmux server. We don't want saved files from more environments to + # overwrite each other. + if ! another_tmux_server_running; then + # give user a chance to restore previously saved session + delay_saving_environment_on_first_plugin_load + add_resurrect_save_interpolation + fi + + if just_started_tmux_server; then + start_auto_restore_in_background + fi + + # Put "#{continuum_status}" interpolation in status-right or + # status-left tmux option to get current tmux continuum status. + update_tmux_option "status-right" + update_tmux_option "status-left" + fi +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/docs/automatic_start.md b/filesystem/root/.tmux/plugins/tmux-continuum/docs/automatic_start.md new file mode 100644 index 00000000..be80e955 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/docs/automatic_start.md @@ -0,0 +1,35 @@ +# Automatic Tmux start + +Tmux is automatically started after the computer/server is turned on. + +### OS X + +To enable this feature: +- put `set -g @continuum-boot 'on'` in `tmux.conf` +- reload tmux config with this shell command: `$ tmux source-file ~/.tmux.conf` + +Next time the computer is started: +- `Terminal.app` window will open and resize to maximum size +- `tmux` command will be executed in the terminal window +- if "auto restore" feature is enabled, tmux will start restoring previous env + +Config options: +- `set -g @continuum-boot-options 'fullscreen'` - terminal window + will go fullscreen +- `set -g @continuum-boot-options 'iterm'` - start `iTerm` instead + of `Terminal.app` +- `set -g @continuum-boot-options 'iterm,fullscreen'` - start `iTerm` + in fullscreen + +### Linux + +Help with this would be greatly appreciated. Please get in touch. + +#### Systemd + +##### this will only start the tmux server, it will *not* start any terminal emulator + +To enable automatic start with systemd: +- Put `set -g @continuum-boot 'on'` in tmux.conf +- reload tmux config with this shell command: `$ tmux source-file ~/.tmux.conf` +- see [systemd](./systemd_details.md) for more details about how this is implemented diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/docs/continuum_status.md b/filesystem/root/.tmux/plugins/tmux-continuum/docs/continuum_status.md new file mode 100644 index 00000000..c154ae4c --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/docs/continuum_status.md @@ -0,0 +1,17 @@ +## Continuum status in tmux status line + +There is an option to display current status of tmux continuum in tmux status +line. This is done via `#{continuum_status}` interpolation and it works with +both `status-right` and `status-left` tmux native options. + +Example usage: + + set -g status-right 'Continuum status: #{continuum_status}' + +When running, `#{continuum_status}` will show continuum save interval: + + Continuum status: 15 + +or if continuous saving is disabled: + + Continuum status: off diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/docs/faq.md b/filesystem/root/.tmux/plugins/tmux-continuum/docs/faq.md new file mode 100644 index 00000000..91a6b9e8 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/docs/faq.md @@ -0,0 +1,57 @@ +### FAQ + +> Will a previous save be overwritten immediately after I start tmux? + +No, first automatic save starts 15 minutes after tmux is started. If automatic +restore is not enabled, that gives you enough time to manually restore from a +previous save. + +> I want to make a restore to a previous point in time, but it seems that save +is now overwritten? + +None of the previous saves are deleted (unless you explicitly do that). All save +files are kept in `~/.tmux/resurrect/` directory.
+Here are the steps to restore to a previous point in time: + +- make sure you start this with a "fresh" tmux instance +- `$ cd ~/.tmux/resurrect/` +- locate the save file you'd like to use for restore (file names have a timestamp) +- symlink the `last` file to the desired save file: `$ ln -sf last` +- do a restore with `tmux-resurrect` key: `prefix + Ctrl-r` + +You should now be restored to the time when `` save happened. + +> Will this plugin fill my hard disk? + +Most likely no. A regular save file is in the range of 5Kb. That said, it +would be good to clean out old save files from `~/.tmux/resurrect/` dir from +time to time. + +> How do I change the save interval to i.e. 1 hour? + +The interval is always measured in minutes. So setting the interval to `60` +(minutes) will do the trick. Put this in `.tmux.conf`: + + set -g @continuum-save-interval '60' + +and then source `tmux.conf` by executing this command in the shell +`$ tmux source-file ~/.tmux.conf`. + +> How do I stop automatic saving? + +Just set the save interval to `0`. Put this in `.tmux.conf` + + set -g @continuum-save-interval '0' + +and then source `tmux.conf` by executing this command in the shell +`$ tmux source-file ~/.tmux.conf`. + +> I had automatic restore turned on, how do I disable it now? + +Just remove `set -g @continuum-restore 'on'` from `tmux.conf`. + +To be absolutely sure automatic restore doesn't happen, create a +`tmux_no_auto_restore` file in your home directory (command: +`$ touch ~/tmux_no_auto_restore`). Automatic restore won't happen if this file +exists. + diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/docs/multiple_tmux_servers.md b/filesystem/root/.tmux/plugins/tmux-continuum/docs/multiple_tmux_servers.md new file mode 100644 index 00000000..98c2506b --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/docs/multiple_tmux_servers.md @@ -0,0 +1,20 @@ +### Behavior when running multiple tmux servers + +(This is safe to skip if you're always running a single tmux server.) + +If you're an advanced tmux user, you might be running multiple tmux servers at +the same time. Maybe you start the first tmux server with `$ tmux` and then +later another one with e.g. `$ tmux -S/tmp/foo`. + +You probably don't want to "auto restore" the same environment in the second +tmux that uses `/tmp/foo` socket. You also probably don't want two tmux +environments both having "auto save" feature on (think about overwrites). + +This plugin handles multi-server scenario by giving precedence to the tmux +server that was first started. + +In the above example, the server started with `$ tmux` will do "auto +restore" (if enabled) and will start "auto saving". +"Auto restore" or "auto saving" **will not** happen for the second server that +was started later with the `$ tmux -S/tmp/foo` command. The plugin will +detect the presence of another server (`$ tmux`) and give it precedence. diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/docs/systemd_details.md b/filesystem/root/.tmux/plugins/tmux-continuum/docs/systemd_details.md new file mode 100644 index 00000000..7b9ed457 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/docs/systemd_details.md @@ -0,0 +1,13 @@ +# Systemd automatic start for tmux + +The first time tmux starts when `@continuum-boot` is set to 'on' tmux-continuum will generate a user level systemd unit file which it will save to `${HOME}/.config/systemd/user/tmux.service` and enable it. From then on when that user logs in, either through a GUI session or on the console or via ssh, Systemd will start the tmux server. + +The command used to start the tmux server is determined via the `@continuum-systemd-start-cmd` option that can be set in .tmux.conf. (Remember to reload your configuration with `tmux source ~/.tmux.conf` afterwards. + +The default command to use is `new-session -d`. If you want more control over what sessions get started then you should set up your sessions in tmux.conf and set `@continuum-systemd-start-cmd = 'start-server'`. As this will be executed as part of systemd's ExecStart statement there will be no shell parsing. See [Systemd manual](http://www.freedesktop.org/software/systemd/man/systemd.service.html#Command%20lines) for more details. + +To control the tmux service you can use all the standard `systemctl` commands using the `--user` argument. eg to see if the tmux server has started: + + systemctl --user status tmux.service + + diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/check_tmux_version.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/check_tmux_version.sh new file mode 100755 index 00000000..f4a887a2 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/check_tmux_version.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +VERSION="$1" +UNSUPPORTED_MSG="$2" + +# 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")" +} + +exit_if_unsupported_version() { + local current_version="$1" + local supported_version="$2" + if [ "$current_version" -lt "$supported_version" ]; then + 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 diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/continuum_restore.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/continuum_restore.sh new file mode 100755 index 00000000..27afbc46 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/continuum_restore.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/helpers.sh" +source "$CURRENT_DIR/variables.sh" + +auto_restore_enabled() { + local auto_restore_value="$(get_tmux_option "$auto_restore_option" "$auto_restore_default")" + [ "$auto_restore_value" == "on" ] && [ ! -f "$auto_restore_halt_file" ] +} + +fetch_and_run_tmux_resurrect_restore_script() { + # give tmux some time to start and source all the plugins + sleep 1 + local resurrect_restore_script_path="$(get_tmux_option "$resurrect_restore_path_option" "")" + if [ -n "$resurrect_restore_script_path" ]; then + "$resurrect_restore_script_path" + fi +} + +main() { + # Advanced edge case handling: auto restore only if this is the only tmux + # server. If another tmux server exists, it is assumed auto-restore is not wanted. + if auto_restore_enabled && ! another_tmux_server_running_on_startup; then + fetch_and_run_tmux_resurrect_restore_script + fi +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/continuum_save.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/continuum_save.sh new file mode 100755 index 00000000..c85f68a6 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/continuum_save.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/helpers.sh" +source "$CURRENT_DIR/variables.sh" +source "$CURRENT_DIR/shared.sh" + +supported_tmux_version_ok() { + "$CURRENT_DIR/check_tmux_version.sh" "$SUPPORTED_VERSION" +} + +get_interval() { + get_tmux_option "$auto_save_interval_option" "$auto_save_interval_default" +} + +auto_save_not_disabled() { + [ "$(get_interval)" -gt 0 ] +} + +enough_time_since_last_run_passed() { + local last_saved_timestamp="$(get_tmux_option "$last_auto_save_option" "0")" + local interval_minutes="$(get_interval)" + local interval_seconds="$((interval_minutes * 60))" + local next_run="$((last_saved_timestamp + $interval_seconds))" + [ "$(current_timestamp)" -ge "$next_run" ] +} + +fetch_and_run_tmux_resurrect_save_script() { + local resurrect_save_script_path="$(get_tmux_option "$resurrect_save_path_option" "")" + if [ -n "$resurrect_save_script_path" ]; then + "$resurrect_save_script_path" "quiet" >/dev/null 2>&1 & + set_last_save_timestamp + fi +} + +main() { + if supported_tmux_version_ok && auto_save_not_disabled && enough_time_since_last_run_passed; then + fetch_and_run_tmux_resurrect_save_script + fi +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/continuum_status.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/continuum_status.sh new file mode 100755 index 00000000..280cf006 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/continuum_status.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/helpers.sh" +source "$CURRENT_DIR/variables.sh" + +print_status() { + local save_int="$(get_tmux_option "$auto_save_interval_option")" + local status="" + local style_wrap + if [ $save_int -gt 0 ]; then + style_wrap="$(get_tmux_option "$status_on_style_wrap_option" "")" + status="$save_int" + else + style_wrap="$(get_tmux_option "$status_off_style_wrap_option" "")" + status="off" + fi + + if [ -n "$style_wrap" ]; then + status="${style_wrap/$status_wrap_string/$status}" + fi + echo "$status" +} +print_status diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start.sh new file mode 100755 index 00000000..433798b1 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/helpers.sh" +source "$CURRENT_DIR/variables.sh" + +is_tmux_automatic_start_enabled() { + local auto_start_value="$(get_tmux_option "$auto_start_option" "$auto_start_default")" + [ "$auto_start_value" == "on" ] +} + +is_osx() { + [ $(uname) == "Darwin" ] +} + +is_systemd() { + [ $(ps -o comm= -p1) == 'systemd' ] +} + +main() { + if is_tmux_automatic_start_enabled; then + if is_osx; then + "$CURRENT_DIR/handle_tmux_automatic_start/osx_enable.sh" + elif is_systemd; then + "$CURRENT_DIR/handle_tmux_automatic_start/systemd_enable.sh" + fi + else + if is_osx; then + "$CURRENT_DIR/handle_tmux_automatic_start/osx_disable.sh" + elif is_systemd; then + "$CURRENT_DIR/handle_tmux_automatic_start/systemd_disable.sh" + fi + fi +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/README.md b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/README.md new file mode 120000 index 00000000..c0cc0779 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/README.md @@ -0,0 +1 @@ +docs/automatic_start.md \ No newline at end of file diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_disable.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_disable.sh new file mode 100755 index 00000000..19f9af11 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_disable.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/../variables.sh" + +main() { + rm "$osx_auto_start_file_path" > /dev/null 2>&1 +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_enable.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_enable.sh new file mode 100755 index 00000000..7e3e2746 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_enable.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/../helpers.sh" +source "$CURRENT_DIR/../variables.sh" + +template() { + local tmux_start_script="$1" + local is_fullscreen="$2" + + local fullscreen_tag="" + if [ "$is_fullscreen" == "true" ]; then + # newline and spacing so tag is aligned with other tags in template + fullscreen_tag=$'\n fullscreen' + fi + + local content + read -r -d '' content <<-EOF + + + + + Label + ${osx_auto_start_file_name} + ProgramArguments + + ${tmux_start_script}$fullscreen_tag + + RunAtLoad + + + + EOF + echo "$content" +} + +get_iterm_or_teminal_option_value() { + local options="$1" + if [[ "$options" =~ "iterm" ]]; then + echo "iterm" + else + # Terminal.app is the default console app + echo "terminal" + fi +} + +get_fullscreen_option_value() { + local options="$1" + if [[ "$options" =~ "fullscreen" ]]; then + echo "true" + else + echo "false" + fi +} + +main() { + local options="$(get_tmux_option "$auto_start_config_option" "$auto_start_config_default")" + local iterm_or_terminal_value="$(get_iterm_or_teminal_option_value "$options")" + local fullscreen_option_value="$(get_fullscreen_option_value "$options")" + local tmux_start_script_path="${CURRENT_DIR}/osx_${iterm_or_terminal_value}_start_tmux.sh" + + local launchd_plist_file_content="$(template "$tmux_start_script_path" "$fullscreen_option_value")" + echo "$launchd_plist_file_content" > "$osx_auto_start_file_path" +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_iterm_start_tmux.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_iterm_start_tmux.sh new file mode 100755 index 00000000..b79e4d7d --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_iterm_start_tmux.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +# for "true full screen" call the script with "fullscreen" as the first argument +TRUE_FULL_SCREEN="$1" + +start_iterm_and_run_tmux() { + osascript <<-EOF + tell application "iTerm" + activate + + # open iterm window + try + set _session to current session of current terminal + on error + set _term to (make new terminal) + tell _term + launch session "Tmux" + set _session to current session + end tell + end try + + # start tmux + tell _session + write text "tmux" + end tell + end tell + EOF +} + +resize_window_to_full_screen() { + osascript <<-EOF + tell application "iTerm" + set winID to id of window 1 + tell i term application "Finder" + set desktopSize to bounds of window of desktop + end tell + set bounds of window id winID to desktopSize + end tell + EOF +} + +resize_to_true_full_screen() { + osascript <<-EOF + tell application "iTerm" + # wait for iTerm to start + delay 1 + activate + # short wait for iTerm to gain focus + delay 0.1 + # Command + Enter for fullscreen + tell i term application "System Events" + key code 36 using {command down} + end tell + end tell + EOF +} + +main() { + start_iterm_and_run_tmux + if [ "$TRUE_FULL_SCREEN" == "fullscreen" ]; then + resize_to_true_full_screen + else + resize_window_to_full_screen + fi +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_terminal_start_tmux.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_terminal_start_tmux.sh new file mode 100755 index 00000000..5a493915 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/osx_terminal_start_tmux.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# for "true full screen" call the script with "fullscreen" as the first argument +TRUE_FULL_SCREEN="$1" + +start_terminal_and_run_tmux() { + osascript <<-EOF + tell application "Terminal" + if not (exists window 1) then reopen + activate + set winID to id of window 1 + do script "tmux" in window id winID + end tell + EOF +} + +resize_window_to_full_screen() { + osascript <<-EOF + tell application "Terminal" + set winID to id of window 1 + tell application "Finder" + set desktopSize to bounds of window of desktop + end tell + set bounds of window id winID to desktopSize + end tell + EOF +} + +resize_to_true_full_screen() { + osascript <<-EOF + tell application "Terminal" + # waiting for Terminal.app to start + delay 1 + activate + # short wait for Terminal to gain focus + delay 0.1 + tell application "System Events" + keystroke "f" using {control down, command down} + end tell + end tell + EOF +} + +main() { + start_terminal_and_run_tmux + if [ "$TRUE_FULL_SCREEN" == "fullscreen" ]; then + resize_to_true_full_screen + else + resize_window_to_full_screen + fi +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/systemd_disable.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/systemd_disable.sh new file mode 100755 index 00000000..115e1c98 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/systemd_disable.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/../variables.sh" + +main() { + systemctl --user disable ${systemd_service_name} +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/systemd_enable.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/systemd_enable.sh new file mode 100755 index 00000000..b68442b0 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/handle_tmux_automatic_start/systemd_enable.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( dirname ${BASH_SOURCE[0]} )" + +source "$CURRENT_DIR/../helpers.sh" +source "$CURRENT_DIR/../variables.sh" + +template() { + local tmux_start_script="$1" + shift + local options="$@" + local content="" + + read -r -d '' content <<-EOF + [Unit] + Description=tmux default session (detached) + Documentation=man:tmux(1) + + [Service] + Type=forking + Environment=DISPLAY=:0 + ExecStart=/usr/bin/tmux ${systemd_tmux_server_start_cmd} + + ExecStop=${HOME}/.tmux/plugins/tmux-resurrect/scripts/save.sh + ExecStop=/usr/bin/tmux kill-server + KillMode=none + + RestartSec=2 + + [Install] + WantedBy=default.target + EOF + + echo "$content" +} + +systemd_tmux_is_enabled() { + systemctl --user is_enabled $(basename "${systemd_unit_file_path}") >/dev/null 2>&1 +} + +enable_tmux_unit_on_boot() { + if ! systemd_tmux_is_enabled; then + systemctl --user enable ${systemd_service_name} + fi +} + +main() { + local options="$(get_tmux_option "$auto_start_config_option" "${auto_start_config_default}")" + local systemd_tmux_server_start_cmd="$(get_tmux_option "${systemd_tmux_server_start_cmd_option}" "${systemd_tmux_server_start_cmd_default}" )" + local tmux_start_script_path="${CURRENT_DIR}/linux_start_tmux.sh" + local systemd_unit_file=$(template "${tmux_start_script_path}" "${options}") + echo "$systemd_unit_file" > "${systemd_unit_file_path}" + enable_tmux_unit_on_boot +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/helpers.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/helpers.sh new file mode 100644 index 00000000..b64fb363 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/helpers.sh @@ -0,0 +1,48 @@ +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 +} + +set_tmux_option() { + local option="$1" + local value="$2" + tmux set-option -gq "$option" "$value" +} + +# multiple tmux server detection helpers + +current_tmux_server_pid() { + echo "$TMUX" | + cut -f2 -d"," +} + +all_tmux_processes() { + # ignores `tmux source-file .tmux.conf` command used to reload tmux.conf + ps -Ao "command pid" | + \grep "^tmux" | + \grep -v "^tmux source" +} + +number_tmux_processes_except_current_server() { + all_tmux_processes | + \grep -v " $(current_tmux_server_pid)$" | + wc -l | + sed "s/ //g" +} + +number_current_server_client_processes() { + tmux list-clients | + wc -l | + sed "s/ //g" +} + +another_tmux_server_running_on_startup() { + # there are 2 tmux processes (current tmux server + 1) on tmux startup + [ "$(number_tmux_processes_except_current_server)" -gt 1 ] +} diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/shared.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/shared.sh new file mode 100644 index 00000000..5ac8885e --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/shared.sh @@ -0,0 +1,7 @@ +current_timestamp() { + echo "$(date +%s)" +} + +set_last_save_timestamp() { + set_tmux_option "$last_auto_save_option" "$(current_timestamp)" +} diff --git a/filesystem/root/.tmux/plugins/tmux-continuum/scripts/variables.sh b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/variables.sh new file mode 100644 index 00000000..8d0a0579 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-continuum/scripts/variables.sh @@ -0,0 +1,40 @@ +SUPPORTED_VERSION="1.9" + +# these tmux options contain paths to tmux resurrect save and restore scripts +resurrect_save_path_option="@resurrect-save-script-path" +resurrect_restore_path_option="@resurrect-restore-script-path" + +auto_save_interval_option="@continuum-save-interval" +auto_save_interval_default="15" + +# time when the tmux environment was last saved (unix timestamp) +last_auto_save_option="@continuum-save-last-timestamp" + +auto_restore_option="@continuum-restore" +auto_restore_default="off" + +auto_restore_halt_file="${HOME}/tmux_no_auto_restore" + +# tmux auto start options +auto_start_option="@continuum-boot" +auto_start_default="off" + +# comma separated list of additional options for tmux auto start +auto_start_config_option="@continuum-boot-options" +auto_start_config_default="" + +osx_auto_start_file_name="Tmux.Start.plist" +osx_auto_start_file_path="${HOME}/Library/LaunchAgents/${osx_auto_start_file_name}" + +status_interpolation_string="\#{continuum_status}" +status_script="#($CURRENT_DIR/scripts/continuum_status.sh)" +# below options set style/color for #{continuum_status} interpolation +status_on_style_wrap_option="@continuum-status-on-wrap-style" # example value: "#[fg=green]#{value}#[fg=white]" +status_off_style_wrap_option="@continuum-status-off-wrap-style" # example value: "#[fg=yellow,bold]#{value}#[fg=white,nobold]" +status_wrap_string="\#{value}" + +systemd_service_name="tmux.service" +systemd_unit_file_path="$HOME/.config/systemd/user/${systemd_service_name}" + +systemd_tmux_server_start_cmd_option="@continuum-systemd-start-cmd" +systemd_tmux_server_start_cmd_default="new-session -d" diff --git a/filesystem/root/.tmux/plugins/tmux-cpu/CHANGELOG.md b/filesystem/root/.tmux/plugins/tmux-cpu/CHANGELOG.md new file mode 100644 index 00000000..1b042fa3 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-cpu/CHANGELOG.md @@ -0,0 +1,22 @@ +# Changelog + +### master + +### v1.0.0, 2014-08-31 +- update readme to reflect github organization change +- bring in linux support +- small refactoring +- rename plugin to tmux-battery +- add contributors to the readme + +### v0.0.2, 2014-06-03 +- switch to tab indentation +- do not automatically prepend battery status +- change format interpolation strings to more Tmux-idiomatic + `#{battery_percentage}` and `#{battery_icon}` +- refactoring for simplicity +- support interpolation in `status-left` option too +- README update + +### v0.0.1, 2014-06-03 +- tag version 0.0.1 diff --git a/filesystem/root/.tmux/plugins/tmux-cpu/LICENSE b/filesystem/root/.tmux/plugins/tmux-cpu/LICENSE new file mode 100644 index 00000000..7d4f87d8 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-cpu/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 ctjhoa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/filesystem/root/.tmux/plugins/tmux-cpu/README.md b/filesystem/root/.tmux/plugins/tmux-cpu/README.md new file mode 100644 index 00000000..5abf8843 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-cpu/README.md @@ -0,0 +1,85 @@ +# Tmux cpu status + +Enables displaying cpu percentage and status icon in Tmux status-right. + +CPU:
+`CPU: ❏ 8.7%` + +This is done by introducing 2 new format strings that can be added to +`status-right` option: +- `#{cpu_icon}` - will display a cpu status icon +- `#{cpu_percentage}` - will show cpu percentage + +### Usage + +Add `#{cpu_icon}` or `#{cpu_percentage}` format strings to existing +`status-right` Tmux option. Example: + + # in .tmux.conf + set -g status-right "CPU: #{cpu_icon} #{cpu_percentage} | %a %h-%d %H:%M " + +### Optional requirement (Linux, BSD, OSX) + +`iostat` or `sar` are the best way to get an accurate cpu percentage + +A fallback is included using `ps -aux` but could be inaccurate. + +### 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 @plugin 'tmux-plugins/tmux-cpu' + +Hit `prefix + I` to fetch the plugin and source it. + +If format strings are added to `status-right`, they should now be visible. + +### Manual Installation + +Clone the repo: + + $ git clone https://github.com/tmux-plugins/tmux-cpu ~/clone/path + +Add this line to the bottom of `.tmux.conf`: + + run-shell ~/clone/path/cpu.tmux + +Reload TMUX environment: + + # type this in terminal + $ tmux source-file ~/.tmux.conf + +If format strings are added to `status-right`, they should now be visible. + +### Changing icons + +By default, these icons are displayed: + + - cpu: "❏" + +You can change these defaults by adding the following to `.tmux.conf` (the +following lines are not in the code block so that emojis can be seen): + + - set-option -g @cpu_icon ":sunglasses:" + +Don't forget to reload TMUX environment (`$ tmux source-file ~/.tmux.conf`) +after you do this. + +### Limitations + +- CPU change most likely won't be instant.
+ It will take some time (15 - 60 seconds) for the value to change. + This depends on the `status-interval` TMUX option. + +### Other plugins + +You might also find these useful: + +- [battery](https://github.com/tmux-plugins/tmux-battery) - Plug and play battery percentage and icon indicator for Tmux. +- [online status](https://github.com/tmux-plugins/tmux-online-status) - online status + indicator in Tmux `status-right`. Useful when on flaky connection to see if + you're online. + +### License + +[MIT](LICENSE) diff --git a/filesystem/root/.tmux/plugins/tmux-cpu/cpu.tmux b/filesystem/root/.tmux/plugins/tmux-cpu/cpu.tmux new file mode 100755 index 00000000..ba45bcde --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-cpu/cpu.tmux @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/scripts/helpers.sh" + +cpu_percentage="#($CURRENT_DIR/scripts/cpu_percentage.sh)" +cpu_icon="#($CURRENT_DIR/scripts/cpu_icon.sh)" +cpu_percentage_interpolation="\#{cpu_percentage}" +cpu_icon_interpolation="\#{cpu_icon}" + +set_tmux_option() { + local option=$1 + local value=$2 + tmux set-option -gq "$option" "$value" +} + +do_interpolation() { + local string=$1 + local percentage_interpolated=${string/$cpu_percentage_interpolation/$cpu_percentage} + local all_interpolated=${percentage_interpolated/$cpu_icon_interpolation/$cpu_icon} + echo $all_interpolated +} + +update_tmux_option() { + local option=$1 + local option_value=$(get_tmux_option "$option") + local new_option_value=$(do_interpolation "$option_value") + set_tmux_option "$option" "$new_option_value" +} + +main() { + update_tmux_option "status-right" + update_tmux_option "status-left" +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-cpu/scripts/cpu_icon.sh b/filesystem/root/.tmux/plugins/tmux-cpu/scripts/cpu_icon.sh new file mode 100755 index 00000000..9b12735f --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-cpu/scripts/cpu_icon.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/helpers.sh" + +# script global variables +cpu_icon="" + +cpu_default="❏ " + +# icons are set as script global variables +get_icon_settings() { + cpu_icon=$(get_tmux_option "@cpu_icon" "$cpu_default") +} + +main() { + get_icon_settings + printf "$cpu_icon" +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-cpu/scripts/cpu_percentage.sh b/filesystem/root/.tmux/plugins/tmux-cpu/scripts/cpu_percentage.sh new file mode 100755 index 00000000..108f27ef --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-cpu/scripts/cpu_percentage.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/helpers.sh" + +print_cpu_percentage() { + if command_exists "iostat"; then + + if is_linux_iostat; then + iostat -c 1 2 | tail -n 2 | head -n 1 | awk '{usage=100-$NF} END {printf("%5.1f%%", usage)}' + elif is_osx; then + iostat -c 2 disk0 | tail -n 1 | awk '{usage=100-$6} END {printf("%5.1f%%", usage)}' + elif is_freebsd || is_openbsd; then + iostat -c 2 | tail -n 1 | awk '{usage=100-$NF} END {printf("%5.1f%%", usage)}' + else + echo "Unknown iostat version please create an issue" + fi + elif command_exists "sar"; then + sar -u 1 1 | tail -n 1 | awk '{usage=100-$NF} END {printf("%5.1f%%", usage)}' + else + if is_cygwin; then + usage="$(WMIC cpu get LoadPercentage | grep -Eo '^[0-9]+')" + printf "%5.1f%%" $usage + else + load=`ps -aux | awk '{print $3}' | tail -n+2 | awk '{s+=$1} END {print s}'` + cpus=$(cpus_number) + echo "$load $cpus" | awk '{printf "%5.2f%%", $1/$2}' + fi + fi +} + +main() { + print_cpu_percentage +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-cpu/scripts/helpers.sh b/filesystem/root/.tmux/plugins/tmux-cpu/scripts/helpers.sh new file mode 100644 index 00000000..032e802c --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-cpu/scripts/helpers.sh @@ -0,0 +1,48 @@ +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 +} + +is_osx() { + [ $(uname) == "Darwin" ] +} + +is_freebsd() { + [ $(uname) == "FreeBSD" ] +} + +is_openbsd() { + [ $(uname) == "OpenBSD" ] +} + +is_linux() { + [ $(uname) == "Linux" ] +} + +is_cygwin() { + command -v WMIC &> /dev/null +} + +is_linux_iostat() { + # Bug in early versions of linux iostat -V return error code + iostat -c &> /dev/null +} + +cpus_number() { + if is_linux; then + nproc + else + sysctl -n hw.ncpu + fi +} + +command_exists() { + local command="$1" + command -v "$command" &> /dev/null +} diff --git a/filesystem/root/.tmux/plugins/tmux-net-speed/LICENSE b/filesystem/root/.tmux/plugins/tmux-net-speed/LICENSE new file mode 100644 index 00000000..8c2266ff --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-net-speed/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Travis Goldie + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/filesystem/root/.tmux/plugins/tmux-net-speed/README.md b/filesystem/root/.tmux/plugins/tmux-net-speed/README.md new file mode 100644 index 00000000..b0f16d7e --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-net-speed/README.md @@ -0,0 +1,81 @@ +# tmux-net-speed +Tmux plugin to monitor upload and download speed of one or all interfaces. + +## Usage +Add one of the following format string to `status-right` tmux option. + +## Special Credit +This plugin is roughly based on the various plugins in [https://github.com/tmux-plugins]("tmux-plugins"). + +## Formats +Shows value in either MB/s, KB/s, or B/s. + +- `#{download_speed}` - Shows only download speed, +- `#{upload_speed}` - Shows only upload speed, +- `#{net_speed}` - Shows both the upload and download speeds. + **Example**: "D: 123 MB/s U: 25 MB/s" + +## Past Values +Since this is a difference, the old values are stored in files in `/tmp/`. The user must be able to +read and write to this directory. + +### Set Options + +Set the following options in your `.tmux.conf`. + +To change which interfaces to pull from, use a space-separated list. If not set, +grabs all the interfaces listed in "/sys/class/net/" + +``` +set -g @net_speed_interfaces "eth0 eth1" +``` + +To change the formatter sting passed to `printf`. + +``` +set -g @download_speed_format "%10s" +set -g @upload_speed_format "%10s" +set -g @net_speed_format "D:%10s U:%10s" +``` + +### 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 @plugin 'tmux-plugins/tmux-net-speed' + +Hit `prefix + I` to fetch the plugin and source it. + +If format strings are added to `status-right`, they should now be visible. + +### Manual Installation + +Clone the repo: + + $ git clone https://github.com/tmux-plugins/tmux-net-speed ~/clone/path + +Add this line to the bottom of `.tmux.conf`: + + run-shell ~/clone/path/net_speed.tmux + +Reload TMUX environment (type this in terminal) + + $ tmux source-file ~/.tmux.conf + +If format strings are added to `status-right`, they should now be visible. + + +### Storage of Past Values +This plugin stores the total output for all the interfaces in a file in `/tmp/`. Therefore, the current user must be able to write and read from that directory. + + +### TODO +- Add unit tests +- Add error handling +- Configure which interfaces to calculate +- Configure format string for `#{net_speed}` +- Handle other OSs (currently only supports Linux) + +### License + +[MIT](LICENSE) diff --git a/filesystem/root/.tmux/plugins/tmux-net-speed/init.sh b/filesystem/root/.tmux/plugins/tmux-net-speed/init.sh new file mode 100755 index 00000000..65235f0e --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-net-speed/init.sh @@ -0,0 +1,13 @@ +#!/bin/bash - + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$CURRENT_DIR/scripts/helpers.sh" + +# Initialize files +main() +{ + # TODO Add error checking + echo "0" > $DOWNLOAD_FILE + echo "0" > $UPLOAD_FILE +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-net-speed/net_speed.tmux b/filesystem/root/.tmux/plugins/tmux-net-speed/net_speed.tmux new file mode 100755 index 00000000..a81f908c --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-net-speed/net_speed.tmux @@ -0,0 +1,36 @@ +#!/bin/bash - + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$CURRENT_DIR/scripts/helpers.sh" + +download_speed="#($CURRENT_DIR/scripts/download_speed.sh)" +net_speed="#($CURRENT_DIR/scripts/net_speed.sh)" +upload_speed="#($CURRENT_DIR/scripts/upload_speed.sh)" + +download_interpolation="\#{download_speed}" +net_interpolation="\#{net_speed}" +upload_interpolation="\#{upload_speed}" + +do_interpolation() { + local input=$1 + local result="" + + result=${input/$download_interpolation/$download_speed} + result=${result/$net_interpolation/$net_speed} + result=${result/$upload_interpolation/$upload_speed} + + echo $result +} + +update_tmux_option() { + local option=$1 + local option_value=$(get_tmux_option "$option") + local new_option_value=$(do_interpolation "$option_value") + set_tmux_option "$option" "$new_option_value" +} + +main() { + update_tmux_option "status-right" + update_tmux_option "status-left" +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-net-speed/run-tests.sh b/filesystem/root/.tmux/plugins/tmux-net-speed/run-tests.sh new file mode 100755 index 00000000..70f0d41a --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-net-speed/run-tests.sh @@ -0,0 +1,6 @@ +#!/bin/bash - +CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +for testSuite in $CURRENT_DIR/tests/suites/* ; do + $testSuite +done diff --git a/filesystem/root/.tmux/plugins/tmux-net-speed/scripts/download_speed.sh b/filesystem/root/.tmux/plugins/tmux-net-speed/scripts/download_speed.sh new file mode 100755 index 00000000..66f5511d --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-net-speed/scripts/download_speed.sh @@ -0,0 +1,28 @@ +#!/bin/bash - + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$CURRENT_DIR/helpers.sh" + +sum_download_speed() +{ + # Output uses first column + sum_speed 1 +} + +main() +{ + # TODO make configurable + #local file=$(get_tmux_option $DOWNLOAD_FILE) + local file=$DOWNLOAD_FILE + local old_val=$(read_file $file) + local new_val=$(sum_download_speed) + + write_file $file $new_val + local vel=$(get_velocity $new_val $old_val) + + ## Format output + local format=$(get_tmux_option @download_speed_format "%s") + printf "$format" "$vel" +} +main + diff --git a/filesystem/root/.tmux/plugins/tmux-net-speed/scripts/helpers.sh b/filesystem/root/.tmux/plugins/tmux-net-speed/scripts/helpers.sh new file mode 100644 index 00000000..02dbb934 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-net-speed/scripts/helpers.sh @@ -0,0 +1,129 @@ +#!/bin/bash - + +## +# Varialbes +## +DOWNLOAD_FILE="/tmp/tmux_net_speed.download" +UPLOAD_FILE="/tmp/tmux_net_speed.upload" + +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 +} + +set_tmux_option() { + local option=$1 + local value=$2 + tmux set-option -gq "$option" "$value" +} + +get_velocity() +{ + local new_value=$1 + local old_value=$2 + + # Consts + local THOUSAND=1024 + local MILLION=1048576 + + local vel=$(( new_value - old_value )) + local vel_kb=$(( vel / THOUSAND )) + local vel_mb=$(( vel / MILLION )) + + if [[ $vel_mb != 0 ]] ; then + echo -n "$vel_mb MB/s" + elif [[ $vel_kb != 0 ]] ; then + echo -n "$vel_kb KB/s"; + else + echo -n "$vel B/s"; + fi +} + +# Reads from value from file. If file does not exist, +# is empty, or not readable, starts back at 0 +read_file() +{ + local path="$1" + local fallback_val=0 + + # File exists and is readdable? + if [[ ! -f "$path" ]] ; then + echo $fallback_val + return 1 + elif [[ ! -r "$path" ]]; then + echo $fallback_val + return 1 + fi + + + # Does the file have content? + tmp=$(< "$path") + if [[ "x${tmp}" == "x" ]] ; then + echo $fallback_val + return 1 + fi + + # Now return known value + echo $tmp +} + +# Update values in file +write_file() +{ + local path="$1" + local val="$2" + + # TODO Add error checking + echo "$val" > "$path" +} + +get_interfaces() +{ + local interfaces=$(get_tmux_option @net_speed_interfaces "") + + if [[ -z "$interfaces" ]] ; then + for interface in /sys/class/net/*; do + interfaces+=$(echo $(basename $interface) " "); + done + fi + + # Do not quote the variable. This way will handle trailing whitespace + echo -n $interfaces +} + +sum_speed() +{ + local column=$1 + + declare -a interfaces=$(get_interfaces) + + local line="" + local val=0 + for intf in ${interfaces[@]} ; do + line=$(cat /proc/net/dev | grep "$intf" | cut -d':' -f 2) + speed="$(echo -n $line | cut -d' ' -f $column)" + let val+=${speed:=0} + done + + echo $val +} + +is_osx() { + [ $(uname) == "Darwin" ] +} + +is_cygwin() { + command -v WMIC > /dev/null +} + +command_exists() { + local command="$1" + type "$command" >/dev/null 2>&1 +} diff --git a/filesystem/root/.tmux/plugins/tmux-net-speed/scripts/net_speed.sh b/filesystem/root/.tmux/plugins/tmux-net-speed/scripts/net_speed.sh new file mode 100755 index 00000000..53909252 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-net-speed/scripts/net_speed.sh @@ -0,0 +1,15 @@ +#!/bin/bash - + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$CURRENT_DIR/helpers.sh" + +main() +{ + local download=$("$CURRENT_DIR/download_speed.sh") + local upload=$("$CURRENT_DIR/upload_speed.sh") + + ## Format output + local format=$(get_tmux_option @net_speed_format "D:%10s U:%10s") + printf "$format" "$download" "$upload" +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-net-speed/scripts/upload_speed.sh b/filesystem/root/.tmux/plugins/tmux-net-speed/scripts/upload_speed.sh new file mode 100755 index 00000000..b66477bb --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-net-speed/scripts/upload_speed.sh @@ -0,0 +1,28 @@ +#!/bin/bash - + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$CURRENT_DIR/helpers.sh" + +sum_upload_speed() +{ + # Output uses ninth column + sum_speed 9 +} + +main() +{ + # TODO make configurable + #local upload_file=$(get_tmux_option $UPLOAD_FILE) + local file=$UPLOAD_FILE + local old_val=$(read_file $file) + local new_val=$(sum_upload_speed) + + write_file $file $new_val + local vel=$(get_velocity $new_val $old_val) + + ## Format output + local format=$(get_tmux_option @upload_speed_format "%s") + printf "$format" "$vel" +} +main + diff --git a/filesystem/root/.tmux/plugins/tmux-net-speed/tests/suites/helpers.test.sh b/filesystem/root/.tmux/plugins/tmux-net-speed/tests/suites/helpers.test.sh new file mode 100755 index 00000000..a68bbb19 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-net-speed/tests/suites/helpers.test.sh @@ -0,0 +1,132 @@ +#!/bin/bash - + +CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SCRIPTS="$CURRENT_DIR/../../scripts" +source "$CURRENT_DIR/../test_utils.sh" + +## +# Description: +# General setup before each test +## +setup() +{ + source "$SCRIPTS/helpers.sh" +} + +## +# get_tmux_option +## +setup_get_tmux_option() +{ + setup + + ## Set generic property + tmux set @get_tmux_option_name "get_tmux_option_val" +} + +cleanup_get_tmux_option() +{ + # Unset value + tmux set -u @get_tmux_option_name +} + +test_get_tmux_option() +{ + ## + # Should return set value + ## + setup_get_tmux_option + + result=$( get_tmux_option "@get_tmux_option_name") + assertEqual "$result" "get_tmux_option_val" "should get tmux prop when given no default" -v + + cleanup_get_tmux_option + + ## + # Should show set value + ## + setup_get_tmux_option + + result=$( get_tmux_option "@get_tmux_option_name_unset") + assertEqual "$result" "" "should get empty string when tmux prop unset" + + cleanup_get_tmux_option + + ## + # Should show set value + ## + setup_get_tmux_option + + result=$( get_tmux_option @get_tmux_option_name_unset my_default) + assertEqual "$result" "my_default" "should get default if provided for unset prop" + + cleanup_get_tmux_option +} + +## +# get_velocity +## +setup_get_velocity() +{ + setup +} + +cleanup_get_velocity() { :; } + +test_get_velocity() +{ + setup_get_velocity + let input=200 + result=$(get_velocity $input 0) + assertEqual "$result" "200 B/s" "should show B/s" + cleanup_get_velocity + + setup_get_velocity + let input=2*1024 + result=$(get_velocity $input 0) + assertEqual "$result" "2 KB/s" "should show KB/s" + cleanup_get_velocity + + setup_get_velocity + let input=3*1048576 + result=$(get_velocity $input 0) + assertEqual "$result" "3 MB/s" "should show MB/s" + cleanup_get_velocity + + + setup_get_velocity + let subtract_from=100*1048576 + let subtract_with=50*1048576 + result=$(get_velocity $subtract_from subtract_with) + assertEqual "$result" "50 MB/s" "should show MB/s if subraction done" + cleanup_get_velocity +} + +## +# get_interfaces +## +setup_get_interfaces() +{ + setup +} + +cleanup_get_interfaces() { :; } + +test_get_interfaces() +{ + setup_get_interfaces + result=$(get_interfaces) + assertEqual "$result" "eth0 lo wlan0" "should output space-delimited list of interfaces" -v + cleanup_get_interfaces +} + +suites() +{ + #test_get_tmux_option + #test_get_velocity + test_get_interfaces +} + +# Run tests +suites + diff --git a/filesystem/root/.tmux/plugins/tmux-net-speed/tests/test_utils.sh b/filesystem/root/.tmux/plugins/tmux-net-speed/tests/test_utils.sh new file mode 100644 index 00000000..045d3e58 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-net-speed/tests/test_utils.sh @@ -0,0 +1,91 @@ +#!/bin/bash - +############################################################################### +# Author: Travis Goldie +# Purpose: Util funcs for unit tests +############################################################################### +## +# Description: +# Asserts if `$1` equals `$2` +## +assertEqual() +{ + local input=$1 + local expected=$2 + local msg=$3 + + if [[ "$4" == "-v" ]] ; then + echo $@ + fi + + if [[ -z msg ]] ; then + msg="Failed test" + fi + + test "$1" == "$2" + err=$? + + if [[ $err == 0 ]] ; then + echo "[PASSED]: ${msg}" + echo + return $err + fi + + if [[ $err != 0 ]] ; then + echo "[FAILED]: ${msg}" + echo + return $err + fi +} + +## +# Description: +# Asserts if `$1` not equals `$2` +## +assertNotEqual() +{ + local input=$1 + local expected=$2 + local msg=$3 + + if [[ -z msg ]] ; then + msg="Failed test" + fi + + test "$1" != "$2" + err=$? + + if [[ $err == 0 ]] ; then + echo "[PASSED]: ${msg}" + echo + return $err + fi + + if [[ $err != 0 ]] ; then + echo "[FAILED]: ${msg}" + echo + return $err + fi +} + +## +# @description +# Checks to see if error code is non-zero. If so, echo message and exit +# with the given error code. +# +# ``` bash +# $ someCmd blah blah2 +# $ err=$? +# $ die $err "If err is non-zero this script will exit" +# ``` +## +die() +{ + local err=$1 + local msg=$2 + local name=$( basename $0 ) + + if [[ $err != 0 ]] ; then + echo "[ERROR]:${name}:code $err:${msg}" + exit $err + fi +} diff --git a/filesystem/root/.tmux/plugins/tmux-prefix-highlight/LICENSE b/filesystem/root/.tmux/plugins/tmux-prefix-highlight/LICENSE new file mode 100644 index 00000000..98da78e0 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-prefix-highlight/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Erick Pintor + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/filesystem/root/.tmux/plugins/tmux-prefix-highlight/README.md b/filesystem/root/.tmux/plugins/tmux-prefix-highlight/README.md new file mode 100644 index 00000000..5d037642 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-prefix-highlight/README.md @@ -0,0 +1,86 @@ +# Tmux prefix highlight + +Plugin that highlights when you press tmux prefix key. Inspired by +[this](http://stackoverflow.com/questions/12003726/give-a-hint-when-press-prefix-key-in-tmux) +thread on stackoverflow. + +Many thanks to [@obxhdx](https://github.com/obxhdx) for showing me this trick. + +Prefix off: +![prefix_off](screenshots/prefix_off.png) + +Prefix on: +![prefix_on](screenshots/prefix_on.png) + +### Usage + +Just add `#{prefix_highlight}` to your left/right status bar. + +```tmux.confi +set -g status-right '#{prefix_highlight} | %a %Y-%m-%d %H:%M' +``` + +The plugin can also be configured to show when copy mode is active; see the +**Configurations** section for details. + +### Installation with Tmux Plugin Manager (recommended) + +Add plugin to the list of TPM plugins: + +```tmux.conf +set -g @plugin 'tmux-plugins/tmux-prefix-highlight' +``` + +Press prefix + I to install it. + +### Manual Installation + +Clone the repo: + +```bash +$ git clone https://github.com/tmux-plugins/tmux-prefix-highlight.git ~/clone/path +``` + +Add this line to your .tmux.conf: + +```tmux.conf +run-shell ~/clone/path/prefix_highlight.tmux +``` + +Reload TMUX environment with: + +```bash +$ tmux source-file ~/.tmux.conf +``` + +### Configurations + +The colors used for the prefix highlight can be configured: + +```tmux.conf +set -g @prefix_highlight_fg 'white' # default is 'colour231' +set -g @prefix_highlight_bg 'blue' # default is 'colour04' +``` + +The plugin can also be configured to show when copy mode is active. If enabled, +the `#{prefix_highlight}` token will be replaced with the string `Copy` when +copy mode is enabled. The style for copy mode can be configured as a +comma-separated list of colors and attributes: + +```tmux.conf +set -g @prefix_highlight_show_copy_mode 'on' +set -g @prefix_highlight_copy_mode_attr 'fg=black,bg=yellow,bold' # default is 'fg=default,bg=yellow' +``` + +Additionally, the plugin can be configured to attach optional affixes to the +value contained in `#{prefix_highlight}`. +(e.g. `< ^B >`) + +```tmux.conf +set -g @prefix_highlight_output_prefix '< ' +set -g @prefix_highlight_output_suffix ' >' +``` + +### License + +[MIT](LICENSE) diff --git a/filesystem/root/.tmux/plugins/tmux-prefix-highlight/prefix_highlight.tmux b/filesystem/root/.tmux/plugins/tmux-prefix-highlight/prefix_highlight.tmux new file mode 100755 index 00000000..c7cd10b4 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-prefix-highlight/prefix_highlight.tmux @@ -0,0 +1,92 @@ +#!/usr/bin/env bash + +set -e + +# Place holder for status left/right +place_holder="\#{prefix_highlight}" + +# Possible configurations +fg_color_config='@prefix_highlight_fg' +bg_color_config='@prefix_highlight_bg' +output_prefix='@prefix_highlight_output_prefix' +output_suffix='@prefix_highlight_output_suffix' +show_copy_config='@prefix_highlight_show_copy_mode' +copy_attr_config='@prefix_highlight_copy_mode_attr' + +# Defaults +default_fg='colour231' +default_bg='colour04' +default_copy_attr='fg=default,bg=yellow' + +tmux_option() { + local -r value=$(tmux show-option -gqv "$1") + local -r default="$2" + + if [ ! -z "$value" ]; then + echo "$value" + else + echo "$default" + fi +} + +highlight() { + local -r \ + status="$1" \ + prefix="$2" \ + prefix_highlight="$3" \ + show_copy_mode="$4" \ + copy_highlight="$5" \ + output_prefix="$6" \ + output_suffix="$7" \ + copy="Copy" + + local -r status_value="$(tmux_option "$status")" + local -r prefix_with_optional_affixes="$output_prefix$prefix$output_suffix" + local -r copy_with_optional_affixes="$output_prefix$copy$output_suffix" + + if [[ "on" = "$show_copy_mode" ]]; then + local -r fallback="${copy_highlight}#{?pane_in_mode,$copy_with_optional_affixes,}" + else + local -r fallback="" + fi + + local -r highlight_on_prefix="${prefix_highlight}#{?client_prefix,$prefix_with_optional_affixes,$fallback}#[default]" + tmux set-option -gq "$status" "${status_value/$place_holder/$highlight_on_prefix}" +} + +main() { + local -r \ + prefix=$(tmux_option prefix) \ + fg_color=$(tmux_option "$fg_color_config" "$default_fg") \ + bg_color=$(tmux_option "$bg_color_config" "$default_bg") \ + show_copy_mode=$(tmux_option "$show_copy_config" "off") \ + output_prefix=$(tmux_option "$output_prefix" " ") \ + output_suffix=$(tmux_option "$output_suffix" " ") \ + copy_attr=$(tmux_option "$copy_attr_config" "$default_copy_attr") + + local -r short_prefix=$( + echo "$prefix" | tr "[:lower:]" "[:upper:]" | sed 's/C-/\^/' + ) + + local -r \ + prefix_highlight="#[fg=$fg_color,bg=$bg_color]" \ + copy_highlight="${copy_attr:+#[default,$copy_attr]}" + + highlight "status-right" \ + "$short_prefix" \ + "$prefix_highlight" \ + "$show_copy_mode" \ + "$copy_highlight" \ + "$output_prefix" \ + "$output_suffix" + + highlight "status-left" \ + "$short_prefix" \ + "$prefix_highlight" \ + "$show_copy_mode" \ + "$copy_highlight" \ + "$output_prefix" \ + "$output_suffix" +} + +main diff --git a/filesystem/root/.tmux/plugins/tmux-prefix-highlight/screenshots/prefix_off.png b/filesystem/root/.tmux/plugins/tmux-prefix-highlight/screenshots/prefix_off.png new file mode 100644 index 0000000000000000000000000000000000000000..ae7dfab117b93b4db3c3ce039893e826e9990b2f GIT binary patch literal 12039 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 literal 0 HcmV?d00001 diff --git a/filesystem/root/.tmux/plugins/tmux-prefix-highlight/screenshots/prefix_on.png b/filesystem/root/.tmux/plugins/tmux-prefix-highlight/screenshots/prefix_on.png new file mode 100644 index 0000000000000000000000000000000000000000..d81adfc779f4455daab86d708aba582e839260d4 GIT binary patch literal 12665 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 kwEM+;|BIK)4)H+@SrzS_3uAWvSKX7exPn-z>% literal 0 HcmV?d00001 diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/.travis.yml b/filesystem/root/.tmux/plugins/tmux-resurrect/.travis.yml new file mode 100644 index 00000000..7837e7b8 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/.travis.yml @@ -0,0 +1,14 @@ +# generic packages and latest Tmux 1.9a +before_install: + - sudo apt-get update + - sudo apt-get install -y git-core expect + - sudo apt-get install -y python-software-properties software-properties-common + - sudo add-apt-repository -y ppa:pi-rho/dev + - sudo apt-get update + - sudo apt-get install -y tmux=1.9a-1~ppa1~p + +install: + - git fetch --unshallow --recurse-submodules || git fetch --recurse-submodules + - lib/tmux-test/setup + +script: ./tests/run_tests_in_isolation diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/CHANGELOG.md b/filesystem/root/.tmux/plugins/tmux-resurrect/CHANGELOG.md new file mode 100644 index 00000000..bccbb7df --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/CHANGELOG.md @@ -0,0 +1,140 @@ +# Changelog + +### master +- save and restore tmux pane contents (@laomaiweng) +- update tmux-test to solve issue with recursing git submodules in that project +- set options quietly in `resurrect.tmux` script +- improve pane contents restoration: `cat ` is no longer shown in pane + content history +- refactoring: drop dependency on `paste` command +- bugfix for pane contents restoration +- expand tilde char `~` if used with `@resurrect-dir` +- do not save empty trailing lines when pane content is saved +- do not save pane contents if pane is empty (only for 'save pane contents' + feature) +- "save pane contents" feature saves files to a separate directory +- archive and compress pane contents file +- make archive & compress pane contents process more portable +- `mutt` added to the list of automatically restored programs +- added guide for migrating from tmuxinator + +### v2.4.0, 2015-02-23 +- add "tmux-test" +- add test for "resurrect save" feature +- add test for "resurrect restore" feature +- make the tests work and pass on travis +- add travis badge to the readme + +### v2.3.0, 2015-02-12 +- Improve fetching proper window_layout for zoomed windows. In order to fetch + proper value, window has to get unzoomed. This is now done faster so that + "unzoom,fetch value,zoom" cycle is almost unnoticable to the user. + +### v2.2.0, 2015-02-12 +- bugfix: zoomed windows related regression +- export save and restore script paths so that 'tmux-resurrect-save' plugin can + use them +- enable "quiet" saving (used by 'tmux-resurrect-save' plugin) + +### v2.1.0, 2015-02-12 +- if restore is started when there's only **1 pane in the whole tmux server**, + assume the users wants the "full restore" and overrwrite that pane. + +### v2.0.0, 2015-02-10 +- add link to the wiki page for "first pane/window issue" to the README as well + as other tweaks +- save and restore grouped sessions (used with multi-monitor workflow) +- save and restore active and alternate windows in grouped sessions +- if there are no grouped sessions, do not output empty line to "last" file +- restore active and alternate windows only if they are present in the "last" file +- refactoring: prefer using variable with tab character +- remove deprecated `M-s` and `M-r` key bindings (breaking change) + +### v1.5.0, 2014-11-09 +- add support for restoring neovim sessions + +### v1.4.0, 2014-10-25 +- plugin now uses strategies when fetching pane full command. Implemented + 'default' strategy. +- save command strategy: 'pgrep'. It's here only if fallback is needed. +- save command strategy: 'gdb' +- rename default strategy name to 'ps' +- create `expect` script that can fully restore tmux environment +- fix default save command strategy `ps` command flags. Flags are different for + FreeBSD. +- add bash history saving and restoring (@rburny) +- preserving layout of zoomed windows across restores (@Azrael3000) + +### 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. + +### 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 diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/CONTRIBUTING.md b/filesystem/root/.tmux/plugins/tmux-resurrect/CONTRIBUTING.md new file mode 100644 index 00000000..444098c1 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/CONTRIBUTING.md @@ -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 diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/LICENSE.md b/filesystem/root/.tmux/plugins/tmux-resurrect/LICENSE.md new file mode 100644 index 00000000..40f6dddd --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (C) 2014 Bruno Sutic + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/README.md b/filesystem/root/.tmux/plugins/tmux-resurrect/README.md new file mode 100644 index 00000000..b551ae58 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/README.md @@ -0,0 +1,135 @@ +# Tmux Resurrect + +[![Build Status](https://travis-ci.org/tmux-plugins/tmux-resurrect.png?branch=master)](https://travis-ci.org/tmux-plugins/tmux-resurrect) + +Restore `tmux` environment after 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 and neovim sessions](docs/restoring_vim_and_neovim_sessions.md)! + +Automatic restoring and continuous saving of tmux env is also possible with +[tmux-continuum](https://github.com/tmux-plugins/tmux-continuum) plugin. + +### Screencast + +[![screencast screenshot](/video/screencast_img.png)](https://vimeo.com/104763018) + +### Key bindings + +- `prefix + Ctrl-s` - save +- `prefix + Ctrl-r` - restore + +### 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 (even when zoomed) +- active and alternative session +- active and alternative window for each session +- windows with focus +- active pane for each window +- "grouped sessions" (useful feature when using tmux with multiple monitors) +- programs running within a pane! More details in the + [restoring programs doc](docs/restoring_programs.md). + +Optional: + +- [restoring vim and neovim sessions](docs/restoring_vim_and_neovim_sessions.md) +- [restoring pane contents](docs/restoring_pane_contents.md) +- [restoring bash history](docs/restoring_bash_history.md) (experimental) + +Requirements / dependencies: `tmux 1.9` or higher, `bash`. + +Tested and working on Linux, OSX and Cygwin. + +`tmux-resurrect` is idempotent! It will not try to restore panes or windows that +already exist.
+The single exception to this is when tmux is started with only 1 pane in order +to restore previous tmux env. Only in this case will this single pane be +overwritten. + +### 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 @plugin '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 with: `$ tmux source-file ~/.tmux.conf`. +You should now be able to use the plugin. + +### Docs + +- [Guide for migrating from tmuxinator](docs/migrating_from_tmuxinator.md) + +**Configuration** + +- [Changing the default key bindings](docs/custom_key_bindings.md). +- Only a conservative list of programs is restored by default:
+ `vi vim nvim emacs man less more tail top htop irssi mutt`.
+ [Restoring programs doc](docs/restoring_programs.md) explains how to restore + additional programs. +- [Change a directory](docs/save_dir.md) where `tmux-resurrect` saves tmux + environment. + +**Optional features** + +- [Restoring vim and neovim sessions](docs/restoring_vim_and_neovim_sessions.md) + is nice if you're a vim/neovim user. +- [Restoring pane contents](docs/restoring_pane_contents.md) feature. + +**Experimental features (also optional)** + +- [restoring bash history](docs/restoring_bash_history.md) + +### 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 +- [tmux-continuum](https://github.com/tmux-plugins/tmux-continuum) - automatic + restoring and continuous saving of tmux env + +You might want to follow [@brunosutic](https://twitter.com/brunosutic) on +twitter if you want to hear about new tmux plugins or feature updates. + +### 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/2036b5e03fb430bbcbc340689d63328abaa28876/bin/tmux-session). + +### License +[MIT](LICENSE.md) diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/docs/custom_key_bindings.md b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/custom_key_bindings.md new file mode 100644 index 00000000..99bfc2c6 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/custom_key_bindings.md @@ -0,0 +1,11 @@ +# Custom key bindings + +The default key bindings are: + +- `prefix + Ctrl-s` - save +- `prefix + Ctrl-r` - restore + +To change these, add to `.tmux.conf`: + + set -g @resurrect-save 'S' + set -g @resurrect-restore 'R' diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/docs/migrating_from_tmuxinator.md b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/migrating_from_tmuxinator.md new file mode 100644 index 00000000..f59f90f2 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/migrating_from_tmuxinator.md @@ -0,0 +1,72 @@ +# Migrating from `tmuxinator` + +### Why migrate to `tmux-resurrect`? + +Here are some reasons why you'd want to migrate from `tmuxinator` to +`tmux-resurrect`: + +- **Less dependencies**
+ `tmuxinator` depends on `ruby` which can be a hassle to set up if you're not a + rubyist.
+ `tmux-resurrect` depends just on `bash` which is virtually + omnipresent. + +- **Simplicity**
+ `tmuxinator` has an executable, CLI interface with half dozen commands and + command completion.
+ `tmux-resurrect` defines just 2 tmux key bindings. + +- **No configuration**
+ `tmuxinator` is all about config files (and their constant updating).
+ `tmux-resurrect` requires no configuration to work. + +- **Better change handling**
+ When you make a change to any aspect of tmux layout, you also have to + update related `tmuxinator` project file (and test to make sure change is + ok).
+ With `tmux-resurrect` there's nothing to do: your change will be + remembered on the next save. + +### How to migrate? + +1. Install `tmux-resurrect`. +2. Open \*all* existing `tmuxinator` projects.
+ Verify all projects are open by pressing `prefix + s` and checking they are + all on the list. +3. Perform a `tmux-resurrect` save. + +That's it! You can continue using just `tmux-resurrect` should you choose so. + +Note: it probably makes no sense to use both tools at the same time as they do +the same thing (creating tmux environment for you to work in). +Technically however, there should be no issues. + +### Usage differences + +`tmuxinator` focuses on managing individual tmux sessions (projects). +`tmux-resurrect` keeps track of the \*whole* tmux environment: all sessions are +saved and restored together. + +A couple tips if you decide to switch to `tmux-resurrect`: + +- Keep all tmux sessions (projects) running all the time.
+ If you want to work on an existing project, you should be able to just + \*switch* to an already open session using `prefix + s`.
+ This is different from `tmuxinator` where you'd usually run `mux new [project]` + in order to start working on something. + +- No need to kill sessions with `tmux kill-session` (unless you really don't + want to work on it ever).
+ It's the recurring theme by now: just keep all the sessions running all the + time. This is convenient and also cheap in terms of resources. + +- The only 2 situations when you need `tmux-resurrect`:
+ 1) Save tmux environment just before restarting/shutting down your + computer.
+ 2) Restore tmux env after you turn the computer on. + +### Other questions? + +Still have questions? Feel free to open an +[issue](ihttps://github.com/tmux-plugins/tmux-resurrect/issues). We'll try to +answer it and also update this doc. diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_bash_history.md b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_bash_history.md new file mode 100644 index 00000000..9cff1ae2 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_bash_history.md @@ -0,0 +1,12 @@ +# Restoring bash history (experimental) + +Enable feature with this option in `.tmux.conf`: + + set -g @resurrect-save-bash-history 'on' + +Bash `history` for individual panes will now be saved and restored. Due to +technical limitations, this only works for panes which have no program running +in foreground when saving. `tmux-resurrect` will send history write command to +each such pane. To prevent these commands from being added to history +themselves, add `HISTCONTROL=ignoreboth` to your `.bashrc` +(this is set by default in Ubuntu). diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_pane_contents.md b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_pane_contents.md new file mode 100644 index 00000000..2dff59a1 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_pane_contents.md @@ -0,0 +1,31 @@ +# Restoring pane contents + +This plugin enables saving and restoring tmux pane contents. + +This feature can be enabled by adding this line to `.tmux.conf`: + + set -g @resurrect-capture-pane-contents 'on' + +##### Known issue + +When using this feature, please check the value of `default-command` +tmux option. That can be done with `$ tmux show -g default-command`. + +The value should NOT contain `&&` or `||` operators. If it does, simplify the +option so those operators are removed. + +Example: + +- this will cause issues (notice the `&&` and `||` operators): + + set -g default-command "which reattach-to-user-namespace > /dev/null && reattach-to-user-namespace -l $SHELL || $SHELL -l" + +- this is ok: + + set -g default-command "reattach-to-user-namespace -l $SHELL" + +Related [bug](https://github.com/tmux-plugins/tmux-resurrect/issues/98). + +Alternatively, you can let +[tmux-sensible](https://github.com/tmux-plugins/tmux-sensible) +handle this option in a cross-platform way and you'll have no problems. diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_programs.md b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_programs.md new file mode 100644 index 00000000..d57b73d4 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_programs.md @@ -0,0 +1,100 @@ +# Restoring programs + +Only a conservative list of programs is restored by default:
+`vi vim nvim emacs man less more tail top htop irssi mutt`. + +This can be configured with `@resurrect-processes` option in `.tmux.conf`. It +contains space-separated list of additional programs to restore. + +- Example restoring additional programs: + + 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"' + +- 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: + + set -g @resurrect-processes 'false' + +- Restore **all** programs (be careful with this!): + + set -g @resurrect-processes ':all:' + +### Clarifications + +> I don't understand tilde `~`, what is it and why is it used when restoring + programs? + +Let's say you use `rails server` command often. You want `tmux-resurrect` to +save and restore it automatically. You might try adding `rails server` to the +list of programs that will be restored: + + set -g @resurrect-processes '"rails server"' # will NOT work + +Upon save, `rails server` command will actually be saved as this command: +`/Users/user/.rbenv/versions/2.0.0-p481/bin/ruby script/rails server` +(if you wanna see how is any command saved, check it yourself in +`~/.tmux/resurrect/last` file). + +When programs are restored, the `rails server` command will NOT be restored +because it does not **strictly** match the long +`/Users/user/.rbenv/versions/2.0.0-p481/bin/ruby script/rails server` string. + +The tilde `~` at the start of the string relaxes process name matching. + + set -g @resurrect-processes '"~rails server"' # OK + +The above option says: "restore full process if `rails server` string is found +ANYWHERE in the process name". + +If you check long process string, there is in fact a `rails server` string at +the end, so now the process will be successfully restored. + +> What is arrow `->` and why is is used? + +(Please read the above clarification about tilde `~`). + +Continuing with our `rails server` example, when the process is finally restored +correctly it might not look pretty as you'll see the whole +`/Users/user/.rbenv/versions/2.0.0-p481/bin/ruby script/rails server` string in +the command line. + +Naturally, you'd rather want to see just `rails server` (what you initially +typed), but that information is now unfortunately lost. + +To aid this, you can use arrow `->`: + + set -g @resurrect-processes '"~rails server->rails server"' # OK + +This option says: "when this process is restored use `rails server` as the +command name". + +Full (long) process name is now ignored and you'll see just `rails server` in +the command line when the program is restored. + +> Now I understand the tilde and the arrow, but things still don't work for me + +Here's the general workflow for figuring this out: + +- Set up your whole tmux environment manually.
+ In our example case, we'd type `rails server` in a pane where we want it to + run. +- Save tmux env (it will get saved to `~/.tmux/resurrect/last`). +- Open `~/.tmux/resurrect/last` file and try to find full process string for + your program.
+ Unfortunately this is a little vague but it should be easy. A smart + thing to do for our example is to search for string `rails` in the `last` + file. +- Now that you know the full and the desired process string use tilde `~` and + arrow `->` in `.tmux.conf` to make things work. diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_vim_and_neovim_sessions.md b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_vim_and_neovim_sessions.md new file mode 100644 index 00000000..f92587f5 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/restoring_vim_and_neovim_sessions.md @@ -0,0 +1,15 @@ +# Restoring vim and neovim sessions + +- save vim/neovim sessions. I recommend + [tpope/vim-obsession](https://github.com/tpope/vim-obsession) (as almost every + plugin, it works for both vim and neovim). +- in `.tmux.conf`: + + # for vim + set -g @resurrect-strategy-vim 'session' + # for neovim + set -g @resurrect-strategy-nvim 'session' + +`tmux-resurrect` will now restore vim and neovim sessions if `Session.vim` file +is present. + diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/docs/save_dir.md b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/save_dir.md new file mode 100644 index 00000000..dc79b4e0 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/docs/save_dir.md @@ -0,0 +1,6 @@ +# Resurrect save dir + +By default Tmux environment is saved to a file in `~/.tmux/resurrect` dir. +Change this with: + + set -g @resurrect-dir '/some/path' diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/.gitignore b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/.gitignore new file mode 100644 index 00000000..27281b52 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/.gitignore @@ -0,0 +1,2 @@ +.vagrant/ +lib/ diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/.travis.yml b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/.travis.yml new file mode 100644 index 00000000..b6d9fad8 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/.travis.yml @@ -0,0 +1,14 @@ +# generic packages and latest Tmux 1.9a +before_install: + - sudo apt-get update + - sudo apt-get install -y git-core expect + - sudo apt-get install -y python-software-properties software-properties-common + - sudo add-apt-repository -y ppa:pi-rho/dev + - sudo apt-get update + - sudo apt-get install -y tmux=1.9a-1~ppa1~p + +install: + - git clone https://github.com/tmux-plugins/tmux-test lib/tmux-test + - lib/tmux-test/setup + +script: ./tests/run_tests_in_isolation diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/CHANGELOG.md b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/CHANGELOG.md new file mode 100644 index 00000000..ec00bdbe --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/CHANGELOG.md @@ -0,0 +1,38 @@ +# Changelog + +### master +- move `setup` task to `.travis.yml` for travis tests +- "merge" travis.yml and travis_for_plugins.yml files (no need to keep em + separate) +- add more useful helper functions +- remove tmux-test repo as a submodule from self, this causes issues with + `$ git submodule update --recursive --init` command that some users use for + managing other plugins + +### v0.2.0, 2015-02-22 +- `setup` script gitignores `tests/helpers.sh` +- move `tests/helpers.sh` to `tests/helpers/helpers.sh` +- `setup` undo removes added lines from gitignore file + +### v0.1.0, 2015-02-22 +- changes so that 'tmux-test' can be included with tmux plugins +- do not gitignore submodules directory +- add installation and usage instructions +- copy `.travis.yml` to the project root when running `setup` script +- add a brief mention of travis CI to the readme +- add test helpers +- `setup` script symlinks helpers file to `tests/` directory +- `setup` script can undo most of its actions +- add a tmux scripting test +- `tmux-test` uses `tmux-test` to test itself +- update `tmux-test` submodule +- a different `travis.yml` for `tmux-test` and for plugins + +### v0.0.1, 2015-02-21 +- git init +- add vagrant provisioning scripts for ubuntu and debian +- add a ".travis.yml" file +- generic "run_tests" script +- "run_tests_in_isolation" script +- add "Vagrantfile" +- enable passing VM names as arguments to "run_tests" script diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/LICENSE.md b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/LICENSE.md new file mode 100644 index 00000000..e6e73501 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (C) Bruno Sutic + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/README.md b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/README.md new file mode 100644 index 00000000..27dccc90 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/README.md @@ -0,0 +1,134 @@ +# tmux-test + +[![Build Status](https://travis-ci.org/tmux-plugins/tmux-test.png?branch=master)](https://travis-ci.org/tmux-plugins/tmux-test) + +A small framework for isolated testing of tmux plugins. Isolation is achieved by +running the tests in `Vagrant`. Works on [travis](travis-ci.org) too. + +Extracted from [tmux plugin manager](https://github.com/tmux-plugins/tpm) and +[tmux-copycat](https://github.com/tmux-plugins/tmux-copycat). + +Dependencies: `Vagrant` (no required when running on travis). + +### Setup + +Let's say you made tmux plugin with the following file hierarchy: + +```text +/tmux-plugin +|-- plugin.tmux +`-- scripts + `-- plugin_script.sh +``` + +From your project root directory (tmux-plugin/) execute the following shell +command to fetch `tmux-test` and add it as a submodule: + + $ git submodule add https://github.com/tmux-plugins/tmux-test.git lib/tmux-test + +Run the `setup` script: + + $ lib/tmux-test/setup + +The project directory will now look like this (additions have comments): + +```text +/tmux-plugin +|-- plugin.tmux +|-- run_tests # symlink, gitignored +|-- .gitignore # 2 lines appended to gitignore +|-- .travis.yml # added +|-- lib/tmux-test/ # git submodule +|-- scripts +| `-- plugin_script.sh +`-- tests # dir to put the tests in + `-- run_tests_in_isolation.sh # symlink, gitignored + `-- helpers + `-- helpers.sh # symlinked bash helpers, gitignored +``` + +`tmux-test` is now set up. You are ok to commit the additions to the repo. + +### Writing and running tests + +A test is any executable with a name starting with `test_` in `tests/` +directory. + +Now that you installed `tmux-test` let's create an example test. + +- create a `tests/test_example.sh` file with the following content (it's a + `bash` script but it can be any executable): + + #/usr/bin/env bash + + CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + + # bash helpers provided by 'tmux-test' + source $CURRENT_DIR/helpers/helpers.sh + + # installs plugin from current repo in Vagrant (or on Travis) + install_tmux_plugin_under_test_helper + + # start tmux in background (plugin under test is sourced) + tmux new -d + + # get first session name + session_name="$(tmux list-sessions -F "#{session_name}")" + + # fail the test if first session name is not "0" + if [ "$session_name" == "0" ]; then + # fail_helper is also provided by 'tmux-test' + fail_helper "First session name is not '0' by default" + fi + + # sets the right script exit code ('tmux-test' helper) + exit_helper + +- make the test file executable with `$ chmod +x tests/test_example.sh` +- run the test by executing `./run_tests` from the project root directory +- the first invocation might take some time because Vagrant's ubuntu virtual + machine is downloading. You should see `Success, tests pass!` message when it's + done. + +Check out more example test scripts in this project's [tests/ directory](tests/). + +### Continuous integration + +The setup script (`lib/tmux-test/setup`) added a `.travis.yml` file to the +project root. To setup continuous integration, just add/enable the project on +[travis](travis-ci.org). + +### Notes + +- The `tests/` directory for tests and `lib/tmux-test/` for cloning `tmux-test` + into cannot be changed currently +- Don't run `tests/run_tests_in_isolation` script on your local development + environment. That's an internal test runner meant to be executed in an + isolated environment like `vagrant` or `travis`.
+ Use `./run_tests` script. +- You can use `KEEP_RUNNING=true ./run_tests` for faster test running cycle. + If this case `Vagrant` will keep running even after the tests are done. +- You can use `VAGRANT_CWD=lib/tmux-text/ vagrant ssh ubuntu` for ssh login to + `Vagrant`. + +### Running `tmux-test` framework tests + +`tmux-test` uses itself to test itself. To run framework tests: + +- clone this project `$ git clone git@github.com:tmux-plugins/tmux-test.git` +- `$ cd tmux-test` +- run `$ ./run_framework_tests` + +### Other goodies + +- [tmux-copycat](https://github.com/tmux-plugins/tmux-copycat) - a plugin for + regex searches in tmux and fast match selection +- [tmux-continuum](https://github.com/tmux-plugins/tmux-continuum) - automatic + restoring and continuous saving of tmux env + +You might want to follow [@brunosutic](https://twitter.com/brunosutic) on +twitter if you want to hear about new tmux plugins or feature updates. + +### License + +[MIT](LICENSE.md) diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/Vagrantfile b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/Vagrantfile new file mode 100644 index 00000000..04b3ebaf --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/Vagrantfile @@ -0,0 +1,17 @@ +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + + config.vm.synced_folder "../../", "/vagrant" + + config.vm.define :ubuntu do |ubuntu| + ubuntu.vm.box = "hashicorp/precise64" + ubuntu.vm.provision "shell", path: "vagrant_ubuntu_provisioning.sh" + end + + config.vm.define :centos do |centos| + centos.vm.box = "chef/centos-6.5" + centos.vm.provision "shell", path: "vagrant_centos_provisioning.sh" + end + +end diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/run_framework_tests b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/run_framework_tests new file mode 100755 index 00000000..ed7f6349 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/run_framework_tests @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +# This file is used to run "tmux-test" framework tests. + +# "setup" script is needed to run the tests, but it overrides some working dir +# files. To address that, "setup" is run before the tests and it's actions are +# undone after. + +main() { + git clone https://github.com/tmux-plugins/tmux-test lib/tmux-test + lib/tmux-test/setup + ./run_tests + local exit_value=$? + lib/tmux-test/setup "undo" + exit "$exit_value" +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/run_tests b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/run_tests new file mode 100755 index 00000000..f53af68b --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/run_tests @@ -0,0 +1,91 @@ +#!/usr/bin/env bash + +# This file is a symlink from 'tmux-test' plugin. +# You probably don't want to edit it. + +# Invoke this script when running a test suite. +# Example invocations: +# ./run_tests # runs tests on default VM ubuntu +# ./run_tests ubuntu # runs tests on ubuntu VM +# ./run_tests ubuntu centos # runs tests on ubuntu and cents VMs + +# For each virtual machine where tests run, this script performs the following: +# - starts VM +# - starts the test suite witin a VM +# - stops the VM after the test suite is done + +export BOXES="$*" + +# global variable for script exit value +export EXIT_VALUE=0 + +register_failing_tests() { + EXIT_VALUE=1 +} + +run_vagrant() { + local box="$1" + VAGRANT_CWD=lib/tmux-test/ vagrant up "$box" +} + +# Halt vagrant after tests are done running, unless KEEP_RUNNING environment +# variable is set to 'true'. +stop_vagrant() { + local box="$1" + if [ -z "$KEEP_RUNNING" ]; then + VAGRANT_CWD=lib/tmux-test/ vagrant halt "$box" + else + echo + echo "KEEP_RUNNING is set. Vagrant not halted." + fi +} + +run_tests() { + local box="$1" + local test_file="/vagrant/tests/run_tests_in_isolation" + echo "Running test suite on $box from: $test_file" + echo + VAGRANT_CWD=lib/tmux-test/ vagrant ssh "$box" -c "cd /vagrant; $test_file" +} + +exit_message() { + local exit_val="$1" + echo + if [ "$exit_val" == 0 ]; then + echo "Success, tests pass!" + else + echo "Tests failed!" 1>&2 + fi +} + +run_tests_on_vm() { + local vm="$1" + run_vagrant "$vm" + run_tests "$vm" + local tests_exit_value="$?" + stop_vagrant "$vm" + if [ "$tests_exit_value" -gt 0 ]; then + register_failing_tests + fi +} + +run_tests_on_virtual_machines() { + if [ -z "$BOXES" ]; then + # no script arguments, run on 'ubuntu' by default + run_tests_on_vm "ubuntu" + else + # run on VMs provided as script arguments + local box + for box in $BOXES; do + run_tests_on_vm "$box" + done + fi +} + +main() { + echo "$BOXES" + run_tests_on_virtual_machines + exit_message "$EXIT_VALUE" + exit "$EXIT_VALUE" +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/setup b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/setup new file mode 100755 index 00000000..575a8a36 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/setup @@ -0,0 +1,93 @@ +#!/usr/bin/env bash + +# invoke this script from your projects root directory + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# pass "undo" as a script arg to undo most of the setup actions +UNDO_SETUP="$1" +undo() { + [ "$UNDO_SETUP" == "undo" ] +} + +restore() { + local file="$1" + rm -f "$file" + git checkout -- "$file" 2>/dev/null +} + +gitignore() { + local file="$1" + grep -q "^${file}$" .gitignore 2>/dev/null || echo "$file" >> .gitignore +} + +remove_from_gitignore() { + local file="$1" + local escaped_filename="$(echo "$file" | sed "s,/,\\\/,g")" + sed -i"" "/^${escaped_filename}$/d" .gitignore +} + +add_files_to_gitignore() { + if ! undo; then + gitignore "run_tests" + gitignore "tests/run_tests_in_isolation" + gitignore "tests/helpers/helpers.sh" + else + remove_from_gitignore "run_tests" + remove_from_gitignore "tests/run_tests_in_isolation" + remove_from_gitignore "tests/helpers/helpers.sh" + fi +} + +symlink_user_test_runner() { + local file="run_tests" + if ! undo; then + ln -sf "lib/tmux-test/${file}" "$file" + else + restore "$file" + fi +} + +create_directory_for_tests() { + if ! undo; then + mkdir -p tests/helpers/ + fi +} + +symlink_internal_test_runner() { + local file="tests/run_tests_in_isolation" + if ! undo; then + ln -sf "../lib/tmux-test/${file}" "$file" + else + restore "$file" + fi +} + +symlink_test_helpers() { + local file="tests/helpers/helpers.sh" + if ! undo; then + ln -sf "../../lib/tmux-test/${file}" "$file" + else + restore "$file" + fi +} + +copy_travis_yml() { + local file=".travis.yml" + if ! undo; then + cp "lib/tmux-test/${file}" "$file" + else + restore "$file" + fi +} + +main() { + add_files_to_gitignore + symlink_user_test_runner + create_directory_for_tests + symlink_internal_test_runner + symlink_test_helpers + copy_travis_yml +} +main + diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/helpers/helpers.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/helpers/helpers.sh new file mode 100644 index 00000000..5d3af2aa --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/helpers/helpers.sh @@ -0,0 +1,60 @@ +# This file is a symlink from 'tmux-test' plugin. +# You probably don't want to edit it. + + +# Global variable that keeps the value of test status (success/fail). +# Suggested usage is via `fail_helper` and `exit_helper` functions. +TEST_STATUS="success" + +# PRIVATE FUNCTIONS + +_teardown() { + rm -f ~/.tmux.conf + rm -rf ~/.tmux/ + tmux kill-server >/dev/null 2>&1 +} + +_clone_the_plugin() { + local plugin_path="${HOME}/.tmux/plugins/tmux-plugin-under-test/" + rm -rf "$plugin_path" + git clone --recursive "${CURRENT_DIR}/../" "$plugin_path" >/dev/null 2>&1 +} + +_add_plugin_to_tmux_conf() { + set_tmux_conf_helper<<-HERE + run-shell '~/.tmux/plugins/tmux-plugin-under-test/*.tmux' + HERE +} + +# PUBLIC HELPER FUNCTIONS + +set_tmux_conf_helper() { + > ~/.tmux.conf # empty tmux.conf file + while read -r line; do + echo "$line" >> ~/.tmux.conf + done +} + +fail_helper() { + local message="$1" + echo "$message" >&2 + TEST_STATUS="fail" +} + +exit_helper() { + _teardown + if [ "$TEST_STATUS" == "fail" ]; then + echo "FAIL!" + echo + exit 1 + else + echo "SUCCESS" + echo + exit 0 + fi +} + +install_tmux_plugin_under_test_helper() { + _clone_the_plugin + _add_plugin_to_tmux_conf +} diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/run_tests_in_isolation b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/run_tests_in_isolation new file mode 100755 index 00000000..30306f0a --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/run_tests_in_isolation @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +# This file is a symlink from 'tmux-test' plugin. +# You probably don't want to edit it. + +# This script should be run within an isolated enviroment (Vagrant, travis). +# Depending on what the tests do, it might NOT be safe to run this script +# directly on the development machine. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +EXIT_VALUE=0 # running a test suite is successful by default + +test_files() { + ls -1 "$CURRENT_DIR" | # test files are in the current dir + \grep -i "^test" | # test file names start with "test" + xargs # file names in a single line +} + +set_exit_val_to_false() { + EXIT_VALUE=1 +} + +run_tests() { + local test_file + for test_file in $(test_files); do + echo "Running test: $test_file" + "${CURRENT_DIR}/${test_file}" + + # handling exit value + local test_exit_value="$?" + if [ "$test_exit_value" -ne 0 ]; then + set_exit_val_to_false + fi + done +} + +main() { + run_tests + exit "$EXIT_VALUE" +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/test_basic_script_execution.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/test_basic_script_execution.sh new file mode 100755 index 00000000..0fdcf091 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/test_basic_script_execution.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +exit 0 diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/test_default_session_name.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/test_default_session_name.sh new file mode 100755 index 00000000..c761b93c --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/test_default_session_name.sh @@ -0,0 +1,24 @@ +#/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# bash helpers provided by 'tmux-test' +source $CURRENT_DIR/helpers/helpers.sh + +# installs plugin from current repo in Vagrant (or on Travis) +install_tmux_plugin_under_test_helper + +# start tmux in background (plugin under test is sourced) +tmux new -d + +# get first session name +session_name="$(tmux list-sessions -F "#{session_name}")" + +# fail the test if first session name is not "0" +if ! [ "$session_name" == "0" ]; then + # fail_helper is also provided by 'tmux-test' + fail_helper "First session name is not '0' by default" +fi + +# sets the right script exit code ('tmux-test' helper) +exit_helper diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/test_tmux_scripting.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/test_tmux_scripting.sh new file mode 100755 index 00000000..3b4beced --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/tests/test_tmux_scripting.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source $CURRENT_DIR/helpers/helpers.sh + +number_of_windows() { + tmux list-windows | + wc -l | + sed "s/ //g" +} + +main() { + # start tmux in the background + tmux new -d + tmux new-window + + local number_of_windows="$(number_of_windows)" + if ! [ "$number_of_windows" -eq 2 ]; then + fail_helper "Incorrect number of windows. Expected 2, got $number_of_windows" + fi + exit_helper +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/vagrant_centos_provisioning.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/vagrant_centos_provisioning.sh new file mode 100644 index 00000000..c5b340be --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/vagrant_centos_provisioning.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +# tmux installation instructions from here +# https://gist.github.com/rschuman/6168833 + +sudo su - + +yum -y install gcc kernel-devel make ncurses-devel +yum -y install git-core expect vim ruby ruby-devel ruby-irb + +# download tmux and libevent +mkdir ~/downloads && cd ~/downloads +curl http://sourceforge.net/projects/levent/files/latest/download?source=files -L -o libevent2.tar.gz -w 'Last URL was: %{url_effective}' +curl http://sourceforge.net/projects/tmux/files/latest/download?source=files -L -o tmux.tar.gz -w 'Last URL was: %{url_effective}' + +# compile libevent +cd ~/downloads +tar zxvf libevent2.tar.gz +cd libevent-*-stable +./configure --prefix=/usr/local +make +make install + +# compile tmux +cd ~/downloads +tar zxvf tmux.tar.gz +cd tmux-* +LDFLAGS="-L/usr/local/lib -Wl,-rpath=/usr/local/lib" ./configure --prefix=/usr/local +make +make install diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/vagrant_ubuntu_provisioning.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/vagrant_ubuntu_provisioning.sh new file mode 100644 index 00000000..0a3c884e --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/lib/tmux-test/vagrant_ubuntu_provisioning.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +sudo apt-get update +sudo apt-get install -y git-core expect vim +sudo apt-get install -y python-software-properties software-properties-common + +# install latest Tmux 1.9a +sudo add-apt-repository -y ppa:pi-rho/dev +sudo apt-get update +sudo apt-get install -y tmux=1.9a-1~ppa1~p diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/resurrect.tmux b/filesystem/root/.tmux/plugins/tmux-resurrect/resurrect.tmux new file mode 100755 index 00000000..1a853140 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/resurrect.tmux @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/scripts/variables.sh" +source "$CURRENT_DIR/scripts/helpers.sh" + +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/save.sh" + done +} + +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/restore.sh" + done +} + +set_default_strategies() { + tmux set-option -gq "${restore_process_strategy_option}irb" "default_strategy" +} + +set_script_path_options() { + tmux set-option -gq "$save_path_option" "$CURRENT_DIR/scripts/save.sh" + tmux set-option -gq "$restore_path_option" "$CURRENT_DIR/scripts/restore.sh" +} + +main() { + set_save_bindings + set_restore_bindings + set_default_strategies + set_script_path_options +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/run_tests b/filesystem/root/.tmux/plugins/tmux-resurrect/run_tests new file mode 120000 index 00000000..68177804 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/run_tests @@ -0,0 +1 @@ +lib/tmux-test/run_tests \ No newline at end of file diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/save_command_strategies/gdb.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/save_command_strategies/gdb.sh new file mode 100755 index 00000000..2f0ab56d --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/save_command_strategies/gdb.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +PANE_PID="$1" + +exit_safely_if_empty_ppid() { + if [ -z "$PANE_PID" ]; then + exit 0 + fi +} + +full_command() { + gdb -batch --eval "attach $PANE_PID" --eval "call write_history(\"/tmp/bash_history-${PANE_PID}.txt\")" --eval 'detach' --eval 'q' >/dev/null 2>&1 + \tail -1 "/tmp/bash_history-${PANE_PID}.txt" +} + +main() { + exit_safely_if_empty_ppid + full_command +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/save_command_strategies/pgrep.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/save_command_strategies/pgrep.sh new file mode 100755 index 00000000..15d98b3e --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/save_command_strategies/pgrep.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +PANE_PID="$1" + +exit_safely_if_empty_ppid() { + if [ -z "$PANE_PID" ]; then + exit 0 + fi +} + +full_command() { + \pgrep -lf -P "$PANE_PID" | + cut -d' ' -f2- +} + +main() { + exit_safely_if_empty_ppid + full_command +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/save_command_strategies/ps.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/save_command_strategies/ps.sh new file mode 100755 index 00000000..47223c5a --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/save_command_strategies/ps.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +PANE_PID="$1" + +exit_safely_if_empty_ppid() { + if [ -z "$PANE_PID" ]; then + exit 0 + fi +} + +ps_command_flags() { + case $(uname -s) in + FreeBSD) echo "-ao" ;; + OpenBSD) echo "-ao" ;; + *) echo "-eo" ;; + esac +} + +full_command() { + ps "$(ps_command_flags)" "ppid command" | + sed "s/^ *//" | + grep "^${PANE_PID}" | + cut -d' ' -f2- +} + +main() { + exit_safely_if_empty_ppid + full_command +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/check_tmux_version.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/check_tmux_version.sh new file mode 100755 index 00000000..b0aedece --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/check_tmux_version.sh @@ -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 diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/helpers.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/helpers.sh new file mode 100644 index 00000000..6b7ea2e9 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/helpers.sh @@ -0,0 +1,130 @@ +default_resurrect_dir="$HOME/.tmux/resurrect" +resurrect_dir_option="@resurrect-dir" + +SUPPORTED_VERSION="1.9" + +d=$'\t' + +# helper functions +get_tmux_option() { + local option="$1" + local default_value="$2" + local option_value=$(tmux show-option -gqv "$option") + if [ -z "$option_value" ]; then + echo "$default_value" + else + echo "$option_value" + fi +} + +# Ensures a message is displayed for 5 seconds in tmux prompt. +# Does not override the 'display-time' tmux option. +display_message() { + local message="$1" + + # display_duration defaults to 5 seconds, if not passed as an argument + if [ "$#" -eq 2 ]; then + local display_duration="$2" + else + local display_duration="5000" + fi + + # saves user-set 'display-time' option + local saved_display_time=$(get_tmux_option "display-time" "750") + + # sets message display time to 5 seconds + tmux set-option -gq display-time "$display_duration" + + # displays message + tmux display-message "$message" + + # restores original 'display-time' value + tmux set-option -gq display-time "$saved_display_time" +} + + +supported_tmux_version_ok() { + $CURRENT_DIR/check_tmux_version.sh "$SUPPORTED_VERSION" +} + +remove_first_char() { + echo "$1" | cut -c2- +} + +capture_pane_contents_option_on() { + local option="$(get_tmux_option "$pane_contents_option" "off")" + [ "$option" == "on" ] +} + +save_bash_history_option_on() { + local option="$(get_tmux_option "$bash_history_option" "off")" + [ "$option" == "on" ] +} + +get_grouped_sessions() { + local grouped_sessions_dump="$1" + export GROUPED_SESSIONS="${d}$(echo "$grouped_sessions_dump" | cut -f2 -d"$d" | tr "\\n" "$d")" +} + +is_session_grouped() { + local session_name="$1" + [[ "$GROUPED_SESSIONS" == *"${d}${session_name}${d}"* ]] +} + +# pane content file helpers + +pane_contents_create_archive() { + tar cf - -C "$(resurrect_dir)" ./pane_contents/ | + gzip > "$(pane_contents_archive_file)" +} + +pane_content_files_restore_from_archive() { + local archive_file="$(pane_contents_archive_file)" + if [ -f "$archive_file" ]; then + gzip -d < "$archive_file" | + tar xf - -C "$(resurrect_dir)" + fi +} + +pane_content_files_cleanup() { + rm "$(pane_contents_dir)"/* +} + +# path helpers + +resurrect_dir() { + local path="$(get_tmux_option "$resurrect_dir_option" "$default_resurrect_dir")" + echo "${path/#\~/$HOME}" # expands tilde if used with @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" +} + +pane_contents_dir() { + echo "$(resurrect_dir)/pane_contents/" +} + +pane_contents_file() { + local pane_id="$1" + echo "$(pane_contents_dir)/pane-${pane_id}" +} + +pane_contents_file_exists() { + local pane_id="$1" + [ -f "$(pane_contents_file "$pane_id")" ] +} + +pane_contents_archive_file() { + echo "$(resurrect_dir)/pane_contents.tar.gz" +} + +resurrect_history_file() { + local pane_id="$1" + echo "$(resurrect_dir)/bash_history-${pane_id}" +} diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/process_restore_helpers.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/process_restore_helpers.sh new file mode 100644 index 00000000..98dda6c1 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/process_restore_helpers.sh @@ -0,0 +1,170 @@ +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 + # check for additional "expansion" of inline strategy, e.g. `vim` to `vim -S` + if _strategy_exists "$inline_strategy"; then + local strategy_file="$(_get_strategy_file "$inline_strategy")" + local inline_strategy="$($strategy_file "$pane_full_command" "$dir")" + fi + 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 ! pane_exists "$session_name" "$window_number" "$pane_index"; then + # pane number limit exceeded, pane does not exist + return 1 + elif _restore_all_processes; then + return 0 + elif _process_on_the_restore_list "$pane_full_command"; then + return 0 + else + return 1 + fi +} + +_restore_all_processes() { + local restore_processes="$(get_tmux_option "$restore_processes_option" "$restore_processes")" + if [ "$restore_processes" == ":all:" ]; then + return 0 + else + return 1 + fi +} + +_process_on_the_restore_list() { + local pane_full_command="$1" + # TODO: make this work without eval + eval set $(_restore_list) + local proc + local match + for proc in "$@"; do + match="$(_get_proc_match_element "$proc")" + if _proc_matches_full_command "$pane_full_command" "$match"; then + return 0 + fi + done + return 1 +} + +_proc_matches_full_command() { + local pane_full_command="$1" + local match="$2" + if _proc_starts_with_tildae "$match"; then + match="$(remove_first_char "$match")" + # regex matching the command makes sure `$match` string is somewhere in the command string + if [[ "$pane_full_command" =~ ($match) ]]; then + return 0 + fi + else + # regex matching the command makes sure process is a "word" + if [[ "$pane_full_command" =~ (^${match} ) ]] || [[ "$pane_full_command" =~ (^${match}$) ]]; then + return 0 + fi + fi + return 1 +} + +_get_proc_match_element() { + echo "$1" | sed "s/${inline_strategy_token}.*//" +} + +_get_proc_restore_element() { + echo "$1" | sed "s/.*${inline_strategy_token}//" +} + +_restore_list() { + local user_processes="$(get_tmux_option "$restore_processes_option" "$restore_processes")" + local default_processes="$(get_tmux_option "$default_proc_list_option" "$default_proc_list")" + if [ -z "$user_processes" ]; then + # user didn't define any processes + echo "$default_processes" + else + echo "$default_processes $user_processes" + fi +} + +_proc_starts_with_tildae() { + [[ "$1" =~ (^~) ]] +} + +_get_inline_strategy() { + local pane_full_command="$1" + # TODO: make this work without eval + eval set $(_restore_list) + local proc + local match + for proc in "$@"; do + if [[ "$proc" =~ "$inline_strategy_token" ]]; then + match="$(_get_proc_match_element "$proc")" + if _proc_matches_full_command "$pane_full_command" "$match"; then + echo "$(_get_proc_restore_element "$proc")" + fi + fi + done +} + +_strategy_exists() { + local pane_full_command="$1" + local strategy="$(_get_command_strategy "$pane_full_command")" + if [ -n "$strategy" ]; then # strategy set? + local strategy_file="$(_get_strategy_file "$pane_full_command")" + [ -e "$strategy_file" ] # strategy file exists? + else + return 1 + fi +} + +_get_command_strategy() { + local pane_full_command="$1" + local command="$(_just_command "$pane_full_command")" + get_tmux_option "${restore_process_strategy_option}${command}" "" +} + +_just_command() { + echo "$1" | cut -d' ' -f1 +} + +_get_strategy_file() { + local pane_full_command="$1" + local strategy="$(_get_command_strategy "$pane_full_command")" + local command="$(_just_command "$pane_full_command")" + echo "$CURRENT_DIR/../strategies/${command}_${strategy}.sh" +} diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/restore.exp b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/restore.exp new file mode 100755 index 00000000..8664b1df --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/restore.exp @@ -0,0 +1,14 @@ +#!/usr/bin/env expect + +# start tmux +spawn tmux -S/tmp/foo + +# delay with sleep to compensate for tmux starting time +sleep 2 + +# run restore script directly +send "~/.tmux/plugins/tmux-resurrect/scripts/restore.sh\r" + +# long wait until tmux restore is complete +# (things get messed up if expect client isn't attached) +sleep 100 diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/restore.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/restore.sh new file mode 100755 index 00000000..50d4cbb5 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/restore.sh @@ -0,0 +1,359 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/variables.sh" +source "$CURRENT_DIR/helpers.sh" +source "$CURRENT_DIR/process_restore_helpers.sh" +source "$CURRENT_DIR/spinner_helpers.sh" + +# delimiter +d=$'\t' + +# Global variable. +# Used during the restore: if a pane already exists from before, it is +# saved in the array in this variable. Later, process running in existing pane +# is also not restored. That makes the restoration process more idempotent. +EXISTING_PANES_VAR="" + +RESTORING_FROM_SCRATCH="false" + +RESTORE_PANE_CONTENTS="false" + +is_line_type() { + local line_type="$1" + local line="$2" + echo "$line" | + \grep -q "^$line_type" +} + +check_saved_session_exists() { + local resurrect_file="$(last_resurrect_file)" + if [ ! -f $resurrect_file ]; then + display_message "Tmux resurrect file not found!" + return 1 + fi +} + +pane_exists() { + local session_name="$1" + local window_number="$2" + local pane_index="$3" + tmux list-panes -t "${session_name}:${window_number}" -F "#{pane_index}" 2>/dev/null | + \grep -q "^$pane_index$" +} + +register_existing_pane() { + local session_name="$1" + local window_number="$2" + local pane_index="$3" + local pane_custom_id="${session_name}:${window_number}:${pane_index}" + local delimiter=$'\t' + EXISTING_PANES_VAR="${EXISTING_PANES_VAR}${delimiter}${pane_custom_id}" +} + +is_pane_registered_as_existing() { + local session_name="$1" + local window_number="$2" + local pane_index="$3" + local pane_custom_id="${session_name}:${window_number}:${pane_index}" + [[ "$EXISTING_PANES_VAR" =~ "$pane_custom_id" ]] +} + +restore_from_scratch_true() { + RESTORING_FROM_SCRATCH="true" +} + +is_restoring_from_scratch() { + [ "$RESTORING_FROM_SCRATCH" == "true" ] +} + +restore_pane_contents_true() { + RESTORE_PANE_CONTENTS="true" +} + +is_restoring_pane_contents() { + [ "$RESTORE_PANE_CONTENTS" == "true" ] +} + +window_exists() { + local session_name="$1" + local window_number="$2" + tmux list-windows -t "$session_name" -F "#{window_index}" 2>/dev/null | + \grep -q "^$window_number$" +} + +session_exists() { + local session_name="$1" + tmux has-session -t "$session_name" 2>/dev/null +} + +first_window_num() { + tmux show -gv base-index +} + +tmux_socket() { + echo $TMUX | cut -d',' -f1 +} + +# Tmux option stored in a global variable so that we don't have to "ask" +# tmux server each time. +cache_tmux_default_command() { + local default_shell="$(get_tmux_option "default-shell" "")" + export TMUX_DEFAULT_COMMAND="$(get_tmux_option "default-command" "$default_shell")" +} + +tmux_default_command() { + echo "$TMUX_DEFAULT_COMMAND" +} + +pane_creation_command() { + echo "cat '$(pane_contents_file "${1}:${2}.${3}")'; exec $(tmux_default_command)" +} + +new_window() { + local session_name="$1" + local window_number="$2" + local window_name="$3" + local dir="$4" + local pane_index="$5" + local pane_id="${session_name}:${window_number}.${pane_index}" + if is_restoring_pane_contents && pane_contents_file_exists "$pane_id"; then + local pane_creation_command="$(pane_creation_command "$session_name" "$window_number" "$pane_index")" + tmux new-window -d -t "${session_name}:${window_number}" -n "$window_name" -c "$dir" "$pane_creation_command" + else + tmux new-window -d -t "${session_name}:${window_number}" -n "$window_name" -c "$dir" + fi +} + +new_session() { + local session_name="$1" + local window_number="$2" + local window_name="$3" + local dir="$4" + local pane_index="$5" + local pane_id="${session_name}:${window_number}.${pane_index}" + if is_restoring_pane_contents && pane_contents_file_exists "$pane_id"; then + local pane_creation_command="$(pane_creation_command "$session_name" "$window_number" "$pane_index")" + TMUX="" tmux -S "$(tmux_socket)" new-session -d -s "$session_name" -n "$window_name" -c "$dir" "$pane_creation_command" + else + TMUX="" tmux -S "$(tmux_socket)" new-session -d -s "$session_name" -n "$window_name" -c "$dir" + fi + # change first window number if necessary + local created_window_num="$(first_window_num)" + if [ $created_window_num -ne $window_number ]; then + tmux move-window -s "${session_name}:${created_window_num}" -t "${session_name}:${window_number}" + fi +} + +new_pane() { + local session_name="$1" + local window_number="$2" + local window_name="$3" + local dir="$4" + local pane_index="$5" + local pane_id="${session_name}:${window_number}.${pane_index}" + if is_restoring_pane_contents && pane_contents_file_exists "$pane_id"; then + local pane_creation_command="$(pane_creation_command "$session_name" "$window_number" "$pane_index")" + tmux split-window -t "${session_name}:${window_number}" -c "$dir" "$pane_creation_command" + else + tmux split-window -t "${session_name}:${window_number}" -c "$dir" + fi + # minimize window so more panes can fit + tmux resize-pane -t "${session_name}:${window_number}" -U "999" +} + +restore_pane() { + local pane="$1" + while IFS=$d read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_full_command; do + dir="$(remove_first_char "$dir")" + window_name="$(remove_first_char "$window_name")" + pane_full_command="$(remove_first_char "$pane_full_command")" + if pane_exists "$session_name" "$window_number" "$pane_index"; then + if is_restoring_from_scratch; then + # overwrite the pane + # happens only for the first pane if it's the only registered pane for the whole tmux server + local pane_id="$(tmux display-message -p -F "#{pane_id}" -t "$session_name:$window_number")" + new_pane "$session_name" "$window_number" "$window_name" "$dir" "$pane_index" + tmux kill-pane -t "$pane_id" + else + # Pane exists, no need to create it! + # Pane existence is registered. Later, its process also won't be restored. + register_existing_pane "$session_name" "$window_number" "$pane_index" + fi + elif window_exists "$session_name" "$window_number"; then + new_pane "$session_name" "$window_number" "$window_name" "$dir" "$pane_index" + elif session_exists "$session_name"; then + new_window "$session_name" "$window_number" "$window_name" "$dir" "$pane_index" + else + new_session "$session_name" "$window_number" "$window_name" "$dir" "$pane_index" + fi + done < <(echo "$pane") +} + +restore_state() { + local state="$1" + echo "$state" | + while IFS=$d read line_type client_session client_last_session; do + tmux switch-client -t "$client_last_session" + tmux switch-client -t "$client_session" + done +} + +restore_grouped_session() { + local grouped_session="$1" + echo "$grouped_session" | + while IFS=$d read line_type grouped_session original_session alternate_window active_window; do + TMUX="" tmux -S "$(tmux_socket)" new-session -d -s "$grouped_session" -t "$original_session" + done +} + +restore_active_and_alternate_windows_for_grouped_sessions() { + local grouped_session="$1" + echo "$grouped_session" | + while IFS=$d read line_type grouped_session original_session alternate_window_index active_window_index; do + alternate_window_index="$(remove_first_char "$alternate_window_index")" + active_window_index="$(remove_first_char "$active_window_index")" + if [ -n "$alternate_window_index" ]; then + tmux switch-client -t "${grouped_session}:${alternate_window_index}" + fi + if [ -n "$active_window_index" ]; then + tmux switch-client -t "${grouped_session}:${active_window_index}" + fi + done +} + +never_ever_overwrite() { + local overwrite_option_value="$(get_tmux_option "$overwrite_option" "")" + [ -n "$overwrite_option_value" ] +} + +detect_if_restoring_from_scratch() { + if never_ever_overwrite; then + return + fi + local total_number_of_panes="$(tmux list-panes -a | wc -l | sed 's/ //g')" + if [ "$total_number_of_panes" -eq 1 ]; then + restore_from_scratch_true + fi +} + +detect_if_restoring_pane_contents() { + if capture_pane_contents_option_on; then + cache_tmux_default_command + restore_pane_contents_true + fi +} + +# functions called from main (ordered) + +restore_all_panes() { + detect_if_restoring_from_scratch # sets a global variable + detect_if_restoring_pane_contents # sets a global variable + if is_restoring_pane_contents; then + pane_content_files_restore_from_archive + fi + while read line; do + if is_line_type "pane" "$line"; then + restore_pane "$line" + fi + done < $(last_resurrect_file) + if is_restoring_pane_contents; then + pane_content_files_cleanup + fi +} + +restore_pane_layout_for_each_window() { + \grep '^window' $(last_resurrect_file) | + while IFS=$d read line_type session_name window_number window_active window_flags window_layout; do + tmux select-layout -t "${session_name}:${window_number}" "$window_layout" + done +} + +restore_shell_history() { + awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ { print $2, $3, $7, $10; }' $(last_resurrect_file) | + while IFS=$d read session_name window_number pane_index pane_command; do + if ! is_pane_registered_as_existing "$session_name" "$window_number" "$pane_index"; then + if [ "$pane_command" == "bash" ]; then + local pane_id="$session_name:$window_number.$pane_index" + # tmux send-keys has -R option that should reset the terminal. + # However, appending 'clear' to the command seems to work more reliably. + local read_command="history -r '$(resurrect_history_file "$pane_id")'; clear" + tmux send-keys -t "$pane_id" "$read_command" C-m + fi + fi + done +} + +restore_all_pane_processes() { + if restore_pane_processes_enabled; then + local pane_full_command + awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $11 !~ "^:$" { print $2, $3, $7, $8, $11; }' $(last_resurrect_file) | + while IFS=$d read session_name window_number pane_index dir pane_full_command; do + dir="$(remove_first_char "$dir")" + pane_full_command="$(remove_first_char "$pane_full_command")" + restore_pane_process "$pane_full_command" "$session_name" "$window_number" "$pane_index" "$dir" + done + fi +} + +restore_active_pane_for_each_window() { + awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $9 == 1 { print $2, $3, $7; }' $(last_resurrect_file) | + while IFS=$d read session_name window_number active_pane; do + tmux switch-client -t "${session_name}:${window_number}" + tmux select-pane -t "$active_pane" + done +} + +restore_zoomed_windows() { + awk 'BEGIN { FS="\t"; OFS="\t" } /^pane/ && $6 ~ /Z/ && $9 == 1 { print $2, $3; }' $(last_resurrect_file) | + while IFS=$d read session_name window_number; do + tmux resize-pane -t "${session_name}:${window_number}" -Z + done +} + +restore_grouped_sessions() { + while read line; do + if is_line_type "grouped_session" "$line"; then + restore_grouped_session "$line" + restore_active_and_alternate_windows_for_grouped_sessions "$line" + fi + done < $(last_resurrect_file) +} + +restore_active_and_alternate_windows() { + awk 'BEGIN { FS="\t"; OFS="\t" } /^window/ && $5 ~ /[*-]/ { print $2, $4, $3; }' $(last_resurrect_file) | + sort -u | + while IFS=$d read session_name active_window window_number; do + tmux switch-client -t "${session_name}:${window_number}" + done +} + +restore_active_and_alternate_sessions() { + while read line; do + if is_line_type "state" "$line"; then + restore_state "$line" + fi + done < $(last_resurrect_file) +} + +main() { + if supported_tmux_version_ok && check_saved_session_exists; then + start_spinner "Restoring..." "Tmux restore complete!" + restore_all_panes + restore_pane_layout_for_each_window >/dev/null 2>&1 + if save_bash_history_option_on; then + restore_shell_history + fi + restore_all_pane_processes + # below functions restore exact cursor positions + restore_active_pane_for_each_window + restore_zoomed_windows + restore_grouped_sessions # also restores active and alt windows for grouped sessions + restore_active_and_alternate_windows + restore_active_and_alternate_sessions + stop_spinner + display_message "Tmux restore complete!" + fi +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/save.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/save.sh new file mode 100755 index 00000000..137e2292 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/save.sh @@ -0,0 +1,290 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/variables.sh" +source "$CURRENT_DIR/helpers.sh" +source "$CURRENT_DIR/spinner_helpers.sh" + +# delimiters +d=$'\t' +delimiter=$'\t' + +# if "quiet" script produces no output +SCRIPT_OUTPUT="$1" + +grouped_sessions_format() { + local format + format+="#{session_grouped}" + format+="${delimiter}" + format+="#{session_group}" + format+="${delimiter}" + format+="#{session_id}" + format+="${delimiter}" + format+="#{session_name}" + echo "$format" +} + +pane_format() { + local format + format+="pane" + format+="${delimiter}" + format+="#{session_name}" + format+="${delimiter}" + format+="#{window_index}" + format+="${delimiter}" + format+=":#{window_name}" + format+="${delimiter}" + format+="#{window_active}" + format+="${delimiter}" + format+=":#{window_flags}" + format+="${delimiter}" + format+="#{pane_index}" + format+="${delimiter}" + format+=":#{pane_current_path}" + format+="${delimiter}" + format+="#{pane_active}" + format+="${delimiter}" + format+="#{pane_current_command}" + format+="${delimiter}" + format+="#{pane_pid}" + format+="${delimiter}" + format+="#{history_size}" + echo "$format" +} + +window_format() { + local format + format+="window" + format+="${delimiter}" + format+="#{session_name}" + format+="${delimiter}" + format+="#{window_index}" + format+="${delimiter}" + format+="#{window_active}" + format+="${delimiter}" + format+=":#{window_flags}" + format+="${delimiter}" + format+="#{window_layout}" + echo "$format" +} + +state_format() { + local format + format+="state" + format+="${delimiter}" + format+="#{client_session}" + format+="${delimiter}" + format+="#{client_last_session}" + echo "$format" +} + +dump_panes_raw() { + tmux list-panes -a -F "$(pane_format)" +} + +dump_windows_raw(){ + tmux list-windows -a -F "$(window_format)" +} + +toggle_window_zoom() { + local target="$1" + tmux resize-pane -Z -t "$target" +} + +_save_command_strategy_file() { + local save_command_strategy="$(get_tmux_option "$save_command_strategy_option" "$default_save_command_strategy")" + local strategy_file="$CURRENT_DIR/../save_command_strategies/${save_command_strategy}.sh" + local default_strategy_file="$CURRENT_DIR/../save_command_strategies/${default_save_command_strategy}.sh" + if [ -e "$strategy_file" ]; then # strategy file exists? + echo "$strategy_file" + else + echo "$default_strategy_file" + fi +} + +pane_full_command() { + local pane_pid="$1" + local strategy_file="$(_save_command_strategy_file)" + # execute strategy script to get pane full command + $strategy_file "$pane_pid" +} + +number_nonempty_lines_on_screen() { + local pane_id="$1" + tmux capture-pane -pJ -t "$pane_id" | + sed '/^$/d' | + wc -l | + sed 's/ //g' +} + +# tests if there was any command output in the current pane +pane_has_any_content() { + local pane_id="$1" + local history_size="$(tmux display -p -t "$pane_id" -F "#{history_size}")" + local cursor_y="$(tmux display -p -t "$pane_id" -F "#{cursor_y}")" + # doing "cheap" tests first + [ "$history_size" -gt 0 ] || # history has any content? + [ "$cursor_y" -gt 0 ] || # cursor not in first line? + [ "$(number_nonempty_lines_on_screen "$pane_id")" -gt 1 ] +} + +capture_pane_contents() { + local pane_id="$1" + local start_line="-$2" + local pane_contents_area="$3" + if pane_has_any_content "$pane_id"; then + if [ "$pane_contents_area" = "visible" ]; then + start_line="0" + fi + # the printf hack below removes *trailing* empty lines + printf '%s\n' "$(tmux capture-pane -epJ -S "$start_line" -t "$pane_id")" > "$(pane_contents_file "$pane_id")" + fi +} + +save_shell_history() { + local pane_id="$1" + local pane_command="$2" + local full_command="$3" + if [ "$pane_command" == "bash" ] && [ "$full_command" == ":" ]; then + # leading space prevents the command from being saved to history + # (assuming default HISTCONTROL settings) + local write_command=" history -w '$(resurrect_history_file "$pane_id")'" + # C-e C-u is a Bash shortcut sequence to clear whole line. It is necessary to + # delete any pending input so it does not interfere with our history command. + tmux send-keys -t "$pane_id" C-e C-u "$write_command" C-m + fi +} + +get_active_window_index() { + local session_name="$1" + tmux list-windows -t "$session_name" -F "#{window_flags} #{window_index}" | + awk '$1 ~ /\*/ { print $2; }' +} + +get_alternate_window_index() { + local session_name="$1" + tmux list-windows -t "$session_name" -F "#{window_flags} #{window_index}" | + awk '$1 ~ /-/ { print $2; }' +} + +dump_grouped_sessions() { + local current_session_group="" + local original_session + tmux list-sessions -F "$(grouped_sessions_format)" | + grep "^1" | + cut -c 3- | + sort | + while IFS=$d read session_group session_id session_name; do + if [ "$session_group" != "$current_session_group" ]; then + # this session is the original/first session in the group + original_session="$session_name" + current_session_group="$session_group" + else + # this session "points" to the original session + active_window_index="$(get_active_window_index "$session_name")" + alternate_window_index="$(get_alternate_window_index "$session_name")" + echo "grouped_session${d}${session_name}${d}${original_session}${d}:${alternate_window_index}${d}:${active_window_index}" + fi + done +} + +fetch_and_dump_grouped_sessions(){ + local grouped_sessions_dump="$(dump_grouped_sessions)" + get_grouped_sessions "$grouped_sessions_dump" + if [ -n "$grouped_sessions_dump" ]; then + echo "$grouped_sessions_dump" + fi +} + +# translates pane pid to process command running inside a pane +dump_panes() { + local full_command + dump_panes_raw | + while IFS=$d read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_pid history_size; do + # not saving panes from grouped sessions + if is_session_grouped "$session_name"; then + continue + fi + full_command="$(pane_full_command $pane_pid)" + echo "${line_type}${d}${session_name}${d}${window_number}${d}${window_name}${d}${window_active}${d}${window_flags}${d}${pane_index}${d}${dir}${d}${pane_active}${d}${pane_command}${d}:${full_command}" + done +} + +dump_windows() { + dump_windows_raw | + while IFS=$d read line_type session_name window_index window_active window_flags window_layout; do + # not saving windows from grouped sessions + if is_session_grouped "$session_name"; then + continue + fi + # window_layout is not correct for zoomed windows + if [[ "$window_flags" == *Z* ]]; then + # unmaximize the window + toggle_window_zoom "${session_name}:${window_index}" + # get correct window layout + window_layout="$(tmux display-message -p -t "${session_name}:${window_index}" -F "#{window_layout}")" + # sleep required otherwise vim does not redraw correctly, issue #112 + sleep 0.1 || sleep 1 # portability hack + # maximize window again + toggle_window_zoom "${session_name}:${window_index}" + fi + echo "${line_type}${d}${session_name}${d}${window_index}${d}${window_active}${d}${window_flags}${d}${window_layout}" + done +} + +dump_state() { + tmux display-message -p "$(state_format)" +} + +dump_pane_contents() { + local pane_contents_area="$(get_tmux_option "$pane_contents_area_option" "$default_pane_contents_area")" + dump_panes_raw | + while IFS=$d read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command pane_pid history_size; do + capture_pane_contents "${session_name}:${window_number}.${pane_index}" "$history_size" "$pane_contents_area" + done +} + +dump_bash_history() { + dump_panes | + while IFS=$d read line_type session_name window_number window_name window_active window_flags pane_index dir pane_active pane_command full_command; do + save_shell_history "$session_name:$window_number.$pane_index" "$pane_command" "$full_command" + done +} + +save_all() { + local resurrect_file_path="$(resurrect_file_path)" + mkdir -p "$(resurrect_dir)" + fetch_and_dump_grouped_sessions > "$resurrect_file_path" + dump_panes >> "$resurrect_file_path" + dump_windows >> "$resurrect_file_path" + dump_state >> "$resurrect_file_path" + ln -fs "$(basename "$resurrect_file_path")" "$(last_resurrect_file)" + if capture_pane_contents_option_on; then + mkdir -p "$(pane_contents_dir)" + dump_pane_contents + pane_contents_create_archive + pane_content_files_cleanup + fi + if save_bash_history_option_on; then + dump_bash_history + fi +} + +show_output() { + [ "$SCRIPT_OUTPUT" != "quiet" ] +} + +main() { + if supported_tmux_version_ok; then + if show_output; then + start_spinner "Saving..." "Tmux environment saved!" + fi + save_all + if show_output; then + stop_spinner + display_message "Tmux environment saved!" + fi + fi +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/spinner_helpers.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/spinner_helpers.sh new file mode 100644 index 00000000..fe73cd70 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/spinner_helpers.sh @@ -0,0 +1,8 @@ +start_spinner() { + $CURRENT_DIR/tmux_spinner.sh "$1" "$2" & + export SPINNER_PID=$! +} + +stop_spinner() { + kill $SPINNER_PID +} diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/tmux_spinner.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/tmux_spinner.sh new file mode 100755 index 00000000..9b1b9792 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/tmux_spinner.sh @@ -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 diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/variables.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/variables.sh new file mode 100644 index 00000000..8d3edd43 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/scripts/variables.sh @@ -0,0 +1,43 @@ +# key bindings +default_save_key="C-s" +save_option="@resurrect-save" +save_path_option="@resurrect-save-script-path" + +default_restore_key="C-r" +restore_option="@resurrect-restore" +restore_path_option="@resurrect-restore-script-path" + +# default processes that are restored +default_proc_list_option="@resurrect-default-processes" +default_proc_list='vi vim nvim emacs man less more tail top htop irssi mutt' + +# User defined processes that are restored +# 'false' - nothing is restored +# ':all:' - all processes are restored +# +# user defined list of programs that are restored: +# 'my_program foo another_program' +restore_processes_option="@resurrect-processes" +restore_processes="" + +# Defines part of the user variable. Example usage: +# set -g @resurrect-strategy-vim "session" +restore_process_strategy_option="@resurrect-strategy-" + +inline_strategy_token="->" + +save_command_strategy_option="@resurrect-save-command-strategy" +default_save_command_strategy="ps" + +# Pane contents capture options. +# @resurrect-pane-contents-area option can be: +# 'visible' - capture only the visible pane area +# 'full' - capture the full pane contents +pane_contents_option="@resurrect-capture-pane-contents" +pane_contents_area_option="@resurrect-pane-contents-area" +default_pane_contents_area="full" + +bash_history_option="@resurrect-save-bash-history" + +# set to 'on' to ensure panes are never ever overwritten +overwrite_option="@resurrect-never-overwrite" diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/strategies/irb_default_strategy.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/strategies/irb_default_strategy.sh new file mode 100755 index 00000000..897f5bbc --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/strategies/irb_default_strategy.sh @@ -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 diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/strategies/nvim_session.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/strategies/nvim_session.sh new file mode 100755 index 00000000..4987c689 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/strategies/nvim_session.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +# "nvim session strategy" +# +# Same as vim strategy, see file 'vim_session.sh' + +ORIGINAL_COMMAND="$1" +DIRECTORY="$2" + +nvim_session_file_exists() { + [ -e "${DIRECTORY}/Session.vim" ] +} + +original_command_contains_session_flag() { + [[ "$ORIGINAL_COMMAND" =~ "-S" ]] +} + +main() { + if nvim_session_file_exists; then + echo "nvim -S" + elif original_command_contains_session_flag; then + # Session file does not exist, yet the original nvim command contains + # session flag `-S`. This will cause an error, so we're falling back to + # starting plain nvim. + echo "nvim" + else + echo "$ORIGINAL_COMMAND" + fi +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/strategies/vim_session.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/strategies/vim_session.sh new file mode 100755 index 00000000..81213442 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/strategies/vim_session.sh @@ -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 diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/tests/fixtures/restore_file.txt b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/fixtures/restore_file.txt new file mode 100644 index 00000000..74bd2401 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/fixtures/restore_file.txt @@ -0,0 +1,21 @@ +pane 0 0 :bash 1 :* 0 :/tmp 1 bash : +pane blue 0 :vim 0 : 0 :/tmp 1 vim :vim foo.txt +pane blue 1 :man 0 :- 0 :/tmp 0 bash : +pane blue 1 :man 0 :- 1 :/usr/share/man 1 man :man echo +pane blue 2 :bash 1 :* 0 :/tmp 1 bash : +pane red 0 :bash 0 : 0 :/tmp 1 bash : +pane red 1 :bash 0 :- 0 :/tmp 0 bash : +pane red 1 :bash 0 :- 1 :/tmp 0 bash : +pane red 1 :bash 0 :- 2 :/tmp 1 bash : +pane red 2 :bash 1 :* 0 :/tmp 0 bash : +pane red 2 :bash 1 :* 1 :/tmp 1 bash : +pane yellow 0 :bash 1 :* 0 :/tmp/bar 1 bash : +window 0 0 1 :* ce9e,200x49,0,0,1 +window blue 0 0 : ce9f,200x49,0,0,2 +window blue 1 0 :- 178b,200x49,0,0{100x49,0,0,3,99x49,101,0,4} +window blue 2 1 :* cea2,200x49,0,0,5 +window red 0 0 : cea3,200x49,0,0,6 +window red 1 0 :- 135b,200x49,0,0[200x24,0,0,7,200x24,0,25{100x24,0,25,8,99x24,101,25,9}] +window red 2 1 :* db81,200x49,0,0[200x24,0,0,10,200x24,0,25,11] +window yellow 0 1 :* 6781,200x49,0,0,12 +state yellow blue diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/tests/fixtures/save_file.txt b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/fixtures/save_file.txt new file mode 100644 index 00000000..ff938ac7 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/fixtures/save_file.txt @@ -0,0 +1,21 @@ +pane 0 0 :bash 1 :* 0 :/tmp 1 bash : +pane blue 0 :vim 0 : 0 :/tmp 1 vim :vim foo.txt +pane blue 1 :man 0 :- 0 :/tmp 0 bash : +pane blue 1 :man 0 :- 1 :/usr/share/man 1 man :man echo +pane blue 2 :bash 1 :* 0 :/tmp 1 bash : +pane red 0 :bash 0 : 0 :/tmp 1 bash : +pane red 1 :bash 0 :- 0 :/tmp 0 bash : +pane red 1 :bash 0 :- 1 :/tmp 0 bash : +pane red 1 :bash 0 :- 2 :/tmp 1 bash : +pane red 2 :bash 1 :* 0 :/tmp 0 bash : +pane red 2 :bash 1 :* 1 :/tmp 1 bash : +pane yellow 0 :bash 1 :* 0 :/tmp/bar 1 bash : +window 0 0 1 :* ce9d,200x49,0,0,0 +window blue 0 0 : cea4,200x49,0,0,7 +window blue 1 0 :- 9797,200x49,0,0{100x49,0,0,8,99x49,101,0,9} +window blue 2 1 :* 677f,200x49,0,0,10 +window red 0 0 : ce9e,200x49,0,0,1 +window red 1 0 :- 52b7,200x49,0,0[200x24,0,0,2,200x24,0,25{100x24,0,25,3,99x24,101,25,4}] +window red 2 1 :* bd68,200x49,0,0[200x24,0,0,5,200x24,0,25,6] +window yellow 0 1 :* 6780,200x49,0,0,11 +state yellow blue diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/create_and_save_tmux_test_environment.exp b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/create_and_save_tmux_test_environment.exp new file mode 100755 index 00000000..feef033e --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/create_and_save_tmux_test_environment.exp @@ -0,0 +1,41 @@ +#!/usr/bin/env expect + +source "./tests/helpers/expect_helpers.exp" + +expect_setup + +spawn tmux +# delay with sleep to compensate for tmux starting time +sleep 1 + +run_shell_command "cd /tmp" + +# session red +new_tmux_session "red" + +new_tmux_window +horizontal_split +vertical_split + +new_tmux_window +horizontal_split + +# session blue +new_tmux_session "blue" + +run_shell_command "touch foo.txt" +run_shell_command "vim foo.txt" + +new_tmux_window +vertical_split +run_shell_command "man echo" + +new_tmux_window + +# session yellow +new_tmux_session "yellow" +run_shell_command "cd /tmp/bar" + +start_resurrect_save + +run_shell_command "tmux kill-server" diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/expect_helpers.exp b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/expect_helpers.exp new file mode 100644 index 00000000..6980428c --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/expect_helpers.exp @@ -0,0 +1,65 @@ +# a set of expect helpers + +# basic setup for each script +proc expect_setup {} { + # disables script output + log_user 0 + # standard timeout + set timeout 5 +} + +proc new_tmux_window {} { + send "c" + send "cd /tmp\r" + sleep 0.2 +} + +proc rename_current_session {name} { + send "$" + # delete existing name with ctrl-u + send "" + send "$name\r" + sleep 0.2 +} + +proc new_tmux_session {name} { + send "TMUX='' tmux new -d -s $name\r" + sleep 1 + send "tmux switch-client -t $name\r" + send "cd /tmp\r" + sleep 0.5 +} + +proc horizontal_split {} { + send "\"" + sleep 0.2 + send "cd /tmp\r" + sleep 0.1 +} + +proc vertical_split {} { + send "%" + sleep 0.2 + send "cd /tmp\r" + sleep 0.1 +} + +proc run_shell_command {command} { + send "$command\r" + sleep 1 +} + +proc start_resurrect_save {} { + send "" + sleep 5 +} + +proc start_resurrect_restore {} { + send "" + sleep 10 +} + +proc clear_screen_for_window {target} { + send "tmux send-keys -t $target C-l\r" + sleep 0.2 +} diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/helpers.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/helpers.sh new file mode 120000 index 00000000..ddf37814 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/helpers.sh @@ -0,0 +1 @@ +../../lib/tmux-test/tests/helpers/helpers.sh \ No newline at end of file diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/restore_and_save_tmux_test_environment.exp b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/restore_and_save_tmux_test_environment.exp new file mode 100755 index 00000000..82da37f0 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/restore_and_save_tmux_test_environment.exp @@ -0,0 +1,18 @@ +#!/usr/bin/env expect + +source "./tests/helpers/expect_helpers.exp" + +expect_setup + +spawn tmux +# delay with sleep to compensate for tmux starting time +sleep 1 + +start_resurrect_restore + +# delete all existing resurrect save files +run_shell_command "rm ~/.tmux/resurrect/*" + +start_resurrect_save + +run_shell_command "tmux kill-server" diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/resurrect_helpers.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/resurrect_helpers.sh new file mode 100644 index 00000000..268aca5e --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/helpers/resurrect_helpers.sh @@ -0,0 +1,11 @@ +# we want "fixed" dimensions no matter the size of real display +set_screen_dimensions_helper() { + stty cols 200 + stty rows 50 +} + +last_save_file_differs_helper() { + local original_file="$1" + diff "$original_file" "${HOME}/.tmux/resurrect/last" + [ $? -ne 0 ] +} diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/tests/run_tests_in_isolation b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/run_tests_in_isolation new file mode 120000 index 00000000..7c9c3f76 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/run_tests_in_isolation @@ -0,0 +1 @@ +../lib/tmux-test/tests/run_tests_in_isolation \ No newline at end of file diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/tests/test_resurrect_restore.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/test_resurrect_restore.sh new file mode 100755 index 00000000..9cf46441 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/test_resurrect_restore.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source $CURRENT_DIR/helpers/helpers.sh +source $CURRENT_DIR/helpers/resurrect_helpers.sh + +setup_before_restore() { + # setup restore file + mkdir -p ~/.tmux/resurrect/ + cp tests/fixtures/restore_file.txt "${HOME}/.tmux/resurrect/restore_file.txt" + ln -sf restore_file.txt "${HOME}/.tmux/resurrect/last" + + # directory used in restored tmux session + mkdir -p /tmp/bar +} + +restore_tmux_environment_and_save_again() { + set_screen_dimensions_helper + $CURRENT_DIR/helpers/restore_and_save_tmux_test_environment.exp +} + +main() { + install_tmux_plugin_under_test_helper + setup_before_restore + restore_tmux_environment_and_save_again + + if last_save_file_differs_helper "tests/fixtures/restore_file.txt"; then + fail_helper "Saved file not correct after restore" + fi + exit_helper +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/tests/test_resurrect_save.sh b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/test_resurrect_save.sh new file mode 100755 index 00000000..99fb9257 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/tests/test_resurrect_save.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source $CURRENT_DIR/helpers/helpers.sh +source $CURRENT_DIR/helpers/resurrect_helpers.sh + +create_tmux_test_environment_and_save() { + set_screen_dimensions_helper + $CURRENT_DIR/helpers/create_and_save_tmux_test_environment.exp +} + +main() { + install_tmux_plugin_under_test_helper + mkdir -p /tmp/bar # setup required dirs + create_tmux_test_environment_and_save + + if last_save_file_differs_helper "tests/fixtures/save_file.txt"; then + fail_helper "Saved file not correct (initial save)" + fi + exit_helper +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/video/issue_vid.png b/filesystem/root/.tmux/plugins/tmux-resurrect/video/issue_vid.png new file mode 100644 index 0000000000000000000000000000000000000000..8ea5ea24cc386581331397628ec3b389474d443b GIT binary patch literal 63584 zcmZVl18^om*EbGF8)suD8{2lSI2+rxZQHiJu{XAD+qQGX`R{!{@Atk>)iX?ke3xlfW?6Y0Rcgf_${Ic0s8C#i54j1Odht>hTZ@@@_?T=Zn-Df4{cVpUDIaOT{GKe)o>sL5h&>Bq0Hb&zmSDp zSXt0qfwySn(I8;EVA2Ap(DL3zMevtb)qUT*$B>{xR^GJY4NrijFE8+@JikT;kZ?Zh z=eww9gs>NC5OuK~N=tZW>ec)@z(6UQ5ehf&j z6_^020_CCr2v$siHs>@4(z?N8kWCe`Zy$1<7T92Ww;&qjfsH>m?!W+vg*%=hRi57( z%m-$Py!Y4oA9=9veZB79+}pn4zBvVhK}-^F>nlRjkX9}%&qrJ!#8763fb;^vQw)1xJw!Ir_iYiDmf$2Jh$I2-x#2CY zlzbUd^+i!=9}~uOPdyFW{9TI=D=G10Dmx$_pOtHLXCIOOlE7vk;wT;*2L;L65|jy# zrjeU!bPd696xAji&b28d9eIEHRGtC{Dl;eG4nk=h8_7tp6-KwS#IpINl+o}e7$ zyWiB_Dr@ne)$L-mZjfQO2PlG#JnGxkZK~Kh&j*ySD?UXi#%d{8y|-dp2#axGA$O5cnx zR%?*aLRLM6`-mhMpe0|Y`ecMwY*j?6Q1@Y*_1WsWgkdTnxmfy7`F57_Zxo)a%k_S3 zpQsZ6hwmbBBf1X;0>24t6RaiQhTGQzbi6S@!iyZucOwKipv>ecFEgEX5`B_y(qP&Hf$Hb9oZDA6iMUf`}vdtM#c)+$mIV3 z7zPkQP6PDOuv2~`{DhB0X7{hG>!}kBuKf@*FcBqF0Wr7YmVxrWiM_C5>tB11i$;O; zFJT6G4E-J@-s6^6gD8EP^D{=d^*Nja+x=T)N6U7d#z%V<3jSzcs}IF1fD{f!b(+L1 z54A2pkPafH50xDNwF+7E3!k8J$yCkG&Ht>usafw2ws9{GO~;aCX-+lviKnQofudGG%1FJ*fU|< zsKFtYBTl&>JyFc4%^~P~9IyB`q0%UaG0adtX)->#0Ga#`WmGnSYI!qf8l3QJfuvdZ zM?%fO)S{EQi&L9NqBk^rQ9xk>mcK!-y`c!BBbH1w^6<}t2$)`Zrt)+=X{Hi9r7(*? zqfacB$c$lH!#j2MDn`|x({fH#aLbq-;8~GdaeSfG!@47`h6F}C`etdEJh2A zS%A~XkNtgzj8;Q!^lO~!pWbfUd&jr#ycD`9wV*pPh~Ch?6uy8j&hB43p*JIOduA{Y zV2FaL`NDN1^3Y7d()|kk9zrw*{*@}$SDyeB65ZhOgZY(yyDhGKanWHC!8mp z_nos&FHb*CQO@p9sn0S`JVjvuHBDFDSeSB~!kChn!a7kqQ8|%3 zAU)8+;YOiE;Y)E&_@+A1BC3;Xz*M1BkyrUvVOOD7;a3@1W3el+ld$VG^I4}@yRB~5 zAFPqB(X9%vI;}C(0qbV$>m17*TOCR5lN~qrv5p4qCG9osLmiGCbdT{4wf9kWnRo9` z#*ZrwaCS3Kjt`bko=>LtYEFE|y9P-njrvi?lV+TPPS6=r)k0SSIC6myH~8BY{I2{q z{CeGZ-4oseACx`tJtW_f z^^oE*PvZE>Esm{PQTIA-1O0ru-TKt1+Z( zk|r56uBM`);_3|HqIK#y2f_J2DI8<>9@eP zyqdRM*4+HlO=Y@pB%{}O)F|9EVVf{Yr`zbWXUp&m4$tR1x&BYY)!{w!Diah z$1&Hm;x;NVZC-d-3^l4dhIMZ^=IA~pc z9c{I<5xpg*uFC-GlJ*kzQg=;i{id$x%-^lfjnc*artC2N(tRdk%A#X|tCY)3_=NWa zlU|X&p8l#vx<(dY*fwlSYzuu;X_LV7))T^u)g6Ubhp&>?tR>x=YW;p%YKmsT z%D(b&Ik+0J`OX$@!_|ss!FBwZW}DNF=@IIo z^27fg_(BEc1`Puz2X_I311k-D42%pa35p4f`{9Scgvf=>Okj!W$?i-yNms?6jdhK` zjn#*Pj5CK#g_VJ{MnHy}g3Z=$v=Cc}&!S9YsltlV#nw&~ito$oHX=E69pi&qimQgx zf^>u9M;1UvL|nk5K+eSDKs?5JHYs~4yOVP@Mm*M$wDSk+PqwV6qL1Q+Tg3JF>J$AG zZM7%I=k@GX+&uaMV(ItlL31gUFd+$@k#+6b_PX@2wB_+E|CJ9#L!CyS2HzU>ns|fX z@yn6(5%n>~NzEm2YsW?4OkgaaDF_tG>wfV;7O$Tml9M&PHcihb{m6cPuO2Kb@FJu? zgewFP*^J3YsY=K15&ZT0GGPwoA~CecP#h6ohYQ2`(xTkJ!Ux+=!*%V$q2~ac;!$of z2aPks%kfP4w%n|AN>+~{jgq0JS8Y(Gv(~w~(@pF_S_a)t#dhg@Exe&#&~+eDDr`1`U&#Z!$=tqbHM6gM>Yn~QhRXWI>T2P-)E0SY!bJO zt9dE|YTqoK+MF(&Tb=K0?l9+b*uU4`9dyXi=JI-5zBl^Kn%u6%ugspZ^q3{h4CMOZ z$KvYxCOo46nNQFkD)*7U67E;#YcIr?#O=D6d>1~K&#t1FcIx8}<_>6Xn75O5Fy)|S z7Nx1>*yS>0pL|yD_qImL;wBa{^3?fLd{W=MpQ66fuCaj`ZhGZZ3w+IiDSDh@UPbXz&H@(c5G&kK_aJ!W?c5mr@>J2pP!Wqp3b2=xe! zthM0P<29WozvH^y!LzD;!xNlq*WRw_gMyPRIu_jrt+W9*7KLZ;Kji@(zqOqF>WfH^7D?y zd3aZ?;*P7kneep^js|-@ljW4l=IrauzRy}jX}phQ;MJ`4*XG_@;97sN;U#ixVvP7y z>}%>ZH4T@pTjA5;fRdanVp^Q4w8~dmfA&#XYB>|{i3+Y?_ig`C``24-nmT=@wnICP z&(-WxCaw%Z3ocLQy6v`gw`*m0aY<9*)yq}kb9U_EbUcr&+tQ80j#ek&Ex+aBdLZ_C zBQDeH+)L`M@I3}{6g-X~jUUFnf;}7;52wNx1E}qX1@K0kW@t)7t-Tj-6d%?lz*_qC z`Eq=yHNrHh{@FV5vft4U#NBC;<&=$#tBpymNsPAo4>t=z%RthA?+d^fJ`Lz zKrI4KVsN6KkXXiOruu0rD?<#ubl!I;-kCdpK^f&%F zRU(;g)m@@S%U2P(lC-c>V@Qcjj83gfu}I+|VR=Iaz<%KJ;+*nm{Wt)B56^(}gzd*n zmI;$iqm{1SuKubizDl}UvVK*+a}j@*ew2LBxkEO>Hb6JWH#)Gk;2xEmcBVRGbGH%I z$)LFI)9!uqqVvE2w~Bp=@dry9HuvWloDFOx3`5LllyqF-^=;v~IGiZM2yaXmQX2M6 zl73=YI%%^KVFpDANs0%i?~3;N#+J@m+B2HT;LTR1McWML1b0?q0}pWWs{=~xr|)zY zA8Q`K>&2^2datzbY=1@^BbJ$9fjWk=l6%|9@bYl6+^tkE4N!Yp+v!(QT=8nH_EhRb z+@v*=rsJ+V<2(1Ph@stuQ9Gsw>`+)|oDJ?MU+?@}-cGGpK5kCkI9W$@`QtpiBhiuN zcJuNX2}RNVlRx^()su83=nDI~Ycp+wfO+?J^)O;gDNHc0VATwJ28dAF3GHt27ztc@ z{C#lYQ*>>2xQ(*YO>lt)__7`G`h=MuOd5+U*C7Z5yvacMz<%RBky(!Ty0tX51 z8v2|}AEY1DFr+bl(R!Cdrsfsr%13<=&4U8LlIY_ww_(0o(X9|}M zuubTW+9RdPy&Nr@92{jG`N%GgX$r0O=L;c;Ur3M&)5;7BG7E7_wDa!~&6lkcDpPJ% z|6?zlYhI$B%_-V1qNwgDSfTayN4l}!FURLv|wuieZb;U6vJl_VRU*57Qru zTT5&nwB?14mmP!^+U!DJ^S;bGc?Gz^u@?sDsAN{DeqrFgY z^_l+C9`{`W4+bBAVmLm+gPr2wne=?I?Mn?j>;FR>WH>;gAs#W}C^-`MkS)(&?jm{7 zsM#hIqFg+RolBkC@VMm6CT&lCmJRH#tGyQbJcy!6E3R?Z<@2uohV%*&H_}*;XSq&w zj?$=<+o;)~Sl8m#b*tGzZ!>cS-1dFdNFhRXsCoVIYI(#zBk-vDIP6`R5tg072@};t z>r!-|dLjRZPMGhKu3Fkeq1Io%E4t>MAv(E1elX5B^MTAzf!y1H5IUfO(0hVhj)8Dm zfjaBq3rwAZptJ*Tz5+mK3H!5?P@zFB@?lwItaf2oP9WkDSjHdnf57*0kHYpx{w8^2 z1VoGd?Df9=$s9^t25lMsR`9N$%HdCMAi~6+PAbi23N1Bg+aGE~Q#a#K#YvN%;IfO{ z$6}1|xM(+r>HE893)b#(Sk^?BmImmCK9j{uPl7QAREKP8Hj=t%sQCEdd=0;3LA}7Uf>MQ| zh2lc##9qXHUNRQ5kCY8Bk4%thORje|FpxQ7`mO7G8iYP=xA}yu;W}Mk0s*55K<;ma zzRJQTlszL&lVytLJV{!B3YWKP&GDkgQ2U%zX{~KX->mvdXOl{^&S~t~=e@0Bt@8I~ z(g#ub$tQzcC;z?cZWnNIpJJKeq$hwN(n<5dDvC=AVM0#Twnp_MT5~~N4-o&92~M*M zj#9Ur4`uC-Sw;6J&|4k`N06Zkw~9DB9Lz8RqBl~2s|u`Bw7!hgGDdOE$Q;BT;rG$7RgtukBE_Od5-CJW^i3P*Eo|+qdgeY0rkhn|2l=>Fm_>4I(9F&p%q+{y z3T#WPEG#>=36>t~=ebYOba^=uK9rjausN}um~Ck7xsFyY-{m zqmTu}WWRCmL61aY=CB%J@rUd5X&JH8*(a&1CP@vl>S#E@wSU?|GsNt~_=(PvC8I_R z{@zFBrfWZVq^t_zHDNSum6#{qBHu{bVJTsWU~FRYVw$PPGfXk^8N}$5HLX2nJaiw+ z7$qBB8t{o930sMm3(d>%)7VYX51KXDvq!!_h%DSRbgvh^t3}Zx?UAY;XB>~TSxkFK zl~dxZSO_`Io>2lIeE$__&)*_?EI{95Par&pWMdX%Y$oAnpR+qT zSsZU1+zL9Q!9LYBB!A#fsXD!+Xrq5G{b`DyIOC@qukuIdqv_A_YBTfOftj3TcDqWA z+MMffYenUH_pwCv!)rJ9!rQQvVp^OwnXXh@_k8>osYAn!s%NF=hO(DN>6XrAR~BL+ z!MJN2F#FVrK;Mt|mep?ber^5sHO;k_TyG?{rdx(!q*E$SfCA{<>$}PJ`Py)nHkfgs zhv*&kY5U>xHPWWBv4-g+=;ZX^@Sp^z3)dAT7S$wmSX@>dVA6DycvMS+L32biQ8`_S z>1*iQ{>|GHTGdvSQxxOp>=nahR3{B|WZS4PXgMje5bN{Q_m^d2{y4zUWI&r)65&xHi`(OP( z%?!kZ|7CHu;v-gp2{m*-vxLf=`OSVq`XITFR$nc*Y1}1t&hX1SkpD6EtTDj#d z+)b?2MJ#MgY@Pnu;OAoFYJ z$`5*6+zo%3OC-E(SwERDQh13{BBFrc;6u1oq~EwN(4g}OSkX3&CTV7t_9<4W%9&53 zT^`*JyuhC4wv#Rz4Qi>7T5Yl`x-PGoEwdY+XANLi({$#SN&T9&jC1=PEJoCiIz;T$ zYftn_E>}dko3y^;4bn89560OmxtJ?LK`?Ri4fco_du(Qu5Sd=s%8h@qsvsxIuqJzm z<^rVOP|V5qp-S+ZQ0qmG8*%Q2f5!$w?GRMUK#XCvzcW2})=r@OV92>6_ynfnY2Io7 zTQT19@p7H71I$5~7?X!NM4Jfc))rG0gGrseDap5yt3uPnx+# zf9Y$_fieUUB7~G62*}p?MT@T|)?gX5VH(1)E4Xt_#OaMe>+6JG)G+Y-&kEz~vjnT` zO8wQBL{;97K-a8*pC6#pgMqk6))GhN<($d7a%uNacUkUm*86V_#P1trj!;B|y^pzv z({1#C79RMlg@A;Pkvc{%n7JCPXS}tb;svYx4;I$)mR`*FuJuCRvqnIlckOdQZ6#Gc z)$JSF>Y}8%!kRZJhExLUy~Mz*VP|E}*_7Zgl1CR8n8>pdhxETF>aQkAl`H*&en?rh z3C<^Lye>ZaWLz>pi58Kr$K7su3xQH{K4&?oH8<| zKE4R4(LbaZXoU|NaJ=DU7r2MzzOhNe}_@#A}rOi_VnaZIs9GB=nOSD;^>-i5@R+f5co*8%9h88kqlZk>X`DBHwad@ zqn?I1D?BXGJJ&#(QePAkGb7J$@WQ0Bo;@8WY_U)tx+OP@30t9xVSU+fzh@=Os$settlw zw|woL0U%{6@n(6Ca7Kl7FWs@*-?F~Uz2N+CLI#Q_!Ws=Ujq`VAj5NQwS(htyz#ZF=zdmhQIXJ!Mb?YJeh&O4!9~$ zvuxn9dOBaGB%pCN$}t?CY@?Y~=TTi|8qGF&q5W!0Q7<#*bHw$jp(OB+cB=(I_Y89F z!x6`HO-d>_aO}CVPYeA#Y(22snp|9PH-MJ`=A@Nl5ZNX9dnew^5uU}(XHeIzFj5k{ z%vYuow3h6T1lPh$Go$4cFA4l1CB+g~!HLnw|vg@OO^JJ_|)7|!SNrJ z3+42g;Vi~#fdzsFgqh%EXgDABZ3uLIl6es*+E0+#{1rwB)6bmpX?M2#f)3VA>PDTI zK-FEOrSYnr1&*9L!nNr0(k_k*EP;j`hYaXH3TPqz5sV3ksFVp6SNRA7l}rdK zi_cSId)62BtH0jK%pum-!eYbqrhk4o6onXrrj3kF#063W`>vj20IEOCCu}9avOMxG zNEkY#KYRw;l#(Z-%bXm8XXxcyP$1oxQ?YVw0%61aBR55af-Xw8Bp@w=sX5DgAkoqy%4N9E^_4u^H_s zA61?y!}%r4@#LlUsRH~r*b>mt<%^Zb3{UZqh>E|wO>+OW^59;^ zEt^LpE1{d?J*3i0Z``s9llj1U)X{oTnqqcd795ihoJZ1~VZxxsj|G{MWEE7Xq9zEO zqFILu31#%#u7sv^_%orcFmmWw1M*33!dc3n?Ze6A=>^kDpF5V~MMsCZt4Wo{wIU-RAdb^9*d^ zjNj5XR;dW>ui%`qXh#VUnW zCdez=BZK;rIvV7_MRZ={H%{qN$k&{2Y-#?)a&n#sE2)cgA4Q-DYtD)l8e7)4uH9zJ zNwaB!|H_)}GTz$sRQob++dns<_uh2);<;W zoDM%dwPsHS&Nq2|p8(%xn_f3vFSY*`X!q~;?J(YuK|SB+hSe4~2IdU-uc?{uPR;v| zOl%bO%OTKuI7{cyt9DxW^)(GbJfZE-3o(IIn4tpfU_XrE; z7stu%t@t*m_+o&%90a;o22R+^a^>mSjd1Sv_nO`G{t`o8Zx?|ll1>ux;uY5s!x-HW z6=4;0%nt)9))ZGGmnfxN97q6^k?spGs3kWBE$t+U2UCF4jNV`ZB7xw7s(3;6@HUT| z0_q*Ju{-{BJ9xqvJ?ToKJyS3TKTF`LIaUl|gc{);o=lbQdhbLY*RXl0s-rr~1c&pyJAHw=dlFItOJvhaRx@%NI)zvd-j>nj_$2zZ$L)p&@mUh+e zRyRG^BaYwX=ytmC z_BOU{mTxXhJCdkRM;FbB?2!?fktZ$0t~IQ`2*PhwyazJpA%J}U1l1hlit~P2_~o2{ zx40%xrv&7l-F_x+Yam{af-Mz=+%4AN_>|1}LZeqE3B!kWuAH$QC??;a7T-3?XM6Ak zJwyy9B5h=dkp%BzL60jz?Te<^HVov(ZdkHR%;@P4Z3rXT=z+}Kz>*=4UKc~nfQA)x zsdqpQ1J(6ajh}wf|tMi*9&W%_9C6gU0bN8o=U!z ze&CKXjGwT^?pk^ndN4W%6w>fqN$`iGQF|8|6=4r}O9zsNl&`~1vCM>C%?m$ig{6ln zhL2H^eVaC?*Yo8uIwT~N!^^C}(<=o2*_bkHQIXMkL-3m$tNQS0D z$rbJ7Vb@|g-ftF|&<#(8OPR2AkE%TyeR zsnzRBJx^rJI1gleY%xcYs9arw&l{I)k9*Q74Vg!HS0c4h;!{Lsk(C&3e2SUxFF5yI z@td%$>7)g@oDe>=-g*F+SbimWD8co>@EgvuEL#0lEOIi9=;1!iZHEu#9Ixqv;(@xG zkr92!qi2j!sDXiE!3d^_h(;iHBJvcO7ajA4Z^Ip~lVZN|1$w(7mIitBhEPduq67S~ zE%P1hk4n~q%6h`d*>>I^!Wpp`To`=`#SqO%7{iiDnmMr~Wb&=uNks04*OJuGehj4# ztZ<&##ioPSYWJc|%~^Y17*V9qOuYgS@P0%h_P>=yi<%xWNn<8ifK?b*w^7Ud+|s)n<{qCN#=NW*vs*Qks+1y!0Zd|z2o?iMN$&d*6t|-! zal57EF5btr-#Gl4?aUdC+;%5Hm6Gh%Ug4co9)#miLQt(QRFmXC?HxsCIUz)@oOQJv zTpfmZKW%Qde93)U?>yL6#xetJ~8DDRaZW-v(#PdbyrDKba97yczp zewnW-R2?+0y{kj2S!JgM_@Rc-)P~3W^DT57a>3P$af1= zv5zR|0@_uS=-kFq$U~{@f!z1yjQxs^n}MaH2UdRkUE`~U`!|&x6=Q4GAb~%ZT^n9O;(@z-| zqEHKsF=evs7BSP$(i#2`o9|nSI>$Fs$<8@1-`g%uhjT32HdvCD&eLrj(VJ$NHv?w( zH@^?ic1VibT)!ul^fq^tneXA7-O)Hdc=Y2uwBwWX9{^Z6L{JR1G^|kRlXpw7nwnqg zB);Ud^K*H$Om1Yc-3r9u09_*J1LkL7T>li3QA<%^u{Kg(k*E6%-#6Ni<39KFIxM;D zp>h_zLJR6}!?D>xk*3XuQ{AQ!VNB~$vlRuR2e)~Qv(ncIp_lOA;r!>A|k0$R!=PAT@H_Z=y>=4KF>wx0+ z8PO-5oQg)3emdXG9lrbPmvvQjz6gPej{$b~HT`OO-%i#2*Wb<(vWSSBF3!72>}>BZ zG?oX8bCN)R$mGl3ok(3prCoA)0SJk56RKB$@3Yx$%t((vDuwK>o9_+KKJ?@KwwF8P~5-P!)%i|Q?sH`y-4rz{mQ!vwLISQ+@2=f3D!O$kt zG!an3z0^o72w%aSp%Xx!OpCp+Dgy9)heF~(>P5;MM;#o<^nC^EetJ@y(`(!-s1I5l zdPKmLVUj@UpQiYnvrjh7!TI+s>OaMOA#&BRDl6fzHvA9+JAiw)UE=bj{Hi&otQ5kl z!E2D%<2)`qL3J$ftNnwbX0*Y;k7>KUtMkH(e0VRmxWQNKL06f4LhNhfy85m6yx)7!e_u z$ZfMHRLjA>h2@XvOYXZzhr@9d@9$IOOM904sKA74q~vlzY0)ynWhr&3Ql`6AMEUS1 z!>=VZrtWVfp$*{f^!s&jIaLHa5G@>u#hMN3ICFpWeJ5-o?whX1nS+)e^XtpbFR(l7 zmkq)w1xU}%&RF9d#iMo)kv?-@KB$h%Yl5@G1# zrEl}N-&E@ZUcW8K-`8QkpOQAp+jTpy7GHcrCcQI)!a_G>(EVK#^jo3B{Y&W^?k6nW z4Yb2wTKsO4B$^{SO5?Ulh!v!Iw|lO}73o$pAEikoJVnXCrmRh1 zq$(v&z`(hG7y!2z%}thI=3GNLor@tb(boML)E9QCAc2T>rj}3`FfeWv`g&=|8Rhau zAWKhQ2tX?$7!FZ0JBhd(8WeXJc9Yrv;OG(6L;S%^G9=sefdh`5{iw&8P(-fwd%d1j z>awPdmz*MW&ud56{f;FsknV8gIjje<^mp8=lUd!(tzbXO>`gvjfe*-Z-Uyh7Lz%G z5$C389%!EBSsZ7Y`o5C$#5TibtBSJZB)KyCsahSe8mkY%-%py%O+A`6xjNnPYWXG_ zF&kezEc_IIsw&3eSIa5!Fvo61jKP#tr+3Su(+k9Rh0(*kCZ4*uSPZyNYI^Q`GbM+~ z!+q)si>SlJTvEj->U?uE4DKpX+{W3e!^2Ubi45N-8k?s`52@hMi>B*t+x}LFI!f1x zO4jp$@xPQEYxlA~?*eY4;$hxv_W6|^ug^^F;{RE1WMn~^750Sp!5tXiB+2X^`Z!Ub zDNkPdhosWBdeID|6DNNlkF=5gj69=}+fyv!($kmuT%w znb}L}F@Q+U%3?J5ZOnp(^b_=&SSiI=Fw8iSWnF@KMAQextbwzXFFCkyVDY7GI14u3 zVPXpX6r4)&AYrx zI{{Gr2$OQOU+i~PSp>Oh+HYo@`JTLBAM!rig4r|EqE99M$Q)- zZ?Wd`!(w(viDr&tukKDF;Gk`VnT^8Y8U)p!b7j11ln}B z%3N$MKFGk6LE`W5NV@SPk(&H`Ux&L}tEz~sCVV1#lPTd| zf1nl^Zstj|JQuJpJR7cyZL~iYl=zqQW+j8&yV3e>sCuY#q*r>@CUCH#*|CCPBDA8s zW?^;{*U2_2K_e38F=kcGt_@pJEoyOhrKt&FROT7KRPgel4oEs8 zLOAM7>XrmM&j*uykQ7o7LQ?jWZ)9j6#*T2MUdAaFTg(i+a~IJ}K-Vzgmv>6PcK{oJM+cn(Z(` z4}^fMN65h|HffzAk&y~)kN8L+*LX zMKrzL{40q~gtN>?sR$X6m`-|>CP?Sx4#je z$8G)_1GyzH6$tX%Q6nduNIeQr2^I-LOt??$UegR5I7~718(~9w5F+j)Eo$Q#&xYBb zhHFri>#7F*nWO-A* zioOxdL&x7X_fO^@33YAN*u#_!Gv03ZZ-1v%Ni0O2cAr8N#yt$?O^Z19GqqNn+uHmR zPCx4FA?&(F+o~6cca6dOgGC$K{%VN&!#j-HpOH-sK#UviIr=3)8?qQETnk2<&KuvSfi^Xk~fO6h#}h&!Qu z^}3Te8uBN^TM9#sQo*vw%RKB%!E-i2>Kd%D^_L|FV+UqU!rNh&L2G!D!fS7Z=G>^E zQslIO2EYWHO)W$xT|BIHo&6Qye zCb^TKsqloG8Hb;L4h-OBIm0mtz~GGINc=l701&wzB3miZ6V2Q#{Rk&Sj;Xr>O69El zgH-=KCJOAW-KGpdX_T*$)r55Qq=wxMCadnpgW6p$BEY}?{Vjp&Pkg$J!F#Sm)i5eFoD&5F zI)OyWdO*x*uqqf=2~4wk!SH;3?Ev=UEVhkk;|L6a3=i(Y;CuySeYz%Tsw!fo3zG!n zcCVT55kvjeDCMvBG4b@S?r0oTD$eM8-R$x?BLrY&iP{KN0+a& zR=;|d#sKEmX=Uq0eFxKBv&1TK|5ik%&}7ZL7>wVGk{@-W+Ev)sjoScn<1N2>T+V2J zw|=~Y&kyO#Un6rAu?H!&zXrtpPKxS6uhh93BvH|7Nyw>S>rk3%+fzgh(gi5LvXyy5 zzFj(jr8{tD$vtSzDA}wMWGgIX^cZ{O z^ciFVd#VkDI1!8w-Z2u%pybNOcQ1B6*gL>_@!1|Pe_8M4@U$DTV8|XVn$JhL+Npyq zzdJfGEk%EM#z+gPKjEH=du|5oT+D2|XQ%}w+>@YhI{&apz7d-IvF(?RBwA|nPqpsF z=2E`bjjB0x!tN#dWt(x#h$$u>aVJQp<#sP+L)VNa;qmBXwk^0EU_iVuB>@Nrg$Jw& zhB@p|J6givp%S6Dy(eD{|H=ylK6W_a>`ho+L6Nt+_<(|N=$sIJUe5X;q3&R1c#H@# zmO%wxgudBNkqVJ;giNjFG)$&?w?w&%#HC!~LznFR<}-qgMv9ZLJ@kTeN-$)Htzc)s_d z-z)($&Apw7{s ztejzg$PQ?9(@iO3HAW1Pkbcq3l+0~r3*;__IMSOz@aVW|uZ=ITNY7zbUIA zWGKtXyE9X8hP;84${*}{RSJ31(16d5XA-`=;mbRX;OlF_^a6Lc9VWrmByxTrwoo^x zMFlSO-fB5Es~H?tHWsN`EmElzV-39E?X}+Y>JcW4;f!+mFz+X?wKcE3}C0gvEvX?oP zQC)h4ZlvFam%I7nl7NSP)?s{|^!&C8F_skQ^poiv^8CG}jewS&u|QeYChO#S<~)dl zHt50Mdjhq+QtHY{u8)WZm-oD0;LwOegmSyFcufg`4%^ymeGe*FTqve`?_PsDqJ8}y zm7%7KzVwn|e=Gfven=j%hODGi)9?;9`VHtg9<}+{0eSXId-p>ax*$-T*mUvq#A?$j2!(7OZ3ccWlvvuohkgLICkKa zLR2zc6h%QTTCWrQ1X^|t(3aDxC-IU!h^N)sYyCxM=I+mOl;rMIBbr25-$RXSWeFeV zqt&nubFR+9iuCX&531Q8^XnQ5gJC*rE9<5{9YG1W9TMX7pw8Q34vp-qc8ofAEa3Cs z1eQ)w?-E2f;lr>HQHe5Aakh)#AD?{=KkyshOC78tB#*c9(%aLbI74^GMB89k#le9J z30-w5f9K6$vY+bpX=_+qWIxk8esx4qBjrPkK7+!G7fMIcAjjq$(>??5BU-Z<&*pf} z)UWUMq#FZgU1wBhvT*r``bQo z^L|4*WQ_dr`A*3G0#-_gYUAbH{Je~GheIU`q5LYOxx`78KO{|gwvy-b_mDWGwvI;l z0X3lRg-l20H4oe4kD{CnX056+Fi1=X(I{3G0;ex^9RAp_@#}*fb$<6(qsfVA`s}=~ zDSCx+0Vq$PF1nmdldRJ;qzCKe**U=Ws;w z-AAG5bNEW>Ukc*9v3hR(K53+7Wajo8ggSfhbiH3qT<8aTcBE+SDjkK_m1F;f4BOfd z0m&MH%R{G?%p_H&GZ6%WZ#Jt)jH1k$LQ~KYPYdw#e6t8z(MQJEf=%zYuG!xAXgTwF zf*cvgpNRayltq=}lZlNy<}Ia5rD}zK<|pF{nZL-vlfA>>bC!yLS3)F*27<{Q>d|~* z5Jj!$(UKKaq_2ZELwq-$93R5MSX}o0DM&irhOxb>2Gc*T-my(bf%x3{jDJ$)vc=<9 z>Y3Xm|JZe9jJ!;5*~dq4^9ibZy-ZG7KRWV`%xdLlMRRj={>%bMlXr*=ZeXPZ<8|M{ zeZxf@u@=bnbJlZ)>7eOKz*6<(#NV=>(ET+HpW2SgtjN|{qHT6MK2a7A8jGuzP(c7rEss~g09c9f2Nv^U!L zq;=4sClrn87Xvkf^E`txcoOqNOH$%dF1vviq|1UZtSV`+U(>m5`#8lZAw(a=^4&R# zLF4^ICXH}-e%1SsvtIy^bZ0o~7QI&hpg#+#?2{-7XDk!B>xZE_#dlt1KkNwJ)2S_J zD1YVoeK_E?J;;*jf1TU$*SeA-SA>S_-j{Y}5ekrcE3ZNkv87{wjxUHioE>RAwf*Ld z%>|KKnE$#eRbmsMxC~)wXcf>Cydl1Dn%&ORwOgC8=$9i5!5nkPMdKbZomL#mRIDSA zf{UW&UBQPTI};BDhZ%d1ZJQa}wr$%sGq#nnZQJ%_Y@5lMJbAx!?f?6_ySuu&)~Z!&NQB%mTebIt zYDxwckpi7UIL)pODbs+p1~z4SM&J35ER#CSU1b|xRh-QJ&JIQZ%&Gm6r%Ip%8HM|v z)yzJ~z@ar*LS_A=ZC!2Uu+&|caj6uwgdoXA$RKA9QI}~dnnprPFjAnvQL1U}IC&Vb zC5cJ_)<`VgNQIscvfJh}5Srfi$R!wbgF?MADHqmseep(r8Qyoe3od5}*KId;g@hS{ zt3B{H6AWQ#*sMM1?Ca>O3@&yV<9!{fcAM7=k!`b}QV?SE`4R;Joev!_1LN7Ck*QhB zZ9htZ16eZ8=CsH^4CevIzXpo zj1WbgFtVZdd|dy=y)x2q4zTz$_3Mq6`=uB3fpv{L~DPXBauBhHOHqFMU~c z&x_cGRbyc$q2*8@^(5%8F1u!#u?FY*@CN$r3bkQjB~rr}s}?1rH04Q`43*!lf_rPTO(o%`W;qx9#PZx{4PK%0cKRk$niwVR3~C~&lI z*#S!21ZYhMAm*tCxI;6BpR)7*c6hw6(RepXIx@BJ z$XL$xKC^JqwhS0bpe&oYq|Zht=qwFlvqK^Xf_U56kbnzrcCdKRW-v}=ov>&?PmBAO zUM(&GenLuyt;r97K>s0AO=?&$=8IZJD*Xd2E|W@YjK+gPIwSjRbr?+0Kvu@oeg%@a z27^bAU74&Yy6{P~ub{f*1M4F0(S(qR%TYN*)ryJ3U{-rpKlosltfE7vESVS+GsxZdx~|sOIh>` zllEmu|HNwZCc^1B`R{ga9!Q&F2N{7Q)T1k7T2u*|g!^GAOnvPV*+s+Gcvcgh@APA$ z^$=}tE`L4a$0>TwmG^17*#f0Fw;cX{7vs*_vW8OV?mH@{7fu0dkGb!>MUF6psDR^P!p~#+Wf{{!|ex}uOD&jB3 zL&7#t?i%>UxdnA#@vLy##-v(d2^KEZy*}A=?6zl;vm;C%Y8ChkMGIu+P61~T-rQcs zFzwfqg?B(l-_>s~hc#PK?^^zdXZ5hXZ^RjmZ3A}7`Y!(Hl)9OUGd^>)IaT-epIpyW zq1TKj`p@g@X?sMGfm*O?3k2v-6=ry#BCl>x`WBB$>Soy*>Ri^#%S<1HH*@nyfl(Bf@_^LyewE}bT? z4@IjjrsuBzmwnNB{rYtp?3=j;_ETaDGgs8I@N6#h49}GKD`v> zCCiag>Z1YcT%|XKd%@%GM}NG~I`B3FZiR%t8nj=EUFDnR+)i}tTR0Qy=e7v6vDrnq zH*v7g0}AGnj+PPolkI_0bt%Y)SBw(rRV1|U5sz+VkQK~wxFh^CZ0nDK57@KZ!*N@J z5%#1qZ$PExuN_(HTDn7f5vbapzN!Lgi>F5M(x+3)zSgeYBCXo*%Qa>bm-~mRHD*7e zt#Y45k4CZPtKF&@HG3?-gu)*>lmx0M5Ebd3>LK#dE0;3A@vHzO$To*Ruhk3c*Z+uC zJYb?1=P7HQf9V}v^_N*&P{OF}(=enC{gDYEes$n;;bRPVnDT!M?Z@zN2XqHw6CUA` zKtWQtqz%7?%FD7~c%B(|3$mB1uD?bAqi&(-7i_p5m^awXF70rOL}>8%>r)8w3zMgq z9i_>S#I2TschzCkpKC~WI{^}xkUAgAj3oUzpjH$Jw8IpI*2C*PR%N@UWWUFuTv{u? z9W*>-CQja~VO#xRJZ_5Zy32}=cQxTVrqI$o2gtR=$}6pxq^GWOJH*`D9M`zGFP&?D z*#`WHnS6zpI$QXAuj}WT9})H4{E_Ns2}=s~tC*P&K~f6@Fyfn9lm5DFLlFM@l)GqhAKN_ZFqINn^Tr{3L=h?Z8THE zt5eUrNI~DX+nm@g80MO(omYBpI|eStf)<|}V3mUtDZdX^oJNE^FYZXE7!{mwcmfgi zr;;?2tpvClIr;wF3J!fy|1lI#|5tns$$f%sF$9?_5$>;M@*tJc$HECI;3FsBq0{+{ zqOvP7SZ2(~$S0&#Z6kgRS+AlWjPJ^(_76kBoIt1Ry!bo1h!7zD%2u$90f!?ejjRw| z4E4(eO82KOhJyK#sLr5qE{+M=%dm$v3EGZX9d!xuq!;?p42?@5X1QoSNvolv^*ImU ztu3?x7w_k<-x={HlcC4kou9m5g}%b(^;#Sqfe)zqaRv7ng25H(+S}@{A$LE>QT1e?bWV_vD%RkSF_`d-DhaQZAy)P-Q79xMC6G$|4H7eG%{Nv3qFm(e90H7k;VyCU!Msb3WYT`Ydq7a?YacTN~C}S56I6QA2s{Gmm)5M9ZE<1E8(Uz<(-#UIZgQB>> zGG+Dze&Vl!r&a}U6CPEGKp>mVzl`Ji#8`>TxLOKECe-|KLGEGxLl;yFU8Pb-{ddc&mdLR5T~5|W2b42W4hB@AO=N`zf62*zyuUx zyl>J0ie8JGD;7qqWGT%<5SmzT#GksqJXpBBn0`P`f2c`112YLcm;%;&(VIwG5dfuO z(#mi@cgkfzt8duzz}R20LiR`pnKm6LufU~XdRpRPVwx{?0 z?AA?593CZ<1iGdswZAa)&>({B;o#{qFT`>2h|p{R(iJ<998wPV-u ziHS?mM!>J3pr6#k9t6fFUG#$xoGHk4}m?EkECYC8Nhqt(LXH|Xy*-twC zSI~}}PAZr}#o1pj`HM}iP|9<{3csPSgdh?wn##%;0zuMsN+EHSQrrnYIjF!SYHoLk z2a1d^5$Xu1Cs&Y0o8w{fAKdild{~sStW1p8fNl>mtsAmN^5gYMKn!9N1|jrzxk6rM zrqmuc>xFJuMK^-GKft0YkWq*FrBJbB7mIy9YDi~^A9#9qaF?a|{xXS-!5A&o1{a)8 z%7=E^=R~fT4^@tj@>$5i=7pS!CTC>ugku-AE~z%2L0Y_iABioqLy@#eEABQu;!aLBrY+s{Kavg!@8hsntMZ%L-SM8kqM= z1&k80Ds?krnSFB{jNuSbTgDS4Y>8%Dv-^%=;8N?Iang#-5>{7P)yOP2r6?>9#JvA; zn%W(*J)l#&K;H0j2Mq$d;naHiOo&m)k71wpABUR(;zthcya++Wr6j8rS*D)$$h15G z+hCGyvwogPd5!Z6&Q$-U2@aq{&}bdt9u>y z+s8DU&@eHE9`Sq=3Z%??aNqJnlwTJe>jBUp``TRDZ^&TsX#7K}DCS;AR~41sr}YZ^ z3CPOx!uN3iB49b@LW*j$9?N>)Il%1Kuk{-^XUSI+C}KbrS_Eowl;^rbN`RdciZI8J z=SR)w82b*!ct6jO{zh%zw4(900aG^s^A{)&%Id;KP-3Otw*KNAu@FsJMtI>kYdSF` z-zN-wXh-$j=HuiCxC*X)7I;okb9mHIMua+F)}(D}AM%iLVd3Vuc)2cGt>%OY!_hqo z^mei3hiIvb^qe${S+?-#hRCmW@Wu?r?+VbR%1{%&@hTlxqJG!1(Xf*XNlA)i`I71T zSx7`g8}@gbW_9sd!vS4<{8eGTKgcv%Q>HA{=j;W36MK3{ripKG9;-zEv=?=~mpBJRtQX3KC_{ zJGzM+#M$#$P{-ZH0RG;%cR!x);A90-VaM8tm4DB#E?ha~C>M*Y!?O-cZ^YX$Mg
)i>T>lVzR#fH{us1rAvHoj=jQN$}2A`zw`Jm8gd-zg2z z6~j6vWr8+X0EB_{z5lm>sL`d$^Lb-kfuVW01-1d_Vb??EYFu=#&??^$MK$A5c@YI- zxT;hD;!TLMvkC!2h$3kK0}Qi-)hsX_NYNTVX8#Th55nq4t<`@w2poOK_9Bd-Q(dacqnk{4ea}{27?7UxFB1m0gnTE z1%xBK6X)-xpb3Lh$7R0$V@Cy58qXJ#CB>3gJSscLOAfLd`z{!yL( zZT!}WDN@SNVN|Cb**7*d1s!jw*8)@}BR7I8jKA4`=b>w2bpjVQ4*oH)Vzxyk3HA{@MEYB@Z3$b+-1$*wL1nkTppzajTOMS%(!q`48h8l@+`o$^dFZ4zV=9x`c>uYL{j#*CC zPuy!xD-les=)UScP5MN+`vk!I{v@Fv@4)OR^9GtmcU34#9CzB7z}UDf!3X-u_+d>r zn!=GpTB~Ad9)5Gf!4vISem|BQfvv5CGY{=4%u^8+8}JI4q|Yx^3>1Yl<=Via{ezHwlZdiDn*ih;_NOSrLNLB;UrJz&;n&NU`=WmR>=kCA zj6;@|)%DC^PCFU-Pwj=)g(_d4qJP6!riEXrM?6XkCMlv(I;#!N2Mnh&B~C-Kw0rFs z9jbD)K9X1$tUp@Y5QUpu0#BKyu}L&$ZPoOpELvf!-(t$h#rZXAp2awM8LO&g;+sV7 zjV%(HsZz9;Q|;JV%<~gZ+P+rDt{4)S8Yp!Un^10eH1o6JG%K%O@h_ab|C@3f1e{bN z1beI9A!O+;gN|WNJ0zmz#Ca{G+df6q2uE^LLTWVJ|Ln;W+!v*{jwE*4{s~~>dhsQ; zYMJ?>CTvm{!u|q~3=rI+ziHGX=Y?OG05WaQ2fsbFMWC@H9Q0KA+l*N9h^{A>V_Q_aNLuQd3Z> zdUhobz`4(QL0MEEBSxbCo*8gEI8)_RpEGCtF6%xLOXtIMy2*h%L8Q&g4t z*t_M~nb>RA=-&)rwM@YDEB~Zb^NSv(l5ie-xOPgsGSt8vjmwx15*aA+j0BZ#o5ga% zI+m(woYb8`;bgh`V2Y(;UYf=te2wy)AqnaqDC_oduRP^areDItt5CNFF7mksOnEPQ zB*a>IOG9O{G$Nuxb$hA;3HQcEKgkNy8(&>c-ToDP=f(WT(&|;XkcG`k^2(4;2UktR zfYV{B3h>CnPAW~YinZ`-62ZbQ4IP$%I*O!Db|~z<8>YS*0)y%m+XQZMkdiLS2K7u= z12a}WQhv5D8@xujj`2D+YMl^@cB#L)oUIsWfv~b?vCfOU2Nm`wmXQ5(rw@KzMVg22 zaOBk`6aXw`+q;bOci*6@$8t^Ep1xcYKWjhs_?awV=&aH@fDS1&ne};1$ zv00~OcG$b7=xjG>!5KsdP>Ta6kNA*-&-v9G)kf-Hmj;E3#UzkngyzD%r8* z>n4F2ub%YmEH95}^T&Ua))y$d`wPmvZr&UI&kG<5;gKvUG;ao87QWYq-OAy^n_aO1 zQ~NFCYl0}3FTBf5Zs%6-9h+vR*nZ^wTA%Tm1Y8uq+F?RL%Y&-V*o zbM!CaF5~yw&=Y&0z6eCg6e`OI9OzU@idwd}4&S%z@aVUQHWM*#%EBF48V&0H00!>? zY0*Zu+jTX)0V_RDsY)vLaSclWO}frQzxYSEzZ348-q6mn{*6~6M0LtXxfQ^2iviN# z1%BG4uQmp1?@#)9u7JTn8w-dpr1kntkVAfEqZ*4p?k zD-N&&C-uUd>m~?Mlr<@OjuAfnV~%JgXGNtQn5;1)NwN|JNPo=l0fpfA z0glfX2`~gL2A1yu>8F@Us^>Q;{iCGRtFI>%hYF}JTBxZxX+yJxplL;_j(1WE&Up*z z+r~}3uu@y?f{;(&;cv%GwRm0iC1oIumdMC+`D`e z&(&2C{#B~(Fp7B%Ai*E1IO`xORT5CI( z&MYcLv~KUq8V1LAM$@oHvE>+P<8(y2IjW!omA6R7EWcBqdS1^ zcU`es_l`?5+lbG6k5ZbH0Vx(1KAuAi=9%Tf{x&*mVheSsD7z~U{_zPAWvjH!8vYn( zcQ_8fHzPr}3PW+PRcNSdMd?GAqO{J%=$|Zrn}{;2JMSH!u@vzerxwFx!ZE12g|(7i zn=7>ssv$@3CKfTSN5lISFYWnXjX*0EFb##6AdUQCtr(UW5|tju5^KFcT2<7HAQMs z<2KdCFCbVtis`J8_+XOGu)0#=IR`RHD;y7BYJ1$by3;mNYI! zv+f8=X_6XY16>FGpg_5dhyW83!VJLyZ#AKZsDHs_Blh=0ne+`>O+j|{9+7_n16(+b-6-a^M1p@;RSy-0|l_I8;;27E{wlXW0z_{KlyK4y_Dpvs5Ro zlfGt)DJ-d(6zvI#g3dxJJSiZe!O>jfocjRp7^*4zNzKaCgVpGDWQC%TaH72b;880r z<*WvNcwCa=V869v0ChZBbehWdXrnjLK?H+(gXNgO#h6I=hH$_{-*lFG@9Z{WL6;84 z?ITQiby&vglVQI7NxHoet%4v8rb*i-Z{^Qp^)7}LEE6G;`5DZ}+m?<<+bGZz2ZVQhMS<+g8vWqG{- zjf7^|-P>Lh}AxPc$!o0vV)qRzzrX2DJFS7_5GxwSKbE zOjc1ai1%zvD0aGL`RoR+cMNO^!gW9T;y>X2TZcCL-+D_^tG2x|n3%9Tc_T95a|_bN z1M%i1eE6N|JOXClwf@06UG7l?EPa3Xq%O} zbokfsrTnZr3A8%R_P9aKAEs4@fRwaix+*_{NRU1>o`+oJO6SRufQFgu;n^HUZBEvx zZ4m^bE(L9O+5rB6NXcoSfJy~|vwtYnzC$Umfj2G%sLt!6oX(T0?vjqlp&glIUVFlO9>&>~ z6D(anqZq!YAQe&9nf|=2w2%dICtU=C-$rpk5orz9%m*f)GJp#d#8OZvQq;V>Bc0U! ztp2a4wx9UgDKeUb8PT4A#mAe5yrhMJj1$!}C=(&BxOLp0_h!@E@ae z7e4k}XeH?Sex#9Hy!Md5WQ1g@D78$}D+=~hzYYjsM58JxX(XZa|k8hHv&?&OCNDvbf!ouvTs>|`TM>{3UN`-85dDupm z(#R2q!AzM;(1uS1!t!2+`J=(@7nvrmWvFA@D)=EGBzTehNkl5H&{#bKP}Ik3l=^4o zfdwAu|EZV13d!Y?zon{8qtO(S;1BJqMElq5(j$6wyz!OZ3m3EAAj4sM^$8~D*x5>B zn$@YSxJgSaokC~-R4MW5B9*(`WXE1-n+of@P~15O7&bagiKyLt$a)sLx@p2rX%0$M zN6Gg(1}FK(*q%RPjF!nl{`@#BC zZffWM%prD9mH0}?CmlU$VnTBZ^FjNd2^^(WW-DO@x%Y2jtc`|)rMzqas~7l0);ln(lK)dLkPP{ zj?G@Dkvr?z|7)&)wbwzRou?rLbEsZ!r#_MJb4f%X%@DNlxHW@TcniGIM8B|%G6 zOFn(t+)NbODg1>NPd|Zj>$p~gC2H5BrNU#0_{BW))d{AP@)eb#RiJ;+s%{WC*2p-r zkU+Dy2%w-8He~2>Hh%d;{-`bA0dlDKwuf#_HirxFZOzinNQ{JTFVdtVzQ7mh<>TL7 zkdZ0q?~G$zrKO<|sU5N$1IhIQ61b+wV8yST!r+T#DyWDB8L06l^8Llod8J!TE(uRc zAP9{xacGoZ5d%g8GC1mL>5+r^AQD`P2F_6(wRSguQPAAjNW7G<_YZ;CDtr;d!6x&S zvV9EoMi^HFKG-STROwW>YuEs~ui-a(QyOaAm?FeHjZJJP~%SpNBA7 z8g75lYQg^Se3hLkTrnqJ6ZVhJL@{ITlsqC5m2T%%`~NDAJ-|sT5YjF`F>2_r`Z=+Z zfk`jW^3Q#WMa2gP#OiD$88$N1Wk^GDd&HL@0cplR`zLC;9y;?IWg&~^XK%7H57>1D zYq)flye7~U*DM1Zc2vlF3$=w-VXn5c=L9Y#3hKa;6#hraXk~+B zqY&(YDx@h?wg?>G74kh%cn85&;WqW>wCv6NJ~RW^@JvF||BQroc+U5`A+W}SaXj|` z)SCoiahmHo_FmubD*ZWRo@8}H_KzoQKt+q+jOm^Hx)YhG2 zqaZMer<$^1g`Y1Ff-L`wp?WX*1E#;vg?Jj5f@mnxE9)P2B%XAbh=Is*=1q~MAJ4aw zbs%vqPSkF)vZ$ur&smM^5OU6L*&3@^EZ55;vPQ9RB0;G+GLM#JvdvL^nNGMdcvcJ| z(n_s`=Mfu>O1yDOikGCL2@rHh5mS9+wD@7(l zPl<>neO#dpHb;2zQKmRymN+E1A(1uA2e3(oQc4vCA`=mbOB*<%GR|@qPmg9j&9q!y zhjugn<0)4D@e~tO5Z`zC4eM+NQ#C3;eT(7`G%U$kAj&NLj4$q-jfX%EqiEgYEFkz5ZQB7Vv6;fN2YY zDi}_X2h3RyUKeBNYYs;~nqAI$D-ZA8)Sk%?gg3^{!Evg)Y%&TiArsuno_L+c_yC=VJM%KP&aeBR;iL*zE=23%!&r|M5UvzklmmBP1SJNsOBS=%GWF`k4-rAhp zFYx&y1)1e!f{qw0aq0aIDc;1s?ZCad|K`4{@OWd^JgT)q6m$FMZf6dyoe6@ALSWd9 zT+#rEa0~wuYAzY6fw(!+FU=hKO9*EdxsBvnhO>>da|P+9eCw*y4rk*Ee|V0*OVWFj zh{y*?_?`G>uydSmubwN8J6+U$72%I8!W;ZEp{E6MOH=@g#+Vv9=Y4OU~etFz%$DuBB#`>v;?N z_WZOr9|0y5qyavMFX&Ah0*KNq6THA#s+32Z{j*n#E$f4tD)J{(*mx;js(;A9C`1Tq zw`p!tl?W^m07>24eRy;_~8*#SOG6~;eL)NZXMb9E(^SED{$(jVta0pl> zC!4Gv8d<*AC>(-~rP+xXV7}sW20w3vmva4$G+PU3XI1|=XExq0wL8?!$7*8Xk(h#h z&HajFRfn@RC)o33;eOgHTJK-$<PXE66x|} zLI;;7#tD?d@2>sVW{w8=!`cW40!VtIdIz$>1w87KJ%LT&q8@d;UUt`X&fu95DA-W|PF7u|l)yT1u?eD)}4+Q@wOM!UpO>(%r3 z{aBL+Lz+xD(rXlZGDzBs{d^v#{$~Bn>HlO62v=wjPV}0q3Ors!(y-1%i$#T5@J>hs zXnV#Ql@EO4H_7vYkcU_L@#HDZml4*)PfG+epj!YOV)0=;gJw_oIdz0-ZEuhT^zMkV z+iM{Xj(+0--;}~B1KLNX%1Z3LXV?4=H*8e=jOtEMNThC(i|?`K6oYZwoacERNU-1@ zyfNX2@PqyD>86UJRq@KK!j2)|wF`hwG0%q=NF90CHNf#od}7kH{=IDc#IP6Ibgg=`wN&F zwVcM@6A4UtZu+hnE*S~FvQn3*S{c^G3aN~!0-_yCRh{&VmU%G~E|9YRP{VTh{Am`D zEJVg9Hd!7hcvrP_8Qlq;r%7*Md&t3xNj_f&=bk+{?g$=H)g+rmO+Da;BD@C2yiycx z>44kz!9DT~a#z=I+6yS%Svz@ri-2H%wVDu`fRC*I{B4KO09bH2D|GH*u z1^gp2>U++v?vy2wX#GBmNM}U)d!mXaq0}V0q(af2CoUiawydJougwh^J6PbN2^nMI zAlfv^W|V2>w)JF`;i4xcahyjBmKh6}CMldesHzbML}>+4@bBC+O}9^oQ);Lg)mV=- zA*f;s_xdy#xY*LFNv8R(d*|fg``;2#!1uPyyApLq8w3p(fZdII{&vm!)Sa z@CfG~eLUiQpqe{VaOCx)L(y2xrP)v%-`Fg+|=nbVW-} zxKT&P{gMT4_Hhzuv=-9QRM7xikO6z1qKqvijY%j&mD!G#pMDTV(jP-ccO(@i&$yx$ zGJPo^RfR9?eL#idnJqn_X#yD)fzl4Gk`EO3B8>A+rQfQ+%mGscbH-q3eCP`z(C9GQ z!BX+o9%H)C;tg^t$QjKtU@hZF{Gr%Iaz&@_*HX z-rs7LRPM^~$^j|F?VuOPiK3KM9u)BGldu#2k6ZdeK+w?6%MgN>0@Cux zZvaqFnwdQr0fLr? zH)4~)uTIw1XjawQiWf;mrW(_+cGV2`|2MYe1f1j{1gCEfW+spbSO}mc)i>lVu6_z( zaIBWRZSwMM^6F*Yn429tS~F;&*h$JL()TCD-~%hLi|P96^4i2~aGK$yJCW?p5``?$ z8$FOM^gMl3Jy!FIKGCFKTp}5Z;zejn{SN}P@Pcz5fg;UQkaMhc08y%*qoO%U8eTQM z$^>u!$?bZEO`x8*`uLsvbKcBEHN_36dvjs91hy&3L)wwPcTz z9%=imt@%$=Y@Tb7)9sGy?RQz#9H-d#T+w)IyAe6K9;yS3SNQZJG7b<1mjy|h#LjF& zSr77&V=Y=B)N2y3Z@t5Jy{KINM0JMpRjM&{y)FGDN87|WoFL01Mo(l6S@MQ-QNJzg z*suo}y*-;SHo&6N7p>_g^sj+jR+#%em{z>(`X`pvpO$6!rCF)W6AF2@Vp~YvPwDBZ00pcWT&^Ft<|Kqw&>Y z{zmQ7aAT!@F_vDvsm+ivTE}O(AK>~vm@iKun41EF@H=lL$E}in@TH?E|0(Nc+tn4M zSn+=OH9oNeqSNc+WX+vMq6_JI-JW9{2Q_S?sR0y-B+#M8^=_`>lb9F$?`OPNE9v{O zBI2B=JNN@zoL%@mG=}1zK|~{7Y^K_s_vdz31wr7gnEx5b$nunGkgBmTK7oxpQ(6Rt zGB>{AP4h*8L?PHcKc@m5txb&pqKcbD;>!%j#`i!l@z0h9^Ao9(!!Hb<^=fQDwz~7o zEAibvo6A|jVCVBoys~}^3{x9uZR~m@n0I8JMaEKQpDj0y@tIuM9=3}q=U7$yQHvMfwBSf= znF+dWDjf*RHK-2W=KVu1%X~ZA$h+Z3@cZoF*560~R{4Mp*CDvxn~Tf5qBU`XFI|6v zWVpK{0u!AjAyCC%tmyxtKbd`T(l;|OEm#)IZ#@Hp8>Wop!$eaRfDrAVfOiQ-ZqUlm z@fJy?_Z!$!B3ZB5{Vlcx=}ei)m7hIdZd&q7RqmQ`M?v**PwGz;JdV4p5GX>a215T$ zN3tZY5)6u3VSApUgKXx|2B*s%K9Mn*zlENVy!Gkou0gUDv!>6Z9?`0TGRSbX`w17qR}Jcx~GP4}&q=R zt~p*Drq5*)D%^7m)T)uG(`IJm2lHtY-u*P&|E?7f_|p=EA%IQ0LO=M-hd)u> zarZ<%*YxOX`t-(rPz}XNj%B@Ab7*s3%Qd2aVP9U53b?o%^q!4HHv)8>_RTokyl+!t zdOuCKi{!p+P!YUprk$DFLpHH*S8TE1+n6U~jcM{5A=3hSAt{qND#FR~A_5W~TEvng zCRH|nlUQl2E(M)|EtaU(sT!uz%GJAG|(1qGID)-uxkyRCan z4EL3^QOF)=;4SwjwK)L-RkrNea1}mR-=0Y7)@9Fa^;7P@Ro$$W^mfA_!W>qqoq680 zDMdaGCjHV}T0Uzw{l&zLx(+Gcse&^l6!z|X27_=GbKO<`kw7lquBc#RtH$D-wSHhm z?tH&VJJl6SZ%``-k;s#l!4`2inIl$?-7q0vJvqgE$B^shsV;*?3BccXZ&2mK-37!JtslDaWWx6F+YnKv*1g*_P zkr5DiJMU~-jqs)}P9IWcU!dj0DlJ~tNd0-F)LY^&7vPl)@^0Gi2o}KS+M8Du;zfkz zcjaGj8kFH{g9&_BP-{JBJ%I;ATv2SUCXC=4q2oyxu^hOw=1)10&o$3wT&b3Pc2#gq zw5s6{bJ(5?|JZ?b!lev@^Kys6ne>Cwsa~pUq(k}R4O|7?l9Sg#RE!}AuGq5?htgs| z0(>GOcIV;8uJdyv4$M0%+?WLL@_rW+Pr@J+U^@MWq2OS~7}~kr2+cUP`5Xv`4~_JS zCPfxMq(@fsbf*OFgj$Ham~z@W&wsuO9x$a zPeEe#Z#3T@8yi-Vi0Uq#cES;bKALogOHjYy_s%)~m>r|GU8l(!MMCEjHl{#(o`zkQ z!W_GqRSFHQHw!X+h7TcKvq?#_5UAT)G0${~C}QPOhN+IkgS&;3yQU$)=^tg4};?CP_Y31al_ z`#j_uQPHX_g(vH*tyi6b1O^>&dy}Lf7=)B?A_ON-JW^mvl{TuVGGz+C?C|CPd|U5l z`*B};WH)J^S0U$f8=P{drCGl0;z$DX;ia&WqPFB`Ezbkt$?|wr1RbRdKkTknqsq1d zc?O;cW4gU6Lv_k;?>=q4f9H3LW=wM*(5MCLr0uaHy~O*JsLNGWVr$~?|3fMU`U%;*Xwfr(bxbA&V_`CGXdvjb+MB+-Q&G$WZ`}nfs)b9Tih?1 zevi+v**sU~qX4gyuLYVh*Di~Lr_x}3Xg>!K=kC1|wTVN-yg^~EBE zBk5pCnLIN!0F4`oYcFfk?HjNY98Ms3?{Hc)E#c)nqFNv-@6=UK6QUls$V1VCGon|V z@#*xF4^r0m_OK9blh-C!{63Z3Jl1-xzgfE%OhxW*SGIB<43zpf-OplGJL%4x>|?KY z`F^W+{nLMLo0)anXYD^OExMXly?GplrV${9$ew4*S$ zx`Pu;R23bBw%1&<3iM$*5EraxvD|6_AbF-a}$L8y= zX`Q13Jic{ld;Kdg#h(^O;=eydz$7wVMT?$pYyv)S?>(r^pX=mu*Jq~hTNnJEz3R^^ zFCl2V;y=xDLH_Jg)Y^dz`ic{J6WA~e0s0F?BVDtJ6r&Phu6`7jL1Iau96KtXGhgmAB~w?78&5^h9oCCUP~j9f8c2VV9Dq|blmoChy*{pY zO5DZT_%*_qzaJAr#WxsqEQ9f#&~!s*PUtI*dmz8C>;Ygrzm|br7hMPA#AFNA62uG6yI~tH!H_-DP68OB}te)j5!I6|9r>QwJOc zx=2oB8$8zf8t1zbF(zZ!Eq$;Fn~*|bUJ)ru(>1Pw0nvWUitEKszA>izKG41rV@(vx)UgpC5j3 znQ$<2%3^e#B#Fda2nxs_7-7AqOplHDeu0I;0(=(^tCA!WmuR&_yH;RXWoJ+Cqq+jb@n2}!dIL@I4zHw6FkwpjyTtS zuNFiHI8qk4dNh{tn^Vgu=|+_uolR-o+TvqNO z*0uJWeW&E2s*sL3ft1xmT1{Xi5ny}+ysEOAa$%_$zh>&ZCYz%Qk?-a(UBrZmkrYWh z)9TzZxJ+eU1erKqZxq6X*xZoe&qgpoCNOn_kR$ODO3h}@^2-jeObs0+?`8#XkOpN! z#I#Rx3w!cUJG$hh;pLQO%!-a4In*LG_It6`V-JYS{b5{g8ZaQzc&nI|1h0WdGBE2(Xe3j(Z84;8X#Dz< ztHX7@K}>zHo6v&k9+-t^2~?LI2o=p<2)jihl`f^j&qlO!*)ILWko)ZTN}%g5M3qs8 zsAKLtOzhihg=k}0!<*;kzPSDlu0QAL&SsF=h0>60CJC(QC#x8Aw^WDAJJI~NtG0@= z?ZJN9v09y28P_#6xb0jo6;51{+FHNsfQNg*sv&x;hY>{fi(cZ6$aR3 zS>HiAEzjj#*!{BO1?NThTm09DaSkKy?=~{)B<}!4{74%&NDC{W^Wj_GvHl;4Mk zz}ENU?F#=odsiRUUuA0-3=OI?EZK95W<2uOmp4qDSRBhJq8p#BYftt^xYh8i{+)|A zLG{{o+muEpF}{ba36tbyTo<10$sN^LxbS7p3GVXYtA|@%nWHP$!2jdv8`$eyyKZCK zc7q0uZ5xek8!NV*rm-5^wr$(C?UQ!D-}wXUde-eZFh{e_c=c)`Q!Wlv%pYP9@|Kwv zujfQA7S}4(YS$#2cAwn};uXR_GqdhHu#>0d$C&p4&wQ4ID%?@#_NQ@|xTV<;(fIQ- zR*NMx=JHH`aq+u^2&QP&-)cQ-$~SGRn(Y%ufUZSLWk~s>(HX z)`1~~42-l{ z(4*5}16CTM3EIyAx;(jSuCierp$j&2r(BY|)a=tCc6vVBOZMQyoRj@= zBL)^LR0@0<85VwomXLgH)?kCI6NeCj`pg;g%y6fWOiVBNy}QYsI4?ev+B3Z&FU$<| zd5(*=M+YZ0AE!S$vg*g%4v=LHBQ@98OdvZ0)JrgDF(XqR3$m9cI^>H>x)7@S@SyQ_ z%^gHGbdwhgMsUQ`)I>dL7>Y>!2Ir=i7D9Dqh2>N*okza^s4NP$b9X;0Vs(GL&!A3n zdg=Hnn{d>o-u3taglyg8Bng&g(ud)>%Ww2j_^6Y zHjrA73JzcBs38K|(ohq65Uc~X%Qa-f6TtKtviQRi3w2$*KvM{ckm=egaq5rWjk+h> zEL1P-)Yf)20~RSD*q znhSHb&4K6Hk~u9h@?#<9r1{%Y(+fl`=S_sJN=>0A7d5p_S#$vAe6zB`Wwy{$u5Y+H zFcDKtKB&7SMayR@#xN}B6~DM4kD*?K_38NLYs<@^+;LxAj3vNLV_c2Dxf*#e@Aj7Z zWVk>8f5_}+4g4PN&iwQZ9bbs+-2DYjYRw*mOy9gxUl zMlcjt(vZZ9Ia&NzxE;|cHGhyROuwq)XjukEe1tEF-BcN?Lv-%aPhS#(Dhi_s3q6BL z(i2R3tMbS--@mpk+cJyEZ5K`xhFh73<6i`X*c z4Sew_v2?eeYeeHD(r_TX)x>^N#9N{>x8I0y-kdo?eNVRG%=?JrS&^{wnaW~US1zwD z6K9=RLD9%iS1tQ3??92?Z@D=uv`gVczfd}RW@HE-At;2UojSJ~$o#3wv&+e{RJo%h z5YaD_fzRt}Ns-&_D!Ts%Svyf`$v&!I!dn!zg$yIeiA|QFAsfRat@!?*x<-xS{<(}`QFg$NI^<{%2!CBJ% z%2HRETx1K(-^K&hFNUf(;Ih+$w0Oi*xY;n~Xt`SfoIXk=F|n@w>)_$bA(i9KXChsv zi{~8M6d6xuG08h7>?}rt&dnIRzWhAG<-|E&*nKLk=&+YzbEz-)W)@ymnqvq%4-C-I z)|kdA7{C17g6F{zKdPQ4E$Rp3A%dfD0Da?ercA^JaiAzkaF75DV4upKwA$({pm&7) z5D^VK8$Cw9xO-cZd0&4eTx4J+uB6#;KB%-_MXNTyPWvj2Q$SwH`BzwpYbipyV@j+R z?23BLRP^aA|6C7X{TdZL9CWpGBM?pZ^OKA_+cQaG>&pG!l-I*%Vq*ps)k~87oj-SO zh&wX~`W_B}U1mEZ$%YaoiVAAxV!`THhNB89`?T%BqEmwX&R!bx(mkz>ZK-%HMd{?n z#Yv7%W=lR6oJmkosk-O45C{kcC70iNYV#O_D#@QmS4}s=12??lcDU}-veMPI39i;4<*rpsyyMG#m z-~TiPyPZQIkEeEIqHnCK7@I7{6!6dt?!1s-572TAs{X<7+JMb`ecdG zya?hoW`t3MsSKOMOjuR~B-GwkwKXO@O@r_n&6%nf``X1IBOGroiCdp@W3;MDijF>x z7ED+iG?^2~zr4YsEkid^^^tQh?Vux+6&M<*`NvpOuJtLyHh@h77R-{SPYG+>w`1GJ}x&`P!?^2iWHG%}Mx)h#=mTKC}HD*i+iF z*5=Q+L6*7(28TEpH-2u?sn(xAk+2DhD_-TjGN_86vUGX?QJ7DpsZ8bsGHaVZ0A~xk*DZ+rh zj&k@Ra=6Q}%$64cHH_HU5k^eAnNBgZ6&N1)yy5P4P(c@KCaf$i;*rK-Xq|*77O*6m z%*xOl^>{}a41LfZlalLIF5-p$@WdbO3#HdXXN#bxh<*OmPZ)mec!OR8ySJ9tC+wg@ zQSW(moMYdbv!jt-BR|Ev3?5ZBW5~qmJRxaC`_i2!7uEgf>c`1Wl#7!rUz?+inE{BY zhmcfb;RW96Yk`k}l6IiGuE#L|^BaJf3uw(-T~Rq_n;u&Q8r+s5siCrVs1ry-CD5!3 zDi-1t3eyttG0NP+OTCm(5{ri;&fVte}&F(U#i^%9*=@JMS+jzb2@Zgny z1?@qX@9QP13k(wEzjSFCU*Yvs$yXE`vb0?rr`1uPquTjV5KZ_@;zp$3{<`t_3phDX zPoBV#VhuY&Z_gZaYXsP?wBq(rpEi~p+CWX%rywq`KxsOxaZOAgjQ||MYJC&o4p!kxSit7 z+bDRN^n|Ew`U?ir+y~sYVk*s5Dw=FDSiI>s7o1VY>TpW_&*wT8XU?=eU%9PgZkDIV zfzBecaO@@uD$Zj)0U3r#*O42+K2= zCi(-+u8%AXDEeHCwtL6}*B-5YhkrhJi6MIvvm&h05&3nrA?9Q=GgvpAdF-0>zLny% zyX<>Iv8Mrjy<6%U1}f~rosHKXbp)uPcH^LSCab@wC?1)v5m+#&N{3B+OPE|*b@4iA zF--Dt9P9E0X|t7f+zeXbl@E;b0~)?zXvNC3+>q(YNTf!Sk0{o1X?f8n-tVo4=~uqa z9S_w~+@Je@3cEg_k-S|o2EI^K2>FZ7yG*{^KZ@%xMnj0p;YXh@g}RG=-KIs7uIVsd zn`C1EU`I)mU;_@Ifi}J32hf8->#}**c%HM63qkQ`1zc3e!(-F&Xxz9O!a4?eu9K>g zGj7aPQ{3Lvb{wI5tZm4{wV1SM=lc7`>obQ}yo2`lfXZ178!Js*Z=)Z0DbWLG*7yzH zu=YVvWBS=?c)gzn<|lK>;{lO3fEa89_jlN-*3S4Fd`OnN}+{Y3+mlfT38_bgLtG zGgq*{3bLWQjyUb5OQmg$*)DceBrArB)!-^f_dttKoVEcrLGtu^G_LYlmG-VI*Nbai z&18dU+T=!KC-v#+g(COCyt@-P0Sw5{dtJfp*~eL&B;U}nZ9Jg~(nlYU!c{jt^HO5KCm?mPa{ zqs3#L%R8(8=%`;JYk{@s**sYJ{_GOo!^TAFR{iSV%XAVJ{9zo@fM!3y|0l5s1G;p( zOtCuScrUu`iuhP*xkCS#;W&}lnV4xO|0CD#q6y#BgYCq|YRnREBeudTQ^>_z(<)HV z!en3|%c_LNs+axcs$mmi>!B65q|R^#-O z?fU~O?qr2!Q##nC=PTza|ZHcd-X4i#Ci`_x?xxgKq2aeyD9Y+Q9jSl3Q-9+3Odn&|?Ab^5?@J^8BZ=ku8f z4|7%uWX~n|5Fz6nG5NN`l#E%`I~cY=HSctxiJ6YrWfTmIzd_3#$=(6lDR0xXUzx@ot9`QHjX84fYh~ia4M2Z@ck5oHQ?8 za3^Cnz1(vOtkEnsj|LyDGv6gDSv%PP9*wW6xR)2t-l>M`JT;%gU*rRDCI}xj%$ELI zrwQDWMRwY-e!$9BT0OUSK+EVBpmxW#?q!FNRU$c~IquBFgMHBVo@iu*BR}f#!hB#O zR~YXcK<<$c9% z0q@l3gJpXD3wZd)x5E7+eFqxhX&9ga_^zI+0=U?^I=*wDrY$z2Nr-CG!eL^AI{Z+m zn6N{)0#DF=uq&D2kx2i=F1cs{6)zj~J5U59YNiMX&TN_mDlI%nWd`neKDFAsRDpnO zg&eD{%nk@fGf_%kfmua?-Z=Kt7^@KdAch!!UuXM|WS74$hS{)CnXyq-ceqs80lUy-J+#rNr%lg57^jH(!Gk z-nJqM@R)|rBhdCwcv?^vgPsv)$XP4tP){vbg(Gv*Lcz>-+1FN&Xi!zg&ZmxEYbVq6 zUso@Iz4l1{Qshj$)y6aJBev(j%6Wz6Mi|N#i^$W*sa^=b#?SXdmdLzs|64rm0)7qJ zCO#^#e33Z0n>6Nc%>gH%M^!*Yn>$hH?RTw}N8P&K;sIj8O5jpd^KtSfL^9l;(G3_= zNK46;6P3r$kbjgP)q=&x3T|$3zY-`dU*6T*UqTL?DN z*cvAE+Tye4dLzP;1g`t_+|Py2)I&_^9Eo14j7>Y$5tfj(@>D zy9qc4n*NSBT&Q0l6r8kFw80r%uagqIM#txMvxv)4ei!o37qc?cnzf@r?u4I>l0^_| z%mN8Ahe1_Noq#Y4?Y?X*ICfG7Hi??7#Ij#YU21$dYI+Oyc>W_6UVzL z(?E{a8iaj`X+ug`$Rd!&qo70|$p{e`d%7A_iFIs6gU&I1OxF`hrHX1J2HFDX6S`_$ z4~qr3N=i5m=cLn5fl5Tb#E|}je7RRh(iE}xDGZ8~%Gz`vKcT^vauwh|hynLAp{p-9fs_R5i^#*7-)O=)DM^*Pz z0fvMXiB91gWoUxLqd6_#m!m!e6#N!E^cCg(AH{tE{dMXv4EdnWK>&k)chgT3ZEpBF&l0X|1itEq11E&BUNO zFvJ^HRe^3mwU7$m5x@(+Fz)||)u6vDSR@q0umCy~K;2WLmWT?L^kbCy)>!S8nJ{#5H+M3d z{z)tNvaT?QUN^q@qTWn~MAlkksryzYZOJMTPdL( zLf))vA238}Z=2s|Hb{$=Sip#%islOUxSsH`C1k=b2wLt^c7;X8%OMvFGZa>{G65WL z>f%7h%~etvT$zZgLVP$eO==0K`R+jPu7a&q&l}Z!_-9{)H=|6Cg*7Ub$T`9yA=Ngc z)Gy|PEoZmyW_S=ROLdfV2k^Peb-*aJ470{{pL^5NY1|apbFnr5L zcecPtX16U9+^^&R-3gB{U)P;)7k7DcJfzO4K*_Vr9pxhC)DD-_MY?ej=3)_TcOlHg zEfCVa{)r+HP7&dbh#JR$Oi25dKSceyEOVWtKR_raNWw#U!-16sEy?{r#=-~4&4$an zl>3muoW6y>5WEOhF)rxVy}Y-p1_=Y$lfnFG`2PAKVu0y?i*CZmlH4K&~!Nz z*UH3x58#S%*_NZH=e;$R&*bXrb$(CmQ#*JeT9IKCD^^a6rzmCEFsN`1&LJ2A3E*!W z2?OYD3EAIB4k=b2F{DugwUm~ZY7jLBs9J`l2LWFe)lIZyR9yuMB}36_ri^Ps_VB{Z zRG7=)le@AjYF%4Mei`J54$hNP*8l&%i3Q<9B@CShtH!~6$z!nnzg_?yns9#dI<;gi zt(su7iU7H4f?Mq5Ur%bHu(#3jq79PecXAd~7EYS|9qaEO6adG;Tx=MA1;E9wMj+=h zATU(8v% zCwTRUDLvE^ZS;1MdOls%nmxDh(e=JBA$U#@3)?!GY2EaY@)Cn!_P)!qX>(Cb+H4aI zwIMV%A67M&{|zuvq?Upmc~FoAV9OM;m24}%pAh0rWAsPQ1W>iV=DO57crBZ29L(CE z4DsBE?f#hkZ-0pXCD1rt;lLA@!qR|_$G{V~B%&^?v7YskP>EtbqQn4u!wNF(jxwl- zgwD-G36d%6o;@5ROkUdV=eV{YO<40sLcJ$^sftb1;xdbtih@OtcC^4v^6 zvWj_Z$fZtd?uu33$Nbg$T|MXjtqBc{*wd*s|CkpxOi#VgaA2e9l3Y&Kzn#;rTa26C zlz+=N41BVQpna&--ls@YG=%L@Z{h`%13%uXyb&YntVDk9$4hgPasPgTV?F_}3>5jz= zLlOZ)^_+nFqCKk86kwseZzAz*iM#R@Kj)6e4@#=fXvINF{}K$$M$RyOjT|O!pLe1+A_d5YCWo3JlGvdpg0nF7grg?>!Is z#pj_WA|nzQ>xFL%s~rpD`1bjugcuklfTI7ddfESDNBjU|-8K3?6lt80xnY-gi9PNo zqO70~UVzu__=iP|wXp4r5*p;`ekBE+d#ET>S_9Yjd{ZS{SpAWqIIoCwWTIT(D+#ZZ zFxh)$2OxuR_)h13U$f3Wz~}Pp8rar-f=^kRMWSNsHR|Zk_qfUH=h&II_<0ZRvb<49 z?;ZOxsAr`h8LA09w3UI+{(>7m-`g7^5x3>Y-hiuvN9GEi>?KaffD zLaN%}&{#^|@07Bw>Wsa=^3sZn;BE1f{YS0KoYUFD?gkcPBe#&LPZEPZ{8xS8eW^Xcq2QKJ)HIXNg>-XY zh}ujpG;72EgqpqFl!-=1e@~G)8aY+P3-bWsC~x2nCOG!hcN7>xvhB`iyju?xMTb2s z5{N#Cg|TqkOtjHn7?_C1H8nEQil_yL-&tK+>nJbh@xIntlo*ra(okgo;o?(ojKi$KmR9iCw$d+rXQsZr(~D-N3$b4_{D*W8DpxCw)ELeU(_Q|vy4&V7ApY$BERhn`Az~_5m zVO(fr;kYl<`N13x~So@H4;doN@PZPr`X-yl18aa3d9pC4@^K=(z{Id`%9A zM0%70FpD8E;7F3pCovj~v+dm@-YLV~TULu6oBklaC!clqahAjdBj_7aEoPlc#Uf4P z*dfMlZA-urbnPC7mFjR&m^0J;!!brywVv=#-22p~_*dF1+D0#X;@*+{MPxz}V9mvS zMY@jb_NCuVngDj1U+0S{+&3=6 zxmbN#^^!T;4L^tT5_Q0IOD>zDr9DM>3W0djoAR1rq0;gLa0sNR(IJ7cAk-`Aiqte9 z94(;XN@xU&bPF$D0oHq!#9P1Q&I;HV@{L;@%AU~kIb%-x!aAXQ546A>;Y}Jf**>Kw z-*a^ZQHc>ExT806dFVWw1}?byI?Jb23KJ{KPb_ucjUl-R=`N0@V0TXlaHgL5cnhUA z-Q)@pLDxY7hqJXbPP>}lKJsrlop%AN(seKROT)Bh9do26NZnC*~esZ98)AmTqwf-LcBa1GA`Voc+O@!puw| z1pEmLWT$}iV)|!FTH<;sHBVorOFt!rjw4@EcC9`IJcabNlRJjjo?=VD@8PkYc4wh( zl37`8zQ@VrpjVup-}B8~b>(t;9@&@MN}ui|@bPQ*r0>rN!-IEWk~}iy~`3+FimWO(3xIH?5n~0G@=? zLNJiC8rq#DoSHY3W-Ylqa^{YfFrv+&zo6pmut>Nv@B#Qy*&ti`Eg=kgIqhN@KoSok z_H%Jpq3TpDzkv8);f*7$+~om_x*IBDoLO)h(in&*e0N&o<$#o6m2QhO+8ZoahK0L zr}*0xm<7PDsbsIsXi)93fGbn_j>vOp!?q$PAu`L42GQ8vlg0^_nD4fEILZ~PuTEc_ITuMrXIESL$qA&9?rNe0DNE3^-CnLnQ{dw5iEM&J ztWhcpHeY~%&k3zHtZ;uQ3tG!tPQCaEMgc&PAt@}M@jtm2Iq~DJfGP?fmC8D@@x5DZ zE^}IB025`KqIAPLg4HbPkkX=Y(t4qPTMvoqUT6QCF3?eD977z7)bqEN1c_P`-%W zd2$oPB?7Nhs_U@wpL48A$H$uETwGh*P?CG>g$e>@2FK&-7Ad!t`M&I?HoQbnJZK+? zzWlQ9_J#=$j?7O9Mf9Z8|3jba4SzioUzESj$=fUJHOi1KlBjQBIObRh*^g(+G5ryE zz3H8NsHc|(kzSlR4r1z#Ywgkb`1_Oo(~l=!5+F{M@qvD=*`7g4jwD`yEZ)ysZqsK*{R5!5=r)LQA_I8j= zlhGWi56q)H&AX&ky9AX09yo~poRCyu`16}v9@U;+Y}Bpt*2+RLb{x{)wsyluy6g?& z)5p5vR*2^zNcWu6Wkwuf`flTONT!VWF@@?vaL_Pq^0vdRkd5G}890%pfzr#3A`zi& zYX|SJnCopHvp_`NV726L=I)lHafET1#*3}?t5~#zPMxooiRl(1d^T8|x4jy3-$4f(4?3ix+kPDsYZe2NpGjLBeoOrM*g_lKo0-^*+r6 zz0b<{*A-n~q6d7PuRH@dXgKRodLuZvv<1Cx?U-pD{Re0lR+q5xgiRgR0wD|&BC-a= z%#s0tu>UQanimpkj?Fkm_CYcSn>onngZbwB$1sy4Xw#V-6~lXv#Z z_QoGUqve%c(OuQm$EF$v@vrq?5irzd$+|Y)HsMF*Kwa@VwG39$s49`YUBDfr9+wa+ z=YYismtpOYH^hG~g4cici8siB>fNUARxwYjFywI<2piqN(mZt|5I_+URxilDi1rVh z<5@LY??PLMzbj!GV@=6I1r* z0MkOST;@xIjx9yec#-m*dg@6h!KXhJSioJh+DY#eZYB^zLZW0_0$CO4k! zUBLZ65r5O;7iad9Y~T>QXX35bCPZw$H`d44U-mx-#=n!MmU=( z66eQ@rQNaoP!~=HtTi`ui}H~yj7Jq2epRxD>}T9g+HD?V3C66u_@$meX#S+o&0X(N zAnA1W;|b>0*< z059%ZTC>oFh+y>-7iXgE&RmeDM<6&iJuCPgXY{1F%42TAHV|q51Kq4$iwF@?G0!Wc z*i{mGE(58@Hdy0^N)m1mI+*?`k^cL#Xn|0#m-)C>3dJwKgzPA?A~f^OQ+ID+z4-ZkNHy)e5`yqh0ryr$NES2;1 ztDFx@_WiB)Msf4_<3R~W7yiTDRNINAvu@02SqIRz+S+Q$n|75b+f5zsl^v%i$#`cI zD5Sm+{#i}jY^9h8n}x5CkO0G=XZ3TJ4Ij<-UC@z(pDkVhjN~N7Seo~xc(iw^l| z!uQKh4WC_~w{MV(GwGymu`A?BI;nla;JcmmdAV`~Dke+vz&HH8d-11}<`2Q+=u?a! z-rF;6vR<)9QhQ^=e+pDaG&NX>LjtAxP~1IkQav`=J{AEaN^?Ry_$@VU*#r(|6LRZQ z&-vy&ZhK_@O(n9w(MKO$sN5ru>V;J_6n6)RIoF z3t*stS=aa4osO3)d9!g3D~~;NebjeR5sBFy0?%bB(>TM1Pm3f0g8pLuWN35-H6=(0 z+*z^Naoio^M>p_-aS;<|2}Zn@0fmI}HMVfpCbFF$lb?w#ljKF_{z&bD;{3%qVe
e|jAduNsOo9xhO{KuF{qv5fQ4oAZj-NdCwE2E1UK+SiCD2$~nJb)uuoO8+J{AM?0 z@uD&Z-8fv_lfw?sY&bNFA~tmS;`#FapAz}nLkSoh^gK{EDj>PLH__gY>$a!Es4-M- zK10yI>g$bVBE1FL198)UpdpZmoXeS#nl*3!)!$8!|E_>$eZBB`S}@=;CZ*`3n@s7_ zT+D(7vsZg__Y3Rs%C_9+j#OqlU9)@gcNPHS5e^3zXAGs{@~`w)px;gWI(-E&^AZl&WjZ0}cDdom(H>7* zyJnma1MC6)-y!d~zLd(5iM}Z6ZS6V2awxzHbLESy^-4M*j^A@2B%DF_6u^d4TrW@1 z?-3r%?99Ze`NuRhb<}6`k0tUEHe!Z{nNY_;xg1#JAh;h@dYI!yCe7qYjc(q}$JbIF z7wfN<$0l^A_;u08OGA%~vd(XqK`N6xhU0GSQv&(;wb(PyWrYw?sHn3Pa*)Aka(^d| z+2PUVwX~JYzgU;6l7dlG9gGvP8+^Nuy0h#2b7}f8k}g<^R2i-wo*oO!=LstQ-V0Tn zr(#?Ag$dBPJvx1B{N}Kf0Ws%?O^Xq2PC1?byi*X|K*0i=vAG#us$_LCvg2P-VUO=! zG=Y|E6i5-W3q4*t|_+vAY;_%&f`ifB(MPyGJE z_snB^{t_kYWh;8Hrk1OlE4&-t^?1+`>5N>hw}^FeXC0}-C9t0ou%;EpaXuQoY!k8@ zrwmK4P$orS&>oFS-^bWH=HocvAY*@GgW?}X|$htLNZ?cP!>1jgUyOp}sC#d5YqgdDWQ2r?Wi>_sgz?@YA`Q56! zExYGeP<%e9_frz%l7LapU@x$J>^Cm2g5dibE=*{;S^(AekQC$SX(Jl*&?6IuQ#cz9p;r&x8$9hx*exiS7CdYRV+d zsoZC-NTREH1elDYYW62-Y8yc*QFu4Byzmitun^L>_68x(^ru-Fb{v*<9@o6BNQSc) zk;jagkh2K48}MY}cRQWkbxOI+Rb>d=C`*DN>+izQ_x;f(0+1%O7Aiwl6yHnZQfc$+ zQOHGp!-VzJWYZ>N^#GHis_4fc)!DaE()fF0FJ4R%BdxaIytB}>MLeEk802J``>Je3 zEJ%P4r*f2E88+0~&QyvQ{ z6g>u3X@s8ttQ(i@t_i)a+B|}I6;~qZ&IJ8e2QSM+8ng83e-X zh-$kvdRf~T>Qzr?0*E1oQHd%o^t4tcQJ>w+G$>%hjsYuVL408(Ku=&=vK5VK4yu5e zw9{a6-F|czdm3wYT9g|yp0%3O?V;Kx5^D(_iA6UzJJ2s;j)Fm0_JP3`zjM^gB;5}aG zK@mz7{UiNW%vtg#?X-m=+k3H+NPM9n!)7|^Wg;`0>8S%_+pb0s>mx(rG5M}_+of-8 z?wfJYXw;M#;0ygJ%*AZBv8ot}>rTxat*DIA|A4lpM#`#6oKOb1Su~o)t>w;Vk#8~I zpx4Jv>o++H4@6U-C`KR1-NQ4Q_H~kj4bsQe!sDRvYVlimwyx+&q%{Kj{F!%9HY2As zUVXEBp4aA`=eQ1=wlf}`*DRfjp%El~hTUJahFVsB5b=r@QRy(3WU0#}~d0*yq zg4j01CVlMocHLJPY@>8Koip19ohR3_gJ|d84+9%JxE^n_0j*zZ9jnK7ww(1Jpv%=f zmFFIvvmtDRI^!FsEAMS?X(``J-pC^BnFFYcCUg$&v>KaB&X^45ScPsVBhz?9; z($;RXjs>{=OQl@;w{gWG7{0~%0@)?3jxR?n)}pV|OdrVqG5%kE{$u&S$YTRnJ6sn9>5i*4ov}pLx8kqu&~$QD$>cYFe*H{oOZ$X)jsfRx4u&cF1JB0J za#zp2CPXd=7u%1KJDvCcX+91!L0+l(w`Ku&jSH*`s_41$s1hhHJ!-=fxgP`M0CJ23 zS(A9(TntY2&25-!X#h!qxQS*;ied?Zr&z>ZM@^JSk(q9ib3;kV1<7k^vUYNj;Uf`_b|NlGl}_AusADY5oz>Yk|FoT+vODGJ)=J@yH0;csT+HXI*EDyJ zw|s7aZG|bXtEDS{nM2G4HIfn!5`;?`o}SKWfAn&SRtuIw_dD=b^E@Pkq;I+2rX3>l zLKR_U1!c`@%xK$wFYLEQY%#h7qVq9OrC#<}^SS&_2XYo=L#XT5ve4eKP4}35r+Xt;fVEm#)H$HalOA{$8126BR=+ z(~8+ytmGhFDC-$Eb}t}pQYvf*Tq(#KOuTyo!adT4gFo8h{m#UR6qUPH>IK z6tCiqFiOY{Yx_)Y85wOv+H(#90?ISf0DwL|5O!0HHH*jTxCX4vX1H@kL(&?gr`K7M!VoByx zhNZUD*%-2_%DV*BV&|zX+P4rG6hkQPP?|nJRi(G?o>Js**e&a11jyRMn^)IoNj+oE z&w6RSFDqDMN>mBmF9DlX2MK+{I$!v?9sF8C9v#_Y*~_&qnb-B+WdPWZauW)x*kiX6)@qNYJ*W=FS=M}aw zBKbV<$8Q+?m-f$NT!aC#1@vs9pZ&nte?DfYe$IqVkton-9OrC6_=6p+W?{H7;;I&8 zo_43ZziQf=9Ygd-5`0Xe<=^OlnhHZN-8+TTZ>zvvsUjI3{xAnz%VfC!e!=u5h+ZcH zjukJJ?XlzPYB>R8XOQ_#5_De|rTX5e>!VQUy?beX{?Jyj(NZwj@iO{k^+&MQ?06<( zQ+4vFN+Vc12tz?lZSF3?lJjN@JHu@o)9G~tp5;(QsgT>2R3-|+LA^qHeQI_)PqzQ3 z#?p!k5={}2hQhMsU@%ug_q49Mrt0;F4GUyT9kU32+&xNav@)$#2)56|hu$0dUtD=h zF-zv3Z|t6J=%IvZ8qDcx8k7u$yiOTh`nn}#%p$u^;5P(({X-w=uKV3+%unE$^j~Yx z=Xuf@Q_21`I^LU$Y)Dd38aQLNz`mPBvufeZ-`f@n zCyfuEv$|B%m^CAlneU7|2)E>f8goNOoo_xj{&p3Ghl4ZM%0&Irs9Hg($h!6&G>Lgm z2bTBYAG`ClkyrmUn~|;(kQE7iL4nun-+bC_Wagd?VB)L@8vTU>qqlD%Ne*ZXZ=V0WOaA0YxjA63k=f2Q(jq`cCZn_H>8-AXVnC^b zca+nx|!5yn4W@|v&4dA@(Zg8WxUy$aAu6i zq&*Qpz_8;t{~PuTrkhItm?nUs3ae>r zYELO;NV{1iCFj1T8Ku@5s$BHOgCS4WGmS&%s2R&?RjoRxokIM*aTOGG@m^2 z3dWDINXQQg*bLHQ4lEcD-4|S_Qwo3=n{QF;2bQA$vCvz%vB1PY%61v)EgQ|dKq6eNM`7lHR(TUEV%B?hcD zJ))B_QI>z?H#d17Q(szIm_rE-nA4Pfa5|x-dF5;d`=*j%%QI5frZA(^$*_^ni`24I zUWt~^Beq->XfjlU_?e|JB>EwfJJEkR)Jr1y!h^-kvzn_+k+EYMT_8-PO(+TJsUe7G z>@L7X_y67=e>7yi3JM{O_^%5H&(~`Wm1uxWJBVxd*I9?HZn6s5sBF7m?P`y?xz&_{ z!kXp{p@xR`z@fsDV3%+kzBhGod4f!keZ1!CpJB_7gRkDgF&4-19C?-_1HGxhMfSxt z1-m@GFv#Cqg&tX8R9U9T9Eu}LL(LX{*jiDFJ-Fw~=it$P)7oWFkGeeW3D$TbEZb*e z!{6oOrYE~0xL=8xXx>#I>9G(2HQV!^!aDm?cD_|xwI}kp5eCk6^bJ7+@iLNYT>ld1 za`xhO5U=I5?X&woZCR$mKN=XT;MPz0%5P~RBk@9p6b%U_aAv{z)W`?LI_KRNgN|i> zKFvYH*Vq{{Z0uz9n9MxpXA^&ajOpv$&3LIzs1=wWf4nM|zWiWkP2+O?z*6f`tpp); zZz}(6)$dw-VKwY6LxN2)(8H$sK}7sn3vZ!COo*_n`va^tyA<-UI+W@T??J(YYxI6&MZUSWFQP9p<2wtdgeyqIgEqv zuC4*}OYN_ZMBb2)tv0wH+D2;+YzxpgHokAaU{*q&DV(9^Stwm1#m%@975#j-fRS2- zrbSSIDExm__wh1OpIbn%hCrtxc}cPS*qzc7JLCMpI8s;adH3?@Wtu7$Kf}H6>fl5{Z6L62W&yYKt^?%`^uTwtkuVr;jC!;V}89oo) z&etU;>h2f7YqwtA#mdrJDrgagZkrx2Kz}e@$*$dv(FZ(4OKt-PV;&My{pL?Iy>#!>Ruwc3h4ckZ5l_~?TKS)q z<7*eN=%-*9B)rjR45REZdQsi4C(S-sNWfwy`Ps$zR%xnksv$0~+so*rJ8P|J_tv{$ zwU;}oMlY>?+Kuh&l~+`-ztcwQeXan z}|B&|E+Y8Kh6`V)t`ibR{mtkw34XSoKf-jR)GrRySaHpkVZ)D*ab@GRFhe$$+6FsR9ax3RflN(6zc72;D!NXtY$@ zs%fALK6tX)_MYnP6nV3#%c}LcqS^dd{p>@6hH`+vNEg-v$%U-RVO2pogT#~p=hCto^-R8Yg;b{alR9AaL`mPkr@8yA$2 zyeCQt;xG&F6f;>_c#!%;rC--N7Xc zi0|8Nb*;G{?9JWa-MY9T8+{=8Px9`;`r|Ee0(GebCNsA+w2t!(+YC$NF~{4$s}}l> zujgyt58TA6OCoB*4>(m;N58|p2RV-U#7b9s9PI5KRE`@<>;jtPzC7@-vo6ZW53KxB z73}WT)Jb1kRpm;YPOjRLfEf6@oJyjqvPRDpDVGl}WT&fSv@h?JFfMlGu4ntwt=XH7 z4t}m;#>h?xWl*G@`$UF}2TOb!-km#QQ5@(ES9(EhlupUaMMd2*4A`jBQRt`mPS`;&Kb`PPW#EL?ffLO$q zEQ-ELT`V1noeo#c=#LGfwJ;YO>(`C@`ZzR^mI3lq7GeAb)ufv8_X$CMr z!x?PDhWpT^$H6oTfam@{e$gog%$<7Ra(Wh8Nb6CtAx~v64IPZUd+%DR!^uk%bEzd~ zaW?dZ&QAmNYC=_qeBH+wCdqGE^Dx%5;*e#h%2FBf8LgLDQTV(rViA+#0XxPHiqOQOm2C#cLtbsTvg z9gPxlC@_2R&z74HElmcw{xIHbP0Em8br=-K0$%R>bC`tqQ*>*h4=OpH0&8%$J|fSx&RTLy#6^NBxDDEd3Tj z!jW{1S;fcYp`5j$?|r%yppGvbBWbk%|6zFlSAp(6LKy9Z9O5UO|8ARu2PVKG9HK0?Ti?vX)D-qi%r>%1S3iE~ z@-_EI5Jq^xk=#9Iz)2$bT+-AuwQ=R)uYOb6lpK9)dV^-;eZcft6mSd6tyXSt?P`h` z&=*-Y|9pf@qeigw65 zd!l=C%$uG6_84OD+<_E1Xi`><(PVK@x*mkQDq_%(kV`PPhll?rKRA>G&r8piKt8QAf83KmR7F+k954j#G0Hf;2-tpiyciFrXahg{ zdc(8^oe%PLL!{v$TkbIyN<Ua%2K(-(optIJy zn9P0dcs{?IJn@_qsH6cd+w0cH5K4$jv%ygC=w;$_%=!2__>><7Hj$w^Nt zTBF*~T~AV_eK~_L%<@FwA7UYSK5w^cl>@U4WJ^g^Wh+X}oUw)y%G|yN-Ob;cS4KM& z)b&rFa&K3-kvz>+_e?YT#n{0tmDD<1x2KXZ)4P1IErl)nfo^V^y+43ZWB@Vvb`M~) zIY45V;k!&(5WK84pZ}jdlIn?Pj_}xPkMp0r&j&dIh(Y0|)C8`1iY6gU5e$SQh+l`W z$^dqZ1698Gn5~5dcL+t4yC8I&bj(9iH+)jnLr2J7oKG_~;_X04XHk%Z96339Weca; zyfhgXQ(QBAsK>L|61fC@Ws1O|q=?91bWztYm$-_&YY2|#6^d$Fw(#J^wfR;u4^TZ03Ih~23Y_`=l*W-2sr%|dY^!SQA7H5Cr`njW6r$(l-Om@9D5(h>wBmow$ zrVThe9PL+^GGmJ3h0#y2`U6OeG(-eG=tJ1KNezzN?i5s;^rt*LO~eWqneER5CkI{h zl^$vLcbkStD&%A=MxLf#ME;G`@=Da4ReqZc`n{Y)sY*~>zr^RuiRqfYYGl}aOg1On zR1D8k3y?~nS+`_~J&lk(7v`cw%;m~-P3(FLzsn&xdF*g_N`;}F;an<7P3Tk@+CcBu zwyf`EU#c9J$_hGV{iea%;9LP|f#Q=2^?nMi;?7`G)Frv<&(d=x>Lia@-Eu9a!izdL zm;VkAgsS2NIN-tMCnGxB(lDDHUjMl1cy!<6;_fnQxY44e+EEVgFP~jli#b9RM9>o> z?23OX;|a{I$TOl}{4v*;2JQ`|#dqw0X9J1vGCPL21lROl{ErcY0KJ$~!Y(Od*SQ$!>vCJ36_hxT1W*(ApYRKC zyL?h`u86cPy4CM`m|0wVU^C<`YIVuH1ugvmFCBOMAE z{C*1_0pW(p9$fYODoKs(n%tAF8)7`-=x#WQqT9;8Jkq3_yV(tOo0r?_Y=8Hv%M{Rg zb;iEGI=0tX2~ZeXD-a8lK!_YlU+@rB;uS?tCa+D?fOQB;IzmLfNV+2K%ahARLG%We zKLHTkwuG&MuMPKPtoyiWqVt|HM^vwJ&a3^1Nv(xF1M7pY+Owrz^D9bM%4)$zm<=;O zHGjjk66v(Yn*)LMZdgl?PUMnFFO#E4TZEOmDNgPnz5c*ftOfVa=hCK63?zbs&a4CyE1rK@bp5Yh2QV)&!JUZ27his&jM$FHFg9Y@bp(T~Zi(mze6a2+v^zezHHK_RTIsrntVw>yo9dyMpR zMLwwo2t)_P&XutaXG*in^In5n&y_icW1`{sqqqoxWvoJrt<6n8oLkO^?om2lmSH9|^hcN`nH#n%?vVBT|@^NK$b%5H}F1aj94 zq&J29EsN=WPyf9be;YCOd?>NUJaU8KMacDKdpC2z@X+7b>L(rD1zPv})xrsao`riya6qRlE*G9Z;+UgN9zU zdjtBD^2Gt_f5@^me|fHBYfkFYccA=Uu5D>?WwBk76f2h-fYV22whCiOcQyw}=eiG= zcJ%LzuAHt%Fl02lN=KX1POC`#78scCUfP_r-SkR_h#?w8@H2(xVr91~&JMeDQ10Ky z!igu_l#s>H=xQ!GT%p`t1{y!4A`t&+nL2SdM0%j*G4y#{A|P+a{_xJ-O7KukpF@hC zL08i`y)D8oj++)Md5pxXco`Y#O;v9z+-ETt{=xRW9362i-?UBuKuS$M>Q+ScO$oPT z{PRYGYahmJ-9`*UUYm^jb64^NGrRC*ZQfnuc+SXm;t|Ze30p4*ZkJORO)_G6Qd20@ zgraH&w!q2I4c|hM@CPh;_j{dE?;d7-0n0W|AtNMt%hTbj3oT}Dx$z3?U5(qdO?}74 zx!f|}Fng^0*&MP@j*f%BES1FUAJ7J5CEzMpnto>SL!y!~ z&ZR0XUv@K(nNwe;laOCwt;6l8e=KRL#3R39K%}meg)`K!pzSTsKl?|_hJR^>mVEUc*DzOZ)qal zbZg=KZxtHPz_LES-~Fc&LMnwX8~qlOBeXBztBZ~QuoIHzeZkZ`SvF-^J@@fky9A5s zPO@l=DJD6w)Mm?XUusij`jWJqA1X2}=SlxqoqD~SS|tx+m@6_s580U^p<6Thm7`@! z=kw<`!dM|Yu9%xH{@mFOOJ>ut-hc)3g!ufilm6~!e=$c<9((wpk6?ueMSuY`Fry(h z9@e~3w56ak1IpJtvpnb@H8v?~O>ymSm!OZ0(gewMfF{jsA^nEF-HJ1g@@($I-w1g= z)w`=Vt*k6iNc6+RyT=D2)-3*{sekQ^5961;qP*gU{|ba)+e!_U?6sWu3b06#-SDZ+XPN&M85+jyGJy+V2zeqc2CRLb2p7HdHT( z>sQm1AzuCYIW{YjaSxrIr?pG31%4@gBd*5yHDn>p#5C#7rRVU&%YGD%_dEPVuF93E zSkP>7bm+4c@DNo`_D8gDXxBGVhMtOpct?teqyyC z;i<;-%gsrK1FPsCs7J|8ig(auOJ?>r> zBCr-nYv#xI@uFBjLPcCKy=T%Y(WhN!=KjuixYUE;ts=vp(B&5B-Q&D|WTktLKEXAK zu;w?idd`ziV5aCxJPz!zq|<8q@6!gMjd5|gz`cgQtZ6mKm&?NA@}U82HhAPa-?~{K z1jwJzx1E!lwMWcYRKkkwshYaoD`p~x?6AQWURELQN`21jJ7U?4ReEL$?mWp*_knZf zO0fC5fr(=ri)_uLJY~NFlMy+hwVOCiTF857_d+aGzzNhrB>Toc76(CB@VnxmI2!{1 zr3Fnkk1b7r(>Otx+)AguI*Ef6opE|7|ySVxOSV7 zx8_>~v1kTo{s^p%1Rgrp?i~Rx9 z`JVTSaodytk0n?`SQ+h0pj%V|^e@iwgE3m07w3C=I3R7^h0lZB$l1beplh^qbz9B_ zXAR;FzM=Q8BTjNZ5eK|dOBllRhZ_vlKX34lJFN=5b#T~D>;dgUv#lGGuWfO_&ebQ` zSpaaf@u(lNVkrCs_qa+xOi=Ifzd)G})Y=m<)1X`NpieZ0ixNmTx34EbKF&~v17+gc zbJL6R>nBpp^aq^{Phc#@yi2+J_hQFp8Ak1K-p(3lFi4+ex83Qq#5D=<&rkFTt&bcd z9`c|o#yOfAA0&KAuqHU4YN6Y!VcaU<67cHUsC)MxW67%LILwilVl&E+_6X{4_)yHs zC(>r8oB4tWg(rDsz=&SNJwlS7Ggdd}M2t6P{(ROVp5v%X09r|9=c*+MeGDYxf5gpi znrJk=Ho!cn2)1n*k3&M{6{=a%K%8rA<}@!5=ePH`i(|r^tj*Yp7%ny$W0*@LT~cPg za3(KjZU)gkP_?$Q-tf3OLd9wiGps`^Pt^tsdt5sc;H_K!`CF}@9RMkYUDw&^oDV}H z0pPOPGrjKtVa+fJnDk}bkzcn$gRM}(g`Z;+c#$E!r%&t}O{`I&zkNNY8}$3Udu<50 zIHgl4aygJ7VMM!x;6=y4fP*i^u)Pzp9f7OwWvpRT&1tc$p7eXD%YQbjcv?YSb4+Lv z2NwMpV<;VIAvU5XaYmv7X$BA3UOYt~^R*L`@uuidsoC|Hs600GG_S+vMq_ktH)1xa>kKbWRIvyvlQU;U^1u~Aw*u!JaE1PeQ*+m_(PuJ1rJ85c;-km;t z{mT>;Uam16Fis98&zs+ko{J#ixfC7Tv~V5Y64{EkU@98*si78^&dO&4NP>q-AIntM2C;mP681?h;Ae#b-Mo?M;x3Qei(L zdpEq}1A>Uo#!a=-Q8{hsU`gDuRcP4%^{MwXV@wKFw>q!-^N4rGt!OL+aHC_5#**R3-Q z9zcNHAS~^a2F6{vf5X`3fDYYL<#p`OWHpbm2nN43Y!;}|hf*EllfwC1-(_hu#BMd9X#nRv^BT+4m zUpRoA9)GoRKe4KX7yLHR;f3otmu|_SKyg4Ruj%_Oju&i7P*-HW9SZZ40=IiM(U&;s z?S`hGd5o4Az(>K0*PD#^7bO$wN;*idEPjvYMRch6=_IUMd=6(~LrLECl4o7=&p>7( zjV-+VM*zTwYA5MY+Pp|=Cg_lOx`G?{WYxtXx)B3BUoGi5()6!FaT^F)Ep2X^vR^mR zr=0i5{~BOkFqL|r4}+DD(>aXS95fH9(#TbGhC~FQv}(R;3YYd|x1O_{TFHifKI?ir z+^QQQ4j31@9eF?GJ6&yBg89s7w2C*iFCye`bvqZsStCLoh5-}G$?sDrL#jeaA09JX z8SLTDWpm+u;loPNVdW}G3@@Yewmgvhl?NiJfiiLQ@X*dSfuy&1AXHrg}iG=dE}hQg8w&g`0~D8ucb?Iw_9^rDI9W)^Io$)C^&+ZsuFgWjg` zrtC)fqA93gkc75ZS>WFsjU4J7}Bq`M*Q3NfE5p#<*9l%I#^dF5(f?5L~mJ-c{fSM)4>8_&lA~T728`>Zd~V4~sIu1FTk+`!q>lW~MEpk@?b? zq8mfJYSzR3K=XpWQkX+pA#Di3!SMlrn^YzHz(hzbCoCd=&j|oDnIZ7Jy`CX_KbZKQ ztVzcY7OF;msi?4`kL!+4Q7}Q0Aj#V3aZPF%_sP4;;_g=XKp5L~=ZbE<DB+3xKoipB-%9+Y;eeL8T=g~sB1vSc6BXZS5~ykB&cPPTBlTUlXIHdW02`0rASDzqgzr!0Qj*C(dP7-oihws}@Vfxl?X(lVpE<->>tZ*MFj z@UVWH(k%S$z{6_=iZ;@bb!#|s(H$`cPiPeoFes^d$YxT?=1@i z^xKqMUY)hh}}BQq_Idtp7(&LmR5B{61znW02rZ#Hjeltx~Lf1!3*VPIgyKFJAzU7r40`~2nK zs;Lrw4C!!sDx{LdEb`ZBIKWa(+HH6GI!V3tL@mE{Z{dR|pP%*IxK=j=Uwn1(RzM(4 z@_yadW$pO&Rq&3W>)po!M}=OAJiYh6Cq3M_I!&zF@t(*FdUK`Yh%NUB%B1byJ>GQM z%KjG$s#aA1=9#T%PO7@Y^u=h|u0O z`!cwbc=2E5CJ67=UVnDaK@PROI}{X92z@{`=W}2(dWHT>B)p_{;c?OaYg-4iMj7QX zW+tcRpe#f;zbh(7^JmlQL-67-hyf^E>;2AkuTPLx|6Aa@L|+>thu<(4j^YY>&lxtt zLQ)`ubC3>RRqY80Mlv+f`AtskD)>I#{Cnl&DGpQDvt=bO4=P!2+EJ)uy5GHP%0|P` zF9SY{`;NznyB))Kcb}aw;d&)fm8a>hr%yhI{KSn)0e2jC3soNZ9sn(h0k`q{Ck2P50;x!>~u+jz@Ip=#0_09=S@VQkq)dJWHR9}NM5I@_-caa zyza;{R0%GfM8{mzvst0j5(Kc`p>E}d#FBO071eF4H#qk|%G5ycB4+5uk59VOg)6{+ ze_6CV=7OREtk;HvzTlY!BwrE;N*_G_-YAdZV0-en%VV(gt4t!XNIE6d_0HCV!pBNipDch33VV3H1v9rvz%v{F&5LUYhSCl~ z%(tdd^{?L2x*m{$0`>3AKF|GJ&zn&!`54pyUb`$x|4+2#&G;MNn^8g3`d?xMhKd-J z<4bE88{EKa3arHk;LB-3B9}_=YhFW{7wpaInZunN>t@U#^6G}wX0HC>3-_Az8Q1X^ zuZ9=lf1sfhP)jqa1apq9$FO{O66npesZbOM|1ju zH+JjT(}#cC?=y-^HR6)!C}ARx3;N>|itA1YjL1KAqf>AG7BwYcF)_lev$yTK`0(hH z316`+?2sz-WX^!9sCE6o(HK&Nr>K?kcKmK~sm}0H_d{z*-?8a&NXYS(|8AAyhyR$+ z6I_7NT9eXhhZBX8;A_3#UdC3nlK+llh38!L1oJqCChN}PpBkZi(XZ}+kgNa*PG?LU z7JU~!Al)3=+cuoT_SMJ+;4Nd|s{?~Q76@lTFx)`Wm}|T?MW_j3RBBtOIb7#HA-VN{ zb)px^9`>;5tlw1ZV6kJ>)UU8jJv)L@!-(pIMMHx{lu!U`iOGzE;(-yU2BHxcqy&{% zWeVT`2_7lK8|;AW9a@>y{4o~ihq~@78I&(-Gh;I$<6kI_x*1x5jZkslB_4e zy<2av;mOfCLolKep#arP@?8tRol-YnXmO?rx~R0Mnxds@mblx3;O_TC`H)pNf7{Rd z%kc(kszmypGbERhC7=n>c10%Wyg=4ZQDYiMMD-R>VXZIG>dxM=-DeVAuZN4i4}F|! ztI%H8r7^OsFC39R*BZP$nh zG7ww1dchJJFu#orUssn-e+XS6Jo_YV(5rUOi{2ptLk*btL@zzs!HIu9uaO7E?cPE~ zW~gK=Kf;p#RsZ37`E5L|{(r)2qRoEtwZtxI7>6#n-kq^E+2YA@^9Ebi7u0jF@DFzh}COiHFX!4lu zoXV|nY?Wf1XFR&lfqms$ZIZq;Y@Ph{zU6sVC`91yD&F{9X>4@LzT!J1vMKwPZ?62+ zGu4$~T7d1+kSStTP&7`hv*7Fko*BaHov+wYTZ(Qf*7iajU4x{pFWm{hBj=gt96?t1 z3GE%j&|>!%#nJh8Kj68mveUeZYKo|4aLX4NCzQ!!cK~ObZ__O2{bVXvr)2qDzwK=5 z{qNMNQuoRGThoWt-uzMG59lgg!E-8iU=5sMASFH4=zIBWe)tgLcO`FFdm;G7<4>CN z*WKs-+w_T-!XX*ZJzOd^qe4&HLPe-J#PlRLceGiPg{bLzzdftvve_QbJM8u^)#dCY zxi>kU3cJ|DkFR2mZflJ-#3@l)h-I{qKa-D_8h+hhW0S2qHEMuNFJVlG!v^n}lTtH&u6;7;Ui#V{YbW*?J|GJeYC0Hi6e<)QaQ_%p2KpBp{I5k(dP|ny>&hMS-deI`2p1dy$})dZmBPKpx5C}%!yX0k8w+n5q3O%S?*525B8K{{$~VoT({F>MAQDVV zz;+EIX%YT8s4WYTnV(nr4h2K=O|QA-9WyuXN7iLWQuu=qYQ5^tWg2DjsdQo6=m(OZiv_)7#&=lw)XlS!(nZpN#8sIfFdWXmQo_L# z-pj#sZaZ$RBbDlHXG6oy8iYai1k3Ih;g#OM1?ofx$0@ocyMZY9pDP^&f>FOsOQlA6 z>`EWnkM%c;Z;pjxK~+<4G|TN&uxad|s+sZ9>&<5|g*?^lNA06-ZrF zRi_O^#Xc3g5#pN~8waHY$y26L_>-z8^47YeqF0*ccA*JK%8*x7)t=s|r))#@qx{{@ zR+g$U2rHp$kN4e65!uuR?>jY2^KmY*w?>f13x1cC)9e*y2@Nf;h?MUx6kdutU(p?2 zWZTFJTSf>=u*FA&{zS%6E`h-OR56Wx}h-3v$K#!daWe zx}-enxZ!dPF`xE$^?-3+HF1Cp+pmBQhpShq|i{}rNGGjb8%8M=&orhkoz7cWZ^e@$<}68NcUCHC`}+ujkg^&fl)?w*cFFFB&T z*1+6{tuXJ0-A}B9wjdPjFT1d<5JzMDfQhQNlomVXb%o^cyZUYbzIHRwt_nH1gKE5& zcHFK)gO|vs*$H&hI5Rm5Y1D(fb0=zv5~ft3669}0NI1zJM20tGdcjH;#ote|ZxUp_r`vd1u0Vn)=^ywdu~BGa^M zLR@@0HW;L^4h;_nT4K^P1mezbi)0cvhfGOzZaWpu@|9P1$^+>uO{sPzZ;ojkWcn4z ze~~YJ`o-0RwfHlPH*8`F8->KBiGsb5{K zhR&+$Pf(o0h&+l=`9?6)XP=`|MFjT_0nYa-iSZGMX4wL6gb`=Tk#@P!{4Wwt z2MCe$ooSmyLM4u4PV&qOm{kJs!T(_RdmbDSk}=;m9DoY7|IxjF~71?kW_3t!1r#pf1j)hcG!g%ZYv z-1CW_gd5-Lk=_A%vZ>EU2glVGBJ3WMCMpPejPVxKgB;l__t^3cFPMS*zOtdrZT5RP ze7LP>+wGdmr={2F4r{9)zae889Ds+tRbK=R!nPMwe>IjlcMs9W2w;rjFgwq$25T?_ zZ(RfD!m`tIBnwC0Az2|6R-$uBd(^*sn9d!UbC=&h!1JMgfRG<805pI=Hs~N1fV)8C zt=GGD_SQsD@i8r!Whjp71|eFGY6nejAs{QSN63qhkP0aBJGx9dUUmJpdsQ0vU`4Jf z)pT{d>MQEGMWscsvGKHitdD`R#FjxY1QPWWwN)|v7+?`b8}xYKXx_S&3;2y)xH3O< z@44}qJGfwr#ph2|l;{L_<)S9-S4II8@zUVj6_$fymf-hYUoK5mClM%hLNBu zLF*ES4*@=ep#(v&IHi(mgy9kPt{;J0j`8cO8h%i$c1PN7>$dq}HlD$X3D|0doANb( z5rU#rtkgmJ83_S{j#>t0?pg0?Ct~_0Po%!Yqc+AMuZ&aiiO10Ka0m@twd8|d>;JY# z++hKbP}8wX$Ht}2gRW0yu4N@%OgE1!B zVVznRIk}0S7VeP;vHerP5)axYl`+i`xn~TIZ|@g6?+sTQqu(JuK3Pdc39y*axBmz4 C3e6e- literal 0 HcmV?d00001 diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/video/screencast_img.png b/filesystem/root/.tmux/plugins/tmux-resurrect/video/screencast_img.png new file mode 100644 index 0000000000000000000000000000000000000000..f5f3d83299e0eb02834030ba8fced6b0e3d9ab43 GIT binary patch literal 124253 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%0AgJ2AX37i}H6SX(5Q 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�Sp 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
f&-kX*~9t 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∓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 IM6N<$f@szA7XSbN literal 0 HcmV?d00001 diff --git a/filesystem/root/.tmux/plugins/tmux-resurrect/video/script.md b/filesystem/root/.tmux/plugins/tmux-resurrect/video/script.md new file mode 100644 index 00000000..ef388248 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-resurrect/video/script.md @@ -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. diff --git a/filesystem/root/.tmux/plugins/tmux-sensible/CHANGELOG.md b/filesystem/root/.tmux/plugins/tmux-sensible/CHANGELOG.md new file mode 100644 index 00000000..579c0dbc --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-sensible/CHANGELOG.md @@ -0,0 +1,43 @@ +# Changelog + +### master +- remove `detach-on-destroy` +- do not set `aggressive-resize` on iTerm terminal +- disable `detach-on-destroy` + +### v3.0.0, 2015-06-24 +- remove 'almost sensible' feature + +### v2.3.0, 2015-06-24 +- update to support \*THE\* latest tmux version +- bugfix for `prefix + R` key binding +- fix for tmux 2.0 `default-terminal` option (thanks @kwbr) + +### v2.2.0, 2015-02-10 +- bugfix in `key_binding_not_set`: the regex is now properly detecting key + bindings with `-r` flag. +- enable `aggressive-resize` + +### v2.1.0, 2014-12-12 +- check before binding `prefix + prefix` (@m1foley) +- enable `focus-events` +- deprecate 'almost sensible' feature. The reason for this is to focus the + plugin on doing just one thing. + +### v2.0.0, 2014-10-03 +- bugfix: prevent exiting tmux if 'reattach-to-user-namespace' is not installed +- remove all mouse-related options +- introduce 'almost sensible' setting and options + +### v1.1.0, 2014-08-30 +- bugfix: determine the default shell from the $SHELL env var on OS X +- set `mode-mouse on` by default +- do not make any decision about the prefix, just enhance it +- update `README.md`. List options set in the plugin. +- do *not* set `mode-mouse on` by default because some users don't like it +- if a user changes default prefix but binds `C-b` to something else, do not + unbind `C-b` + +### v1.0.0, 2014-07-30 +- initial work on the plugin +- add readme diff --git a/filesystem/root/.tmux/plugins/tmux-sensible/LICENSE.md b/filesystem/root/.tmux/plugins/tmux-sensible/LICENSE.md new file mode 100644 index 00000000..40f6dddd --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-sensible/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (C) 2014 Bruno Sutic + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/filesystem/root/.tmux/plugins/tmux-sensible/README.md b/filesystem/root/.tmux/plugins/tmux-sensible/README.md new file mode 100644 index 00000000..7185b670 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-sensible/README.md @@ -0,0 +1,114 @@ +# Tmux sensible + +A set of tmux options that should be acceptable to everyone. + +Inspired by [vim-sensible](https://github.com/tpope/vim-sensible). + +Tested and working on Linux, OSX and Cygwin. + +### Principles + +- `tmux-sensible` options should be acceptable to **every** tmux user!
+ If any of the options bothers you, please open an issue and it will probably + be updated (or removed). +- if you think a new option should be added, feel free to open a pull request. +- **no overriding** of user defined settings.
+ Your existing `.tmux.conf` settings are respected and they won't be changed. + That way you can use `tmux-sensible` if you have a few specific options. + +### Goals + +- group standard tmux community options in one place +- remove clutter from your `.tmux.conf` +- educate new tmux users about basic options + +### Options + + # utf8 is on + set -g utf8 on + set -g status-utf8 on + + # address vim mode switching delay (http://superuser.com/a/252717/65504) + set -s escape-time 0 + + # increase scrollback buffer size + set -g history-limit 50000 + + # tmux messages are displayed for 4 seconds + set -g display-time 4000 + + # refresh 'status-left' and 'status-right' more often + set -g status-interval 5 + + # set only on OS X where it's required + set -g default-command "reattach-to-user-namespace -l $SHELL" + + # upgrade $TERM + set -g default-terminal "screen-256color" + + # emacs key bindings in tmux command prompt (prefix + :) are better than + # vi keys, even for vim users + set -g status-keys emacs + + # focus events enabled for terminals that support them + set -g focus-events on + + # super useful when using "grouped sessions" and multi-monitor setup + setw -g aggressive-resize on + +### Key bindings + + # easier and faster switching between next/prev window + bind C-p previous-window + bind C-n next-window + +Above bindings enhance the default `prefix + p` and `prefix + n` bindings by +allowing you to hold `Ctrl` and repeat `a + p`/`a + n` (if your prefix is +`C-a`), which is a lot quicker. + + # source .tmux.conf as suggested in `man tmux` + bind R source-file '~/.tmux.conf' + +"Adaptable" key bindings that build upon your `prefix` value: + + # if prefix is 'C-a' + bind C-a send-prefix + bind a last-window + +If prefix is `C-b`, above keys will be `C-b` and `b`.
+If prefix is `C-z`, above keys will be `C-z` and `z`... you get the idea. + +### 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 @plugin 'tmux-plugins/tmux-sensible' + +Hit `prefix + I` to fetch the plugin and source it. That's it! + +### Manual Installation + +Clone the repo: + + $ git clone https://github.com/tmux-plugins/tmux-sensible ~/clone/path + +Add this line to the bottom of `.tmux.conf`: + + run-shell ~/clone/path/sensible.tmux + +Reload TMUX environment with `$ tmux source-file ~/.tmux.conf`, and that's it. + +### Other goodies + +You might also find these useful: + +- [copycat](https://github.com/tmux-plugins/tmux-copycat) + improve tmux search and reduce mouse usage +- [pain control](https://github.com/tmux-plugins/tmux-pain-control) + useful standard bindings for controlling panes +- [resurrect](https://github.com/tmux-plugins/tmux-resurrect) + persists tmux environment across system restarts + +### License + +[MIT](LICENSE.md) diff --git a/filesystem/root/.tmux/plugins/tmux-sensible/sensible.tmux b/filesystem/root/.tmux/plugins/tmux-sensible/sensible.tmux new file mode 100755 index 00000000..9d6fcf5c --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-sensible/sensible.tmux @@ -0,0 +1,161 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# used to match output from `tmux list-keys` +KEY_BINDING_REGEX="bind-key[[:space:]]\+\(-r[[:space:]]\+\)\?\(-T prefix[[:space:]]\+\)\?" + +is_osx() { + local platform=$(uname) + [ "$platform" == "Darwin" ] +} + +iterm_terminal() { + [[ "$TERM_PROGRAM" =~ ^iTerm ]] +} + +command_exists() { + local command="$1" + type "$command" >/dev/null 2>&1 +} + +# returns prefix key, e.g. 'C-a' +prefix() { + tmux show-option -gv prefix +} + +# if prefix is 'C-a', this function returns 'a' +prefix_without_ctrl() { + local prefix="$(prefix)" + echo "$prefix" | cut -d '-' -f2 +} + +option_value_not_changed() { + local option="$1" + local default_value="$2" + local option_value=$(tmux show-option -gv "$option") + [ "$option_value" == "$default_value" ] +} + +server_option_value_not_changed() { + local option="$1" + local default_value="$2" + local option_value=$(tmux show-option -sv "$option") + [ "$option_value" == "$default_value" ] +} + +key_binding_not_set() { + local key="$1" + if $(tmux list-keys | grep -q "${KEY_BINDING_REGEX}${key}[[:space:]]"); then + return 1 + else + return 0 + fi +} + +key_binding_not_changed() { + local key="$1" + local default_value="$2" + if $(tmux list-keys | grep -q "${KEY_BINDING_REGEX}${key}[[:space:]]\+${default_value}"); then + # key still has the default binding + return 0 + else + return 1 + fi +} + +main() { + # OPTIONS + + # enable utf8 (option removed in tmux 2.2) + tmux set-option -g utf8 on 2>/dev/null + + # enable utf8 in tmux status-left and status-right (option removed in tmux 2.2) + tmux set-option -g status-utf8 on 2>/dev/null + + # address vim mode switching delay (http://superuser.com/a/252717/65504) + if server_option_value_not_changed "escape-time" "500"; then + tmux set-option -s escape-time 0 + fi + + # increase scrollback buffer size + if option_value_not_changed "history-limit" "2000"; then + tmux set-option -g history-limit 50000 + fi + + # tmux messages are displayed for 4 seconds + if option_value_not_changed "display-time" "750"; then + tmux set-option -g display-time 4000 + fi + + # refresh 'status-left' and 'status-right' more often + if option_value_not_changed "status-interval" "15"; then + tmux set-option -g status-interval 5 + fi + + # required (only) on OS X + if is_osx && command_exists "reattach-to-user-namespace" && option_value_not_changed "default-command" ""; then + tmux set-option -g default-command "reattach-to-user-namespace -l $SHELL" + fi + + # upgrade $TERM, tmux 1.9 + if option_value_not_changed "default-terminal" "screen"; then + tmux set-option -g default-terminal "screen-256color" + fi + # upgrade $TERM, tmux 2.0+ + if server_option_value_not_changed "default-terminal" "screen"; then + tmux set-option -s default-terminal "screen-256color" + fi + + # emacs key bindings in tmux command prompt (prefix + :) are better than + # vi keys, even for vim users + tmux set-option -g status-keys emacs + + # focus events enabled for terminals that support them + tmux set-option -g focus-events on + + # super useful when using "grouped sessions" and multi-monitor setup + if ! iterm_terminal; then + tmux set-window-option -g aggressive-resize on + fi + + # DEFAULT KEY BINDINGS + + local prefix="$(prefix)" + local prefix_without_ctrl="$(prefix_without_ctrl)" + + # if C-b is not prefix + if [ $prefix != "C-b" ]; then + # unbind obsolte default binding + if key_binding_not_changed "C-b" "send-prefix"; then + tmux unbind-key C-b + fi + + # pressing `prefix + prefix` sends to the shell + if key_binding_not_set "$prefix"; then + tmux bind-key "$prefix" send-prefix + fi + fi + + # If Ctrl-a is prefix then `Ctrl-a + a` switches between alternate windows. + # Works for any prefix character. + if key_binding_not_set "$prefix_without_ctrl"; then + tmux bind-key "$prefix_without_ctrl" last-window + fi + + # easier switching between next/prev window + if key_binding_not_set "C-p"; then + tmux bind-key C-p previous-window + fi + if key_binding_not_set "C-n"; then + tmux bind-key C-n next-window + fi + + # source `.tmux.conf` file - as suggested in `man tmux` + if key_binding_not_set "R"; then + tmux bind-key R run-shell ' \ + tmux source-file ~/.tmux.conf > /dev/null; \ + tmux display-message "Sourced .tmux.conf!"' + fi +} +main diff --git a/filesystem/root/.tmux/plugins/tpm/.travis.yml b/filesystem/root/.tmux/plugins/tpm/.travis.yml new file mode 100644 index 00000000..ac45d8bc --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/.travis.yml @@ -0,0 +1,19 @@ +# generic packages and tmux +before_install: + - sudo apt-get update + - sudo apt-get install -y git-core expect + - sudo apt-get install -y python-software-properties software-properties-common + - sudo apt-get install -y libevent-dev libncurses-dev + - git clone https://github.com/tmux/tmux.git + - cd tmux + - git checkout 2.0 + - sh autogen.sh + - ./configure && make && sudo make install + +install: + - git fetch --unshallow --recurse-submodules || git fetch --recurse-submodules + # manual `git clone` required for testing `tmux-test` plugin itself + - git clone https://github.com/tmux-plugins/tmux-test lib/tmux-test; true + - lib/tmux-test/setup + +script: ./tests/run_tests_in_isolation diff --git a/filesystem/root/.tmux/plugins/tpm/CHANGELOG.md b/filesystem/root/.tmux/plugins/tpm/CHANGELOG.md new file mode 100644 index 00000000..672d3e71 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/CHANGELOG.md @@ -0,0 +1,83 @@ +# Changelog + +### master +- upgrade to new version of `tmux-test` +- bug: when using `emacs` copy mode, Enter does not quit screen after tpm + installation/update. Fix by making `Escape` the key for emacs mode. +- add a doc with troubleshooting instructions +- add `.gitattributes` file that forces linefeed characters (classic `\n`) as + line endings - helps with misconfigured git on windows/cygwin +- readme update: announce Cygwin support +- un-deprecate old plugin definition syntax: `set -g @tpm_plugins` + +### v3.0.0, 2015-08-03 +- refactor `shared_set_tpm_path_constant` function +- move all instructions to `docs/` dir +- add `bin/install_plugins` cli executable script +- improved test runner function +- switch to using [tmux-test](https://github.com/tmux-plugins/tmux-test) + framework +- add `bin/update_plugins` cli executable script +- refactor test `expect` scripts, make them simpler and ensure they properly + assert expectations +- refactor code that sets 'TMUX_PLUGIN_MANAGER_PATH' global env var +- stop using global variable for 'tpm path' +- support defining plugins via `set -g @plugin` in sourced files as well + +### v2.0.0, 2015-07-07 +- enable overriding default key bindings +- start using `C-c` to clear screen +- add uninstall/clean procedure and keybinding (prefix+alt+u) (@chilicuil) +- add new `set @plugin 'repo'` plugin defintion syntax (@chilicuil) +- revert back to using `-g` flag in new plugin definition syntax +- permit leading whitespace with new plugin definition syntax (thanks @chilicuil) +- make sure `TMUX_PLUGIN_MANAGER_PATH` always has trailng slash +- ensure old/deprecated plugin syntax `set -g @tpm_plugins` works alongside new + `set -g @plugin` syntax + +### v1.2.2, 2015-02-08 +- set GIT_TERMINAL_PROMPT=0 when doing `git clone`, `pull` or `submodule update` + to ensure git does not prompt for username/password in any case + +### v1.2.1, 2014-11-21 +- change the way plugin name is expanded. It now uses the http username + and password by default, like this: `https://git::@github.com/`. This prevents + username and password prompt (and subsequently tmux install hanging) with old + git versions. Fixes #7. + +### v1.2.0, 2014-11-20 +- refactor tests so they can be used on travis +- add travis.yml, add travis badge to the readme + +### v1.1.0, 2014-11-19 +- if the plugin is not downloaded do not source it +- remove `PLUGINS.md`, an obsolete list of plugins +- update readme with instructions about uninstalling plugins +- tilde char and `$HOME` in `TMUX_SHARED_MANAGER_PATH` couldn't be used because + they are just plain strings. Fixing the problem by manually expanding them. +- bugfix: fragile `*.tmux` file globbing (@majutsushi) + +### v1.0.0, 2014-08-05 +- update readme because of github organization change to + [tmux-plugins](https://github.com/tmux-plugins) +- update tests to pass +- update README to suggest different first plugin +- update list of plugins in the README +- remove README 'about' section +- move key binding to the main file. Delete `key_binding.sh`. +- rename `display_message` -> `echo_message` +- installing plugins installs just new plugins. Already installed plugins aren't + updated. +- add 'update plugin' binding and functionality +- add test for updating a plugin + +### v0.0.2, 2014-07-17 +- run all *.tmux plugin files as executables +- fix all redirects to /dev/null +- fix bug: TPM shared path is created before sync (cloning plugins from github + is done) +- add test suite running in Vagrant +- add Tmux version check. `TPM` won't run if Tmux version is less than 1.9. + +### v0.0.1, 2014-05-21 +- get TPM up and running diff --git a/filesystem/root/.tmux/plugins/tpm/HOW_TO_PLUGIN.md b/filesystem/root/.tmux/plugins/tpm/HOW_TO_PLUGIN.md new file mode 100644 index 00000000..99016192 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/HOW_TO_PLUGIN.md @@ -0,0 +1,2 @@ +Instructions moved to +[docs/how_to_create_plugin.md](docs/how_to_create_plugin.md). diff --git a/filesystem/root/.tmux/plugins/tpm/LICENSE.md b/filesystem/root/.tmux/plugins/tpm/LICENSE.md new file mode 100644 index 00000000..12228654 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/LICENSE.md @@ -0,0 +1,20 @@ +MIT license +Copyright (C) 2014 Bruno Sutic + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/filesystem/root/.tmux/plugins/tpm/README.md b/filesystem/root/.tmux/plugins/tpm/README.md new file mode 100644 index 00000000..647fd6f5 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/README.md @@ -0,0 +1,107 @@ +# Tmux Plugin Manager + +[![Build Status](https://travis-ci.org/tmux-plugins/tpm.png?branch=master)](https://travis-ci.org/tmux-plugins/tpm) + +Installs and loads TMUX plugins. + +Tested and working on Linux, OSX, and Cygwin. + +### Installation + +Requirements: `tmux` version 1.9 (or higher), `git`, `bash`. + +Clone TPM: + + $ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm + +Put this at the bottom of `.tmux.conf`: + + # List of plugins + set -g @plugin 'tmux-plugins/tpm' + set -g @plugin 'tmux-plugins/tmux-sensible' + + # Other examples: + # set -g @plugin 'github_username/plugin_name' + # set -g @plugin 'git@github.com/user/plugin' + # set -g @plugin 'git@bitbucket.com/user/plugin' + + # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) + run '~/.tmux/plugins/tpm/tpm' + +Reload TMUX environment so TPM is sourced: + + # type this in terminal if tmux is already running + $ tmux source ~/.tmux.conf + +That's it! + +### Installing plugins + +1. Add new plugin to `~/.tmux.conf` with `set -g @plugin '...'` +2. Press `prefix + I` (capital I, as in **I**nstall) to fetch the plugin. + +You're good to go! The plugin was cloned to `~/.tmux/plugins/` dir and sourced. + +### Uninstalling plugins + +1. Remove (or comment out) plugin from the list. +2. Press `prefix + alt + u` (lowercase u as in **u**ninstall) to remove the plugin. + +All the plugins are installed to `~/.tmux/plugins/` so alternatively you can +find plugin directory there and remove it. + +### Key bindings + +`prefix + I` +- Installs new plugins from GitHub or any other git repository +- Refreshes TMUX environment + +`prefix + U` +- updates plugin(s) + +`prefix + alt + u` +- remove/uninstall plugins not on the plugin list + +### More plugins + +For more plugins, check [here](https://github.com/tmux-plugins). + +### Docs + +- [Help, tpm not working](docs/tpm_not_working.md) - problem solutions + +More advanced features and instructions, regular users probably do not need +this: + +- [How to create a plugin](docs/how_to_create_plugin.md). It's easy. +- [Managing plugins via the command line](docs/managing_plugins_via_cmd_line.md) +- [Changing plugins install dir](docs/changing_plugins_install_dir.md) +- [Automatic TPM installation on a new machine](docs/automatic_tpm_installation.md) + +### Tests + +Tests for this project run on [travis](https://travis-ci.org/tmux-plugins/tpm). + +When run locally, [vagrant](https://www.vagrantup.com/) is required. +Run tests with: + + # within project directory + $ ./run_tests + +### 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 +- [tmux-continuum](https://github.com/tmux-plugins/tmux-continuum) - automatic + restoring and continuous saving of tmux env + +You might want to follow [@brunosutic](https://twitter.com/brunosutic) on +twitter if you want to hear about new tmux plugins or feature updates. + +### License + +[MIT](LICENSE.md) diff --git a/filesystem/root/.tmux/plugins/tpm/bin/clean_plugins b/filesystem/root/.tmux/plugins/tpm/bin/clean_plugins new file mode 100755 index 00000000..12f87305 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/bin/clean_plugins @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Script intended for use via the command line. +# +# `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system, +# but does not need to be started in order to run this script. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" + +main() { + "$SCRIPTS_DIR/clean_plugins.sh" # has correct exit code +} +main diff --git a/filesystem/root/.tmux/plugins/tpm/bin/install_plugins b/filesystem/root/.tmux/plugins/tpm/bin/install_plugins new file mode 100755 index 00000000..c66b15b3 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/bin/install_plugins @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Script intended for use via the command line. +# +# `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system, +# but does not need to be started in order to run this script. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" + +main() { + "$SCRIPTS_DIR/install_plugins.sh" # has correct exit code +} +main diff --git a/filesystem/root/.tmux/plugins/tpm/bin/update_plugins b/filesystem/root/.tmux/plugins/tpm/bin/update_plugins new file mode 100755 index 00000000..30a56469 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/bin/update_plugins @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# Script intended for use via the command line. +# +# `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system, +# but does not need to be started in order to run this script. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" +PROGRAM_NAME="$0" + +if [ $# -eq 0 ]; then + echo "usage:" + echo " $PROGRAM_NAME all update all plugins" + echo " $PROGRAM_NAME tmux-foo update plugin 'tmux-foo'" + echo " $PROGRAM_NAME tmux-bar tmux-baz update multiple plugins" + exit 1 +fi + +main() { + "$SCRIPTS_DIR/update_plugin.sh" --shell-echo "$*" # has correct exit code +} +main "$*" + diff --git a/filesystem/root/.tmux/plugins/tpm/bindings/clean_plugins b/filesystem/root/.tmux/plugins/tpm/bindings/clean_plugins new file mode 100755 index 00000000..9a0d5d7a --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/bindings/clean_plugins @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# Tmux key-binding script. +# Scripts intended to be used via the command line are in `bin/` directory. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" +HELPERS_DIR="$SCRIPTS_DIR/helpers" + +source "$HELPERS_DIR/tmux_echo_functions.sh" +source "$HELPERS_DIR/tmux_utils.sh" + +main() { + reload_tmux_environment + "$SCRIPTS_DIR/clean_plugins.sh" --tmux-echo >/dev/null 2>&1 + reload_tmux_environment + end_message +} +main diff --git a/filesystem/root/.tmux/plugins/tpm/bindings/install_plugins b/filesystem/root/.tmux/plugins/tpm/bindings/install_plugins new file mode 100755 index 00000000..3ade3c42 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/bindings/install_plugins @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# Tmux key-binding script. +# Scripts intended to be used via the command line are in `bin/` directory. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" +HELPERS_DIR="$SCRIPTS_DIR/helpers" + +source "$HELPERS_DIR/tmux_echo_functions.sh" +source "$HELPERS_DIR/tmux_utils.sh" + +main() { + reload_tmux_environment + "$SCRIPTS_DIR/install_plugins.sh" --tmux-echo >/dev/null 2>&1 + reload_tmux_environment + end_message +} +main diff --git a/filesystem/root/.tmux/plugins/tpm/bindings/update_plugins b/filesystem/root/.tmux/plugins/tpm/bindings/update_plugins new file mode 100755 index 00000000..28cc281b --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/bindings/update_plugins @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# Tmux key-binding script. +# Scripts intended to be used via the command line are in `bin/` directory. + +# This script: +# - shows a list of installed plugins +# - starts a prompt to enter the name of the plugin that will be updated + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" +HELPERS_DIR="$SCRIPTS_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" +source "$HELPERS_DIR/tmux_echo_functions.sh" +source "$HELPERS_DIR/tmux_utils.sh" + +display_plugin_update_list() { + local plugins="$(tpm_plugins_list_helper)" + tmux_echo "Installed plugins:" + tmux_echo "" + + for plugin in $plugins; do + # displaying only installed plugins + if plugin_already_installed "$plugin"; then + local plugin_name="$(plugin_name_helper "$plugin")" + tmux_echo " $plugin_name" + fi + done + + tmux_echo "" + tmux_echo "Type plugin name to update it." + tmux_echo "" + tmux_echo "- \"all\" - updates all plugins" + tmux_echo "- ENTER - cancels" +} + +update_plugin_prompt() { + tmux command-prompt -p 'plugin update:' " \ + send-keys C-c; \ + run-shell '$SCRIPTS_DIR/update_plugin_prompt_handler.sh %1'" +} + +main() { + reload_tmux_environment + display_plugin_update_list + update_plugin_prompt +} +main diff --git a/filesystem/root/.tmux/plugins/tpm/docs/automatic_tpm_installation.md b/filesystem/root/.tmux/plugins/tpm/docs/automatic_tpm_installation.md new file mode 100644 index 00000000..630573f3 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/docs/automatic_tpm_installation.md @@ -0,0 +1,12 @@ +# Automatic tpm installation + +One of the first things we do on a new machine is cloning our dotfiles. Not everything comes with them though, so for example `tpm` most likely won't be installed. + +If you want to install `tpm` and plugins automatically when tmux is started, put the following snippet in `.tmux.conf` before the final `run '~/.tmux/plugins/tpm/tpm'`: + +``` +if "test ! -d ~/.tmux/plugins/tpm" \ + "run 'git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm && ~/.tmux/plugins/tpm/bin/install_plugins'" +``` + +This useful tip was submitted by @acr4 and narfman0. diff --git a/filesystem/root/.tmux/plugins/tpm/docs/changing_plugins_install_dir.md b/filesystem/root/.tmux/plugins/tpm/docs/changing_plugins_install_dir.md new file mode 100644 index 00000000..93af6757 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/docs/changing_plugins_install_dir.md @@ -0,0 +1,14 @@ +# Changing plugins install dir + +By default, TPM installs plugins to `~/.tmux/plugins/`. + +You can change the install path by putting this in `.tmux.conf`: + + set-environment -g TMUX_PLUGIN_MANAGER_PATH '/some/other/path/' + +Tmux plugin manager initialization in `.tmux.conf` should also be updated: + + # initializes TMUX plugin manager in a new path + run /some/other/path/tpm/tpm + +Please make sure that the `run` line is at the very bottom of `.tmux.conf`. diff --git a/filesystem/root/.tmux/plugins/tpm/docs/how_to_create_plugin.md b/filesystem/root/.tmux/plugins/tpm/docs/how_to_create_plugin.md new file mode 100644 index 00000000..b1a68f93 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/docs/how_to_create_plugin.md @@ -0,0 +1,108 @@ +# How to create Tmux plugins + +Creating a new plugin is easy. + +For demonstration purposes we'll create a simple plugin that lists all +installed TPM plugins. Yes, a plugin that lists plugins :) We'll bind that to +`prefix + T`. + +The source code for this example plugin can be found +[here](https://github.com/tmux-plugins/tmux-example-plugin). + +### 1. create a new git project + +TPM depends on git for downloading and updating plugins. + +To create a new git project: + + $ mkdir tmux_my_plugin + $ cd tmux_my_plugin + $ git init + +### 2. create a `*.tmux` plugin run file + +When it sources a plugin, TPM executes all `*.tmux` files in your plugins' +directory. That's how plugins are run. + +Create a plugin run file in plugin directory: + + $ touch my_plugin.tmux + $ chmod u+x my_plugin.tmux + +You can have more than one `*.tmux` file, and all will get executed. However, usually +you'll need just one. + +### 3. create a plugin key binding + +We want the behavior of the plugin to trigger when a user hits `prefix + T`. + +Key `T` is chosen because: + - it's "kind of" a mnemonic for `TPM` + - the key is not used by Tmux natively. Tmux man page, KEY BINDINGS section + contains a list of all the bindings Tmux uses. There's plenty of unused keys + and we don't want to override any of Tmux default key bindings. + +Open the plugin run file in your favorite text editor: + + $ vim my_plugin.tmux + # or + $ subl my_plugin.tmux + +Put the following content in the file: + + #!/usr/bin/env bash + + CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + tmux bind-key T run-shell "$CURRENT_DIR/scripts/tmux_list_plugins.sh" + +As you can see, plugin run file is a simple bash script that sets up the binding. + +When pressed, `prefix + T` will execute another shell script: +`tmux_list_plugins.sh`. That script should be in `scripts/` directory - +relative to the plugin run file. + + +### 4. listing plugins + +Now that we have the binding, let's create a script that's invoked with +`prefix + T`. + + $ mkdir scripts + $ touch scripts/tmux_list_plugins.sh + $ chmod u+x scripts/tmux_list_plugins.sh + +And here's the script content: + + #!/usr/bin/env bash + + # fetching the directory where plugins are installed + plugin_path="$(tmux show-env -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)" + + # listing installed plugins + ls -1 "$plugin_path" + +### 5. try it out + +To see if this works, execute the plugin run file: + + $ ./my_plugin.tmux + +That should set up the key binding. Now hit `prefix + T` and see if it works. + +### 6. publish the plugin + +When everything is ready, push the plugin to an online git repository, +preferably Github. + +Other users can install your plugin by just adding plugin git URL to the +`@plugin` list in their `.tmux.conf`. + +If the plugin is on Github, your users will be able to use the shorthand of +`github_username/repository`. + +### Conclusion + +Hopefully, that was easy. As you can see, it's mostly shell scripting. + +You can use other scripting languages (ruby, python etc) but plain old shell +is preferred because of portability. diff --git a/filesystem/root/.tmux/plugins/tpm/docs/managing_plugins_via_cmd_line.md b/filesystem/root/.tmux/plugins/tpm/docs/managing_plugins_via_cmd_line.md new file mode 100644 index 00000000..7aefd7d1 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/docs/managing_plugins_via_cmd_line.md @@ -0,0 +1,36 @@ +# Managing plugins via the command line + +Aside from tmux key bindings, TPM provides shell interface for managing plugins +via scripts located in [bin/](../bin/) directory. + +Tmux does not need to be started in order to run scripts (but it's okay if it +is). If you [changed tpm install dir](../docs/changing_plugins_install_dir.md) +in `.tmux.conf` that should work fine too. + +Prerequisites: + +- tmux installed on the system (doh) +- `.tmux.conf` set up for TPM + +### Installing plugins + +As usual, plugins need to be specified in `.tmux.conf`. Run the following +command to install plugins: + + ~/.tmux/plugins/tpm/bin/install_plugins + +### Updating plugins + +To update all installed plugins: + + ~/.tmux/plugins/tpm/bin/update_plugins all + +or update a single plugin: + + ~/.tmux/plugins/tpm/bin/update_plugins tmux-sensible + +### Removing plugins + +To remove plugins not on the plugin list: + + ~/.tmux/plugins/tpm/bin/clean_plugins diff --git a/filesystem/root/.tmux/plugins/tpm/docs/tpm_not_working.md b/filesystem/root/.tmux/plugins/tpm/docs/tpm_not_working.md new file mode 100644 index 00000000..87d29984 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/docs/tpm_not_working.md @@ -0,0 +1,80 @@ +# Help, tpm not working! + +Here's the list of issues users had with `tpm`: + +
+ +> Nothing works. `tpm` key bindings `prefix + I`, `prefix + U` not even + defined. + +Related [issue #22](https://github.com/tmux-plugins/tpm/issues/22) + +- Do you have required `tmux` version to run `tpm`?
+ Check `tmux` version with `$ tmux -V` command and make sure it's higher or + equal to the required version for `tpm` as stated in the readme. + +- ZSH tmux plugin might be causing issues.
+ If you have it installed, try disabling it and see if `tpm` works then. + +
+ +> Help, I'm using custom config file with `tmux -f /path/to/my_tmux.conf` +to start Tmux and for some reason plugins aren't loaded!? + +Related [issue #57](https://github.com/tmux-plugins/tpm/issues/57) + +`tpm` has a known issue when using custom config file with `-f` option. +The solution is to use alternative plugin definition syntax. Here are the steps +to make it work: + +1. remove all `set -g @plugin` lines from tmux config file +2. in the config file define the plugins in the following way: + + # List of plugins + set -g @tpm_plugins ' \ + tmux-plugins/tpm \ + tmux-plugins/tmux-sensible \ + tmux-plugins/tmux-resurrect \ + ' + + # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) + run '~/.tmux/plugins/tpm/tpm' + +3. Reload TMUX environment so TPM is sourced: `$ tmux source /path/to/my_tmux.conf` + +The plugins should now be working. + +
+ +> Weird sequence of characters show up when installing or updating plugins + +Related: [issue #25](https://github.com/tmux-plugins/tpm/issues/25) + +- This could be caused by [tmuxline.vim](https://github.com/edkolev/tmuxline.vim) + plugin. Uninstall it and see if things work. + +
+ +> "failed to connect to server" error when sourcing .tmux.conf + +Related: [issue #48](https://github.com/tmux-plugins/tpm/issues/48) + +- Make sure `tmux source ~/.tmux.conf` command is ran from inside `tmux`. + +
+ +> tpm not working: '~/.tmux/plugins/tpm/tpm' returned 2 (Windows / Cygwin) + +Related: [issue #81](https://github.com/tmux-plugins/tpm/issues/81) + +This issue is most likely caused by Windows line endings. For example, if you +have git's `core.autocrlf` option set to `true`, git will automatically convert +all the files to Windows line endings which might cause a problem. + +The solution is to convert all line ending to Unix newline characters. This +command handles that for all files under `.tmux/` dir (skips `.git` +subdirectories): + +```bash +find ~/.tmux -type d -name '.git*' -prune -o -type f -print0 | xargs -0 dos2unix +``` diff --git a/filesystem/root/.tmux/plugins/tpm/scripts/check_tmux_version.sh b/filesystem/root/.tmux/plugins/tpm/scripts/check_tmux_version.sh new file mode 100755 index 00000000..b0aedece --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/scripts/check_tmux_version.sh @@ -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 diff --git a/filesystem/root/.tmux/plugins/tpm/scripts/clean_plugins.sh b/filesystem/root/.tmux/plugins/tpm/scripts/clean_plugins.sh new file mode 100755 index 00000000..a0255246 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/scripts/clean_plugins.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" +source "$HELPERS_DIR/utility.sh" + +if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions + source "$HELPERS_DIR/tmux_echo_functions.sh" +else # shell output functions + source "$HELPERS_DIR/shell_echo_functions.sh" +fi + +clean_plugins() { + local plugins plugin plugin_directory + plugins="$(tpm_plugins_list_helper)" + + for plugin_directory in "$(tpm_path)"/*; do + [ -d "${plugin_directory}" ] || continue + plugin="$(plugin_name_helper "${plugin_directory}")" + case "${plugins}" in + *"${plugin}"*) : ;; + *) + [ "${plugin}" = "tpm" ] && continue + echo_ok "Removing \"$plugin\"" + rm -rf "${plugin_directory}" >/dev/null 2>&1 + [ -d "${plugin_directory}" ] && + echo_err " \"$plugin\" clean fail" || + echo_ok " \"$plugin\" clean success" + ;; + esac + done +} + +main() { + ensure_tpm_path_exists + clean_plugins + exit_value_helper +} +main diff --git a/filesystem/root/.tmux/plugins/tpm/scripts/helpers/plugin_functions.sh b/filesystem/root/.tmux/plugins/tpm/scripts/helpers/plugin_functions.sh new file mode 100644 index 00000000..d2778d59 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/scripts/helpers/plugin_functions.sh @@ -0,0 +1,86 @@ +# using @tpm_plugins is now deprecated in favor of using @plugin syntax +tpm_plugins_variable_name="@tpm_plugins" + +# manually expanding tilde char or `$HOME` variable. +_manual_expansion() { + local path="$1" + local expanded_tilde="${path/#\~/$HOME}" + echo "${expanded_tilde/#\$HOME/$HOME}" +} + +_tpm_path() { + local string_path="$(tmux start-server\; show-environment -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)/" + _manual_expansion "$string_path" +} + +_CACHED_TPM_PATH="$(_tpm_path)" + +_tmux_conf_contents() { + cat /etc/tmux.conf ~/.tmux.conf 2>/dev/null + if [ "$1" == "full" ]; then # also output content from sourced files + local file + for file in $(_sourced_files); do + cat $(_manual_expansion "$file") 2>/dev/null + done + fi +} + +# return files sourced from tmux config files +_sourced_files() { + _tmux_conf_contents | + awk '/^[ \t]*source(-file)? +/ { gsub(/'\''/,""); gsub(/'\"'/,""); print $2 }' +} + +# Want to be able to abort in certain cases +trap "exit 1" TERM +export TOP_PID=$$ + +_fatal_error_abort() { + echo >&2 "Aborting." + kill -s TERM $TOP_PID +} + +# PUBLIC FUNCTIONS BELOW + +tpm_path() { + if [ "$_CACHED_TPM_PATH" == "/" ]; then + echo >&2 "FATAL: Tmux Plugin Manager not configured in tmux.conf" + _fatal_error_abort + fi + echo "$_CACHED_TPM_PATH" +} + +tpm_plugins_list_helper() { + # lists plugins from @tpm_plugins option + echo "$(tmux start-server\; show-option -gqv "$tpm_plugins_variable_name")" + + # read set -g @plugin "tmux-plugins/tmux-example-plugin" entries + _tmux_conf_contents "full" | + awk '/^[ \t]*set(-option)? +-g +@plugin/ { gsub(/'\''/,""); gsub(/'\"'/,""); print $4 }' +} + +# Allowed plugin name formats: +# 1. "git://github.com/user/plugin_name.git" +# 2. "user/plugin_name" +plugin_name_helper() { + local plugin="$1" + # get only the part after the last slash, e.g. "plugin_name.git" + local plugin_basename="$(basename "$plugin")" + # remove ".git" extension (if it exists) to get only "plugin_name" + local plugin_name="${plugin_basename%.git}" + echo "$plugin_name" +} + +plugin_path_helper() { + local plugin="$1" + local plugin_name="$(plugin_name_helper "$plugin")" + echo "$(tpm_path)${plugin_name}/" +} + +plugin_already_installed() { + local plugin="$1" + local plugin_path="$(plugin_path_helper "$plugin")" + [ -d "$plugin_path" ] && + cd "$plugin_path" && + git remote >/dev/null 2>&1 +} diff --git a/filesystem/root/.tmux/plugins/tpm/scripts/helpers/shell_echo_functions.sh b/filesystem/root/.tmux/plugins/tpm/scripts/helpers/shell_echo_functions.sh new file mode 100644 index 00000000..ecaa37e4 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/scripts/helpers/shell_echo_functions.sh @@ -0,0 +1,7 @@ +echo_ok() { + echo "$*" +} + +echo_err() { + fail_helper "$*" +} diff --git a/filesystem/root/.tmux/plugins/tpm/scripts/helpers/tmux_echo_functions.sh b/filesystem/root/.tmux/plugins/tpm/scripts/helpers/tmux_echo_functions.sh new file mode 100644 index 00000000..7a6ef0a0 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/scripts/helpers/tmux_echo_functions.sh @@ -0,0 +1,28 @@ +_has_emacs_mode_keys() { + $(tmux show -gw mode-keys | grep -q emacs) +} + +tmux_echo() { + local message="$1" + tmux run-shell "echo '$message'" +} + +echo_ok() { + tmux_echo "$*" +} + +echo_err() { + tmux_echo "$*" +} + +end_message() { + if _has_emacs_mode_keys; then + local continue_key="ESCAPE" + else + local continue_key="ENTER" + fi + tmux_echo "" + tmux_echo "TMUX environment reloaded." + tmux_echo "" + tmux_echo "Done, press $continue_key to continue." +} diff --git a/filesystem/root/.tmux/plugins/tpm/scripts/helpers/tmux_utils.sh b/filesystem/root/.tmux/plugins/tpm/scripts/helpers/tmux_utils.sh new file mode 100644 index 00000000..e39946ad --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/scripts/helpers/tmux_utils.sh @@ -0,0 +1,3 @@ +reload_tmux_environment() { + tmux source-file ~/.tmux.conf >/dev/null 2>&1 +} diff --git a/filesystem/root/.tmux/plugins/tpm/scripts/helpers/utility.sh b/filesystem/root/.tmux/plugins/tpm/scripts/helpers/utility.sh new file mode 100644 index 00000000..de6eb35f --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/scripts/helpers/utility.sh @@ -0,0 +1,17 @@ +ensure_tpm_path_exists() { + mkdir -p "$(tpm_path)" +} + +fail_helper() { + local message="$1" + echo "$message" >&2 + FAIL="true" +} + +exit_value_helper() { + if [ "$FAIL" == "true" ]; then + exit 1 + else + exit 0 + fi +} diff --git a/filesystem/root/.tmux/plugins/tpm/scripts/install_plugins.sh b/filesystem/root/.tmux/plugins/tpm/scripts/install_plugins.sh new file mode 100755 index 00000000..7958ab53 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/scripts/install_plugins.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" +source "$HELPERS_DIR/utility.sh" + +if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions + source "$HELPERS_DIR/tmux_echo_functions.sh" +else # shell output functions + source "$HELPERS_DIR/shell_echo_functions.sh" +fi + +clone() { + local plugin="$1" + cd "$(tpm_path)" && + GIT_TERMINAL_PROMPT=0 git clone --recursive "$plugin" >/dev/null 2>&1 +} + +# tries cloning: +# 1. plugin name directly - works if it's a valid git url +# 2. expands the plugin name to point to a github repo and tries cloning again +clone_plugin() { + local plugin="$1" + clone "$plugin" || + clone "https://git::@github.com/$plugin" +} + +# clone plugin and produce output +install_plugin() { + local plugin="$1" + local plugin_name="$(plugin_name_helper "$plugin")" + + if plugin_already_installed "$plugin"; then + echo_ok "Already installed \"$plugin_name\"" + else + echo_ok "Installing \"$plugin_name\"" + clone_plugin "$plugin" && + echo_ok " \"$plugin_name\" download success" || + echo_err " \"$plugin_name\" download fail" + fi +} + +install_plugins() { + local plugins="$(tpm_plugins_list_helper)" + for plugin in $plugins; do + install_plugin "$plugin" + done +} + +verify_tpm_path_permissions() { + local path="$(tpm_path)" + # check the write permission flag for all users to ensure + # that we have proper access + [ -w "$path" ] || + echo_err "$path is not writable!" +} + +main() { + ensure_tpm_path_exists + verify_tpm_path_permissions + install_plugins + exit_value_helper +} +main diff --git a/filesystem/root/.tmux/plugins/tpm/scripts/source_plugins.sh b/filesystem/root/.tmux/plugins/tpm/scripts/source_plugins.sh new file mode 100755 index 00000000..bb79c26d --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/scripts/source_plugins.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" + +plugin_dir_exists() { + [ -d "$1" ] +} + +# Runs all *.tmux files from the plugin directory. +# Files are ran as executables. +# No errors if the plugin dir does not exist. +silently_source_all_tmux_files() { + local plugin_path="$1" + local plugin_tmux_files="$plugin_path*.tmux" + if plugin_dir_exists "$plugin_path"; then + for tmux_file in $plugin_tmux_files; do + # if the glob didn't find any files this will be the + # unexpanded glob which obviously doesn't exist + [ -f "$tmux_file" ] || continue + # runs *.tmux file as an executable + $tmux_file >/dev/null 2>&1 + done + fi +} + +source_plugins() { + local plugin plugin_path + local plugins="$(tpm_plugins_list_helper)" + for plugin in $plugins; do + plugin_path="$(plugin_path_helper "$plugin")" + silently_source_all_tmux_files "$plugin_path" + done +} + +main() { + source_plugins +} +main diff --git a/filesystem/root/.tmux/plugins/tpm/scripts/update_plugin.sh b/filesystem/root/.tmux/plugins/tpm/scripts/update_plugin.sh new file mode 100755 index 00000000..7d856eec --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/scripts/update_plugin.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +# this script handles core logic of updating plugins + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" +source "$HELPERS_DIR/utility.sh" + +if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions + source "$HELPERS_DIR/tmux_echo_functions.sh" +else # shell output functions + source "$HELPERS_DIR/shell_echo_functions.sh" +fi + +# from now on ignore first script argument +shift + +pull_changes() { + local plugin="$1" + local plugin_path="$(plugin_path_helper "$plugin")" + cd "$plugin_path" && + GIT_TERMINAL_PROMPT=0 git pull && + GIT_TERMINAL_PROMPT=0 git submodule update --init --recursive +} + +update() { + local plugin="$1" + $(pull_changes "$plugin" > /dev/null 2>&1) && + echo_ok " \"$plugin\" update success" || + echo_err " \"$plugin\" update fail" +} + +update_all() { + echo_ok "Updating all plugins!" + echo_ok "" + local plugins="$(tpm_plugins_list_helper)" + for plugin in $plugins; do + local plugin_name="$(plugin_name_helper "$plugin")" + # updating only installed plugins + if plugin_already_installed "$plugin_name"; then + update "$plugin_name" & + fi + done + wait +} + +update_plugins() { + local plugins="$*" + for plugin in $plugins; do + local plugin_name="$(plugin_name_helper "$plugin")" + if plugin_already_installed "$plugin_name"; then + update "$plugin_name" & + else + echo_err "$plugin_name not installed!" & + fi + done + wait +} + +main() { + ensure_tpm_path_exists + if [ "$1" == "all" ]; then + update_all + else + update_plugins "$*" + fi + exit_value_helper +} +main "$*" diff --git a/filesystem/root/.tmux/plugins/tpm/scripts/update_plugin_prompt_handler.sh b/filesystem/root/.tmux/plugins/tpm/scripts/update_plugin_prompt_handler.sh new file mode 100755 index 00000000..5e1f7d91 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/scripts/update_plugin_prompt_handler.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +if [ $# -eq 0 ]; then + exit 0 +fi + +source "$HELPERS_DIR/tmux_echo_functions.sh" +source "$HELPERS_DIR/tmux_utils.sh" + +main() { + "$CURRENT_DIR/update_plugin.sh" --tmux-echo "$*" + reload_tmux_environment + end_message +} +main "$*" diff --git a/filesystem/root/.tmux/plugins/tpm/scripts/variables.sh b/filesystem/root/.tmux/plugins/tpm/scripts/variables.sh new file mode 100644 index 00000000..5601a866 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/scripts/variables.sh @@ -0,0 +1,13 @@ +install_key_option="@tpm-install" +default_install_key="I" + +update_key_option="@tpm-update" +default_update_key="U" + +clean_key_option="@tpm-clean" +default_clean_key="M-u" + +SUPPORTED_TMUX_VERSION="1.9" + +DEFAULT_TPM_ENV_VAR_NAME="TMUX_PLUGIN_MANAGER_PATH" +DEFAULT_TPM_PATH="$HOME/.tmux/plugins/" diff --git a/filesystem/root/.tmux/plugins/tpm/tests/expect_failed_plugin_download b/filesystem/root/.tmux/plugins/tpm/tests/expect_failed_plugin_download new file mode 100755 index 00000000..b9704771 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/tests/expect_failed_plugin_download @@ -0,0 +1,36 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + I +send "I" + +# cloning might take a while +set timeout 20 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installing \"non-existing-plugin\"" +} + +expect { + "\"non-existing-plugin\" download fail" +} + +expect { + "Done, press ENTER to continue" { + exit 0 + } +} + +exit 1 diff --git a/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_clean_plugins b/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_clean_plugins new file mode 100755 index 00000000..987c49d1 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_clean_plugins @@ -0,0 +1,35 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + alt + u +send "u" + +set timeout 5 + +expect_after { + timeout { exit 1 } +} + +expect { + "Removing \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" clean success" +} + +expect { + "Done, press ENTER to continue." { + exit 0 + } +} + +exit 1 diff --git a/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_multiple_plugins_download b/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_multiple_plugins_download new file mode 100755 index 00000000..cc87a26c --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_multiple_plugins_download @@ -0,0 +1,44 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + I +send "I" + +# cloning might take a while +set timeout 15 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installing \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" download success" +} + +expect { + "Installing \"tmux-copycat\"" +} + +expect { + "\"tmux-copycat\" download success" +} + +expect { + "Done, press ENTER to continue." { + exit 0 + } +} + +exit 1 diff --git a/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_plugin_download b/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_plugin_download new file mode 100755 index 00000000..388f05d5 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_plugin_download @@ -0,0 +1,50 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + I +send "I" + +# cloning might take a while +set timeout 15 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installing \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" download success" +} + +expect { + "Done, press ENTER to continue" { + send " " + } +} + +sleep 1 +# this is tmux prefix + I +send "I" + +expect { + "Already installed \"tmux-example-plugin\"" +} + +expect { + "Done, press ENTER to continue" { + exit 0 + } +} + +exit 1 diff --git a/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_update_of_a_single_plugin b/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_update_of_a_single_plugin new file mode 100755 index 00000000..bcd64fe6 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_update_of_a_single_plugin @@ -0,0 +1,55 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + U +send "U" + +set timeout 15 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installed plugins" +} + +expect { + "tmux-example-plugin" +} + +expect { + "\"all\" - updates all plugins" +} + +expect { + "ENTER - cancels" +} + +# wait for tmux to display prompt before sending characters +sleep 1 +send "tmux-example-plugin\r" + +expect { + "Updating \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" update success" +} + +expect { + "Done, press ENTER to continue." { + exit 0 + } +} + +exit 1 diff --git a/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_update_of_all_plugins b/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_update_of_all_plugins new file mode 100755 index 00000000..4f3a4a38 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/tests/expect_successful_update_of_all_plugins @@ -0,0 +1,59 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + U +send "U" + +set timeout 5 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installed plugins" +} + +expect { + "tmux-example-plugin" +} + +expect { + "\"all\" - updates all plugins" +} + +expect { + "ENTER - cancels" +} + +# wait for tmux to display prompt before sending characters +sleep 1 +send "all\r" + +expect { + "Updating all plugins!" +} + +expect { + "Updating \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" update success" +} + +expect { + "Done, press ENTER to continue." { + exit 0 + } +} + +exit 1 diff --git a/filesystem/root/.tmux/plugins/tpm/tests/helpers/tpm.sh b/filesystem/root/.tmux/plugins/tpm/tests/helpers/tpm.sh new file mode 100644 index 00000000..1594afb9 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/tests/helpers/tpm.sh @@ -0,0 +1,13 @@ +check_dir_exists_helper() { + [ -d "$1" ] +} + +# runs the scripts and asserts it has the correct output and exit code +script_run_helper() { + local script="$1" + local expected_output="$2" + local expected_exit_code="${3:-0}" + $script 2>&1 | + grep "$expected_output" >/dev/null 2>&1 && # grep -q flag quits the script early + [ "${PIPESTATUS[0]}" -eq "$expected_exit_code" ] +} diff --git a/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_clean.sh b/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_clean.sh new file mode 100755 index 00000000..d36c468c --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_clean.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TPM_DIR="$PWD" +PLUGINS_DIR="$HOME/.tmux/plugins" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +manually_install_the_plugin() { + rm -rf "$PLUGINS_DIR" + mkdir -p "$PLUGINS_DIR" + cd "$PLUGINS_DIR" + git clone --quiet https://github.com/tmux-plugins/tmux-example-plugin +} + +# TMUX KEY-BINDING TESTS + +test_plugin_uninstallation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + + "$CURRENT_DIR/expect_successful_clean_plugins" || + fail_helper "[key-binding] clean fails" + + teardown_helper +} + +# SCRIPT TESTS + +test_plugin_uninstallation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + + script_run_helper "$TPM_DIR/bin/clean_plugins" '"tmux-example-plugin" clean success' || + fail_helper "[script] plugin cleaning fails" + + teardown_helper +} + +test_unsuccessful_plugin_uninstallation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + chmod 000 "$PLUGINS_DIR/tmux-example-plugin" # disable directory deletion + + local expected_exit_code=1 + script_run_helper "$TPM_DIR/bin/clean_plugins" '"tmux-example-plugin" clean fail' "$expected_exit_code" || + fail_helper "[script] unsuccessful plugin cleaning doesn't fail" + + chmod 755 "$PLUGINS_DIR/tmux-example-plugin" # enable directory deletion + + teardown_helper +} + +run_tests diff --git a/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_installation.sh b/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_installation.sh new file mode 100755 index 00000000..94fb674f --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_installation.sh @@ -0,0 +1,284 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PLUGINS_DIR="$HOME/.tmux/plugins" +TPM_DIR="$PWD" + +CUSTOM_PLUGINS_DIR="$HOME/foo/plugins" +ADDITIONAL_CONFIG_FILE_1="$HOME/.tmux/additional_config_file_1" +ADDITIONAL_CONFIG_FILE_2="$HOME/.tmux/additional_config_file_2" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +# TMUX KEY-BINDING TESTS + +test_plugin_installation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_successful_plugin_download" || + fail_helper "[key-binding] plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding] plugin download fails" + + teardown_helper +} + +test_plugin_installation_via_tmux_key_binding_set_option() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set-option -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_successful_plugin_download" || + fail_helper "[key-binding][set-option] plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding][set-option] plugin download fails" + + teardown_helper +} + +test_plugin_installation_custom_dir_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set-environment -g TMUX_PLUGIN_MANAGER_PATH '$CUSTOM_PLUGINS_DIR' + + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_successful_plugin_download" || + fail_helper "[key-binding][custom dir] plugin installation fails" + + check_dir_exists_helper "$CUSTOM_PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding][custom dir] plugin download fails" + + teardown_helper + rm -rf "$CUSTOM_PLUGINS_DIR" +} + +test_non_existing_plugin_installation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/non-existing-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_failed_plugin_download" || + fail_helper "[key-binding] non existing plugin installation doesn't fail" + + teardown_helper +} + +test_multiple_plugins_installation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + \ \ set -g @plugin 'tmux-plugins/tmux-copycat' + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_successful_multiple_plugins_download" || + fail_helper "[key-binding] multiple plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[key-binding] plugin download fails (tmux-copycat)" + + teardown_helper +} + +test_plugins_installation_from_sourced_file_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + source '$ADDITIONAL_CONFIG_FILE_1' + set -g @plugin 'tmux-plugins/tmux-example-plugin' + run-shell "$TPM_DIR/tpm" + HERE + + mkdir ~/.tmux + echo "set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_1" + + "$CURRENT_DIR/expect_successful_multiple_plugins_download" || + fail_helper "[key-binding][sourced file] plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding][sourced file] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[key-binding][sourced file] plugin download fails (tmux-copycat)" + + teardown_helper +} + +test_plugins_installation_from_multiple_sourced_files_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + \ \ source '$ADDITIONAL_CONFIG_FILE_1' + source-file '$ADDITIONAL_CONFIG_FILE_2' + run-shell "$TPM_DIR/tpm" + HERE + + mkdir ~/.tmux + echo "set -g @plugin 'tmux-plugins/tmux-example-plugin'" > "$ADDITIONAL_CONFIG_FILE_1" + echo " set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_2" + + "$CURRENT_DIR/expect_successful_multiple_plugins_download" || + fail_helper "[key-binding][multiple sourced files] plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding][multiple sourced files] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[key-binding][multiple sourced files] plugin download fails (tmux-copycat)" + + teardown_helper +} + +# SCRIPT TESTS + +test_plugin_installation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script] plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script] plugin download fails" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-example-plugin"' || + fail_helper "[script] plugin already installed message fail" + + teardown_helper +} + +test_plugin_installation_custom_dir_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set-environment -g TMUX_PLUGIN_MANAGER_PATH '$CUSTOM_PLUGINS_DIR' + + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script][custom dir] plugin installation fails" + + check_dir_exists_helper "$CUSTOM_PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script][custom dir] plugin download fails" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-example-plugin"' || + fail_helper "[script][custom dir] plugin already installed message fail" + + teardown_helper + rm -rf "$CUSTOM_PLUGINS_DIR" +} + +test_non_existing_plugin_installation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/non-existing-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + local expected_exit_code=1 + script_run_helper "$TPM_DIR/bin/install_plugins" '"non-existing-plugin" download fail' "$expected_exit_code" || + fail_helper "[script] non existing plugin installation doesn't fail" + + teardown_helper +} + +test_multiple_plugins_installation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + \ \ set -g @plugin 'tmux-plugins/tmux-copycat' + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script] multiple plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[script] plugin download fails (tmux-copycat)" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-copycat"' || + fail_helper "[script] multiple plugins already installed message fail" + + teardown_helper +} + +test_plugins_installation_from_sourced_file_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + source '$ADDITIONAL_CONFIG_FILE_1' + set -g @plugin 'tmux-plugins/tmux-example-plugin' + run-shell "$TPM_DIR/tpm" + HERE + + mkdir ~/.tmux + echo "set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_1" + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-copycat" download success' || + fail_helper "[script][sourced file] plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script][sourced file] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[script][sourced file] plugin download fails (tmux-copycat)" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-copycat"' || + fail_helper "[script][sourced file] plugins already installed message fail" + + teardown_helper +} + +test_plugins_installation_from_multiple_sourced_files_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + \ \ source '$ADDITIONAL_CONFIG_FILE_1' + source-file '$ADDITIONAL_CONFIG_FILE_2' + set -g @plugin 'tmux-plugins/tmux-example-plugin' + run-shell "$TPM_DIR/tpm" + HERE + + mkdir ~/.tmux + echo " set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_1" + echo "set -g @plugin 'tmux-plugins/tmux-sensible'" > "$ADDITIONAL_CONFIG_FILE_2" + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-sensible" download success' || + fail_helper "[script][multiple sourced files] plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script][multiple sourced files] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[script][multiple sourced files] plugin download fails (tmux-copycat)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-sensible/" || + fail_helper "[script][multiple sourced files] plugin download fails (tmux-sensible)" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-sensible"' || + fail_helper "[script][multiple sourced files] plugins already installed message fail" + + teardown_helper +} + +run_tests diff --git a/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_installation_legacy.sh b/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_installation_legacy.sh new file mode 100755 index 00000000..b1d0cf6d --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_installation_legacy.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PLUGINS_DIR="$HOME/.tmux/plugins" +TPM_DIR="$PWD" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +# TMUX KEY-BINDING TESTS + +test_plugin_installation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @tpm_plugins "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + # opens tmux and test it with `expect` + $CURRENT_DIR/expect_successful_plugin_download || + fail_helper "[key-binding] plugin installation fails" + + # check plugin dir exists after download + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding] plugin download fails" + + teardown_helper +} + +test_legacy_and_new_syntax_for_plugin_installation_work_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @tpm_plugins " \ + tmux-plugins/tmux-example-plugin \ + " + set -g @plugin 'tmux-plugins/tmux-copycat' + run-shell "$TPM_DIR/tpm" + HERE + + # opens tmux and test it with `expect` + "$CURRENT_DIR"/expect_successful_multiple_plugins_download || + fail_helper "[key-binding] multiple plugins installation fails" + + # check plugin dir exists after download + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[key-binding] plugin download fails (tmux-copycat)" + + teardown_helper +} + +# SCRIPT TESTS + +test_plugin_installation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @tpm_plugins "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script] plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script] plugin download fails" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-example-plugin"' || + fail_helper "[script] plugin already installed message fail" + + teardown_helper +} + +test_legacy_and_new_syntax_for_plugin_installation_work_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @tpm_plugins " \ + tmux-plugins/tmux-example-plugin \ + " + set -g @plugin 'tmux-plugins/tmux-copycat' + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script] multiple plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[script] plugin download fails (tmux-copycat)" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-copycat"' || + fail_helper "[script] multiple plugins already installed message fail" + + teardown_helper +} + +run_tests diff --git a/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_sourcing.sh b/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_sourcing.sh new file mode 100755 index 00000000..c06f1fe9 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_sourcing.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TPM_DIR="$PWD" +PLUGINS_DIR="$HOME/.tmux/plugins" + +CUSTOM_PLUGINS_DIR="$HOME/foo/plugins" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +check_binding_defined() { + local binding="$1" + tmux list-keys | grep -q "$binding" +} + +create_test_plugin_helper() { + local plugin_path="$PLUGINS_DIR/tmux_test_plugin/" + rm -rf "$plugin_path" + mkdir -p "$plugin_path" + + while read line; do + echo "$line" >> "$plugin_path/test_plugin.tmux" + done + chmod +x "$plugin_path/test_plugin.tmux" +} + +check_tpm_path() { + local correct_tpm_path="$1" + local tpm_path="$(tmux start-server\; show-environment -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)" + [ "$correct_tpm_path" == "$tpm_path" ] +} + +test_plugin_sourcing() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "doesnt_matter/tmux_test_plugin" + run-shell "$TPM_DIR/tpm" + HERE + + # manually creates a local tmux plugin + create_test_plugin_helper <<- HERE + tmux bind-key R run-shell foo_command + HERE + + tmux new-session -d # tmux starts detached + check_binding_defined "R run-shell foo_command" || + fail_helper "Plugin sourcing fails" + + teardown_helper +} + +test_default_tpm_path() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + run-shell "$TPM_DIR/tpm" + HERE + + check_tpm_path "${PLUGINS_DIR}/" || + fail_helper "Default TPM path not correct" + + teardown_helper +} + +test_custom_tpm_path() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set-environment -g TMUX_PLUGIN_MANAGER_PATH '$CUSTOM_PLUGINS_DIR' + run-shell "$TPM_DIR/tpm" + HERE + + check_tpm_path "$CUSTOM_PLUGINS_DIR" || + fail_helper "Custom TPM path not correct" + + teardown_helper +} + +run_tests diff --git a/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_update.sh b/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_update.sh new file mode 100755 index 00000000..4924d161 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/tests/test_plugin_update.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TPM_DIR="$PWD" +PLUGINS_DIR="$HOME/.tmux/plugins" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +manually_install_the_plugin() { + mkdir -p "$PLUGINS_DIR" + cd "$PLUGINS_DIR" + git clone --quiet https://github.com/tmux-plugins/tmux-example-plugin +} + +# TMUX KEY-BINDING TESTS + +test_plugin_update_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + + "$CURRENT_DIR/expect_successful_update_of_all_plugins" || + fail_helper "[key-binding] 'update all plugins' fails" + + "$CURRENT_DIR/expect_successful_update_of_a_single_plugin" || + fail_helper "[key-binding] 'update single plugin' fails" + + teardown_helper +} + +# SCRIPT TESTS + +test_plugin_update_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + + local expected_exit_code=1 + script_run_helper "$TPM_DIR/bin/update_plugins" 'usage' "$expected_exit_code" || + fail_helper "[script] running update plugins without args should fail" + + script_run_helper "$TPM_DIR/bin/update_plugins tmux-example-plugin" '"tmux-example-plugin" update success' || + fail_helper "[script] plugin update fails" + + script_run_helper "$TPM_DIR/bin/update_plugins all" '"tmux-example-plugin" update success' || + fail_helper "[script] update all plugins fails" + + teardown_helper +} + +run_tests diff --git a/filesystem/root/.tmux/plugins/tpm/tpm b/filesystem/root/.tmux/plugins/tpm/tpm new file mode 100755 index 00000000..570d58b4 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tpm/tpm @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BINDINGS_DIR="$CURRENT_DIR/bindings" +SCRIPTS_DIR="$CURRENT_DIR/scripts" + +source "$SCRIPTS_DIR/variables.sh" + +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 +} + +tpm_path_set() { + tmux show-environment -g "$DEFAULT_TPM_ENV_VAR_NAME" >/dev/null 2>&1 +} + +set_default_tpm_path() { + tmux set-environment -g "$DEFAULT_TPM_ENV_VAR_NAME" "$DEFAULT_TPM_PATH" +} + +# Ensures TMUX_PLUGIN_MANAGER_PATH global env variable is set. +# +# Put this in `.tmux.conf` to override the default: +# `set-environment -g TMUX_PLUGIN_MANAGER_PATH "/some/other/path/"` +set_tpm_path() { + if ! tpm_path_set; then + set_default_tpm_path + fi +} + +# 1. Fetches plugin names from `@plugin` variables +# 2. Creates full plugin path +# 3. Sources all *.tmux files from each of the plugin directories +# - no errors raised if directory does not exist +# Files are sourced as tmux config files, not as shell scripts! +source_plugins() { + "$SCRIPTS_DIR/source_plugins.sh" >/dev/null 2>&1 +} + +# prefix + I - downloads TPM plugins and reloads TMUX environment +# prefix + U - updates a plugin (or all of them) and reloads TMUX environment +# prefix + alt + u - remove unused TPM plugins and reloads TMUX environment +set_tpm_key_bindings() { + local install_key="$(get_tmux_option "$install_key_option" "$default_install_key")" + tmux bind-key "$install_key" run-shell "$BINDINGS_DIR/install_plugins" + + local update_key="$(get_tmux_option "$update_key_option" "$default_update_key")" + tmux bind-key "$update_key" run-shell "$BINDINGS_DIR/update_plugins" + + local clean_key="$(get_tmux_option "$clean_key_option" "$default_clean_key")" + tmux bind-key "$clean_key" run-shell "$BINDINGS_DIR/clean_plugins" +} + +supported_tmux_version_ok() { + "$SCRIPTS_DIR/check_tmux_version.sh" "$SUPPORTED_TMUX_VERSION" +} + +main() { + if supported_tmux_version_ok; then + set_tpm_path + set_tpm_key_bindings + source_plugins + fi +} +main