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 00000000..7695ad49 Binary files /dev/null and b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_charging.png differ 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 00000000..53c6134d Binary files /dev/null and b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_discharging.png differ 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 00000000..9b3cd82b Binary files /dev/null and b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_full.png differ 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 00000000..c8731f75 Binary files /dev/null and b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_remain.png differ 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 00000000..30359c61 Binary files /dev/null and b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_green.png differ 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 00000000..0ccf4567 Binary files /dev/null and b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_orange.png differ 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 00000000..ed184b0a Binary files /dev/null and b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_red.png differ 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 00000000..386ee63b Binary files /dev/null and b/filesystem/root/.tmux/plugins/tmux-battery/screenshots/battery_status_bg_yellow.png differ diff --git a/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_graph.sh b/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_graph.sh new file mode 100755 index 00000000..906c5e10 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_graph.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/helpers.sh" + +print_graph() { + if [ -z "$1" ]; then + echo "" + elif [ "$1" -lt "20" ]; then + echo "▁" + elif [ "$1" -lt "40" ]; then + echo "▂" + elif [ "$1" -lt "60" ]; then + echo "▃" + elif [ "$1" -lt "80" ]; then + echo "▅" + else + echo "▇" + fi +} + +main() { + local percentage=$($CURRENT_DIR/battery_percentage.sh) + print_graph ${percentage%?} +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_icon.sh b/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_icon.sh new file mode 100755 index 00000000..1aed4c04 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_icon.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/helpers.sh" + +# script global variables +charged_icon="" +charging_icon="" +attached_icon="" +discharging_icon="" + +charged_default="❇ " +charged_default_osx="🔋 " +charging_default="⚡️ " +attached_default="⚠️ " +discharging_default="" + +charged_default() { + if is_osx; then + echo "$charged_default_osx" + else + echo "$charged_default" + fi +} + +# icons are set as script global variables +get_icon_settings() { + charged_icon=$(get_tmux_option "@batt_charged_icon" "$(charged_default)") + charging_icon=$(get_tmux_option "@batt_charging_icon" "$charging_default") + attached_icon=$(get_tmux_option "@batt_attached_icon" "$attached_default") + discharging_icon=$(get_tmux_option "@batt_discharging_icon" "$discharging_default") +} + +print_icon() { + local status=$1 + if [[ $status =~ (charged) ]]; then + printf "$charged_icon" + elif [[ $status =~ (^charging) ]]; then + printf "$charging_icon" + elif [[ $status =~ (^discharging) ]]; then + printf "$discharging_icon" + elif [[ $status =~ (attached) ]]; then + printf "$attached_icon" + fi +} + +main() { + get_icon_settings + local status=$(battery_status) + print_icon "$status" +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_percentage.sh b/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_percentage.sh new file mode 100755 index 00000000..0f7f48bc --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_percentage.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/helpers.sh" + +print_battery_percentage() { + # percentage displayed in the 2nd field of the 2nd row + if command_exists "pmset"; then + pmset -g batt | grep -o "[0-9]\{1,3\}%" + elif command_exists "upower"; then + local batteries=( $(upower -e | grep battery) ) + local energy + local energy_full + for battery in ${batteries[@]}; do + energy=$(upower -i $battery | awk -v nrg="$energy" '/energy:/ {print nrg+$2}') + energy_full=$(upower -i $battery | awk -v nrgfull="$energy_full" '/energy-full:/ {print nrgfull+$2}') + done + echo $energy $energy_full | awk '{printf("%d%%", ($1/$2)*100)}' + elif command_exists "acpi"; then + acpi -b | grep -Eo "[0-9]+%" + fi +} + +main() { + print_battery_percentage +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_remain.sh b/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_remain.sh new file mode 100755 index 00000000..959afc7d --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_remain.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/helpers.sh" + +battery_discharging() { + local status="$(battery_status)" + [[ $status =~ (discharging) ]] +} + +pmset_battery_remaining_time() { + pmset -g batt | grep -o '[0-9]\{1,2\}:[0-9]\{1,2\}' +} + +print_battery_remain() { + if command_exists "pmset"; then + pmset_battery_remaining_time + elif command_exists "upower"; then + battery=$(upower -e | grep battery | head -1) + if is_chrome; then + if battery_discharging; then + upower -i $battery | grep 'time to empty' | awk '{printf "- %s %s left", $4, $5}' + else + upower -i $battery | grep 'time to full' | awk '{printf "- %s %s till full", $4, $5}' + fi + else + upower -i $battery | grep -E '(remain|time to empty)' | awk '{print $(NF-1)}' + fi + elif command_exists "acpi"; then + acpi -b | grep -Eo "[0-9]+:[0-9]+:[0-9]+" + fi +} + +print_battery_full() { + if command_exists "upower"; then + battery=$(upower -e | grep battery | head -1) + upower -i $battery | grep 'time to full' | awk '{printf "- %s %s till full", $4, $5}' + fi +} + +main() { + if battery_discharging; then + print_battery_remain + else + print_battery_full + fi +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_status_bg.sh b/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_status_bg.sh new file mode 100755 index 00000000..a26f37aa --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_status_bg.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/helpers.sh" + +color_full_charge_default="#[bg=green]" +color_high_charge_default="#[bg=yellow]" +color_medium_charge_default="#[bg=colour208]" # orange +color_low_charge_default="#[bg=red]" + +color_full_charge="" +color_high_charge="" +color_medium_charge="" +color_low_charge="" + +get_charge_color_settings() { + color_full_charge=$(get_tmux_option "@batt_color_full_charge" "$color_full_charge_default") + color_high_charge=$(get_tmux_option "@batt_color_high_charge" "$color_high_charge_default") + color_medium_charge=$(get_tmux_option "@batt_color_medium_charge" "$color_medium_charge_default") + color_low_charge=$(get_tmux_option "@batt_color_low_charge" "$color_low_charge_default") +} + +print_battery_status_bg() { + # Call `battery_percentage.sh`. + percentage=$($CURRENT_DIR/battery_percentage.sh | sed -e 's/%//') + if [ $percentage -eq 100 ]; then + printf $color_full_charge + elif [ $percentage -le 99 -a $percentage -ge 51 ];then + printf $color_high_charge + elif [ $percentage -le 50 -a $percentage -ge 16 ];then + printf $color_medium_charge + else + printf $color_low_charge + fi +} + +main() { + get_charge_color_settings + print_battery_status_bg +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_status_fg.sh b/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_status_fg.sh new file mode 100755 index 00000000..50d10cb3 --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-battery/scripts/battery_status_fg.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source "$CURRENT_DIR/helpers.sh" + +color_full_charge_default="#[fg=green]" +color_high_charge_default="#[fg=yellow]" +color_medium_charge_default="#[fg=colour208]" # orange +color_low_charge_default="#[fg=red]" + +color_full_charge="" +color_high_charge="" +color_medium_charge="" +color_low_charge="" + +get_charge_color_settings() { + color_full_charge=$(get_tmux_option "@batt_color_full_charge" "$color_full_charge_default") + color_high_charge=$(get_tmux_option "@batt_color_high_charge" "$color_high_charge_default") + color_medium_charge=$(get_tmux_option "@batt_color_medium_charge" "$color_medium_charge_default") + color_low_charge=$(get_tmux_option "@batt_color_low_charge" "$color_low_charge_default") +} + +print_battery_status_fg() { + # Call `battery_percentage.sh`. + percentage=$($CURRENT_DIR/battery_percentage.sh | sed -e 's/%//') + if [ $percentage -eq 100 ]; then + printf $color_full_charge + elif [ $percentage -le 99 -a $percentage -ge 51 ];then + printf $color_high_charge + elif [ $percentage -le 50 -a $percentage -ge 16 ];then + printf $color_medium_charge + else + printf $color_low_charge + fi +} + +main() { + get_charge_color_settings + print_battery_status_fg +} +main diff --git a/filesystem/root/.tmux/plugins/tmux-battery/scripts/helpers.sh b/filesystem/root/.tmux/plugins/tmux-battery/scripts/helpers.sh new file mode 100644 index 00000000..2068604e --- /dev/null +++ b/filesystem/root/.tmux/plugins/tmux-battery/scripts/helpers.sh @@ -0,0 +1,41 @@ +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_chrome() { + chrome="/sys/class/chromeos/cros_ec" + if [ -d "$chrome" ]; then + return 0 + else + return 1 + fi +} + +command_exists() { + local command="$1" + type "$command" >/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 00000000..ae7dfab1 Binary files /dev/null and b/filesystem/root/.tmux/plugins/tmux-prefix-highlight/screenshots/prefix_off.png differ 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 00000000..d81adfc7 Binary files /dev/null and b/filesystem/root/.tmux/plugins/tmux-prefix-highlight/screenshots/prefix_on.png differ 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 00000000..8ea5ea24 Binary files /dev/null and b/filesystem/root/.tmux/plugins/tmux-resurrect/video/issue_vid.png differ 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 00000000..f5f3d832 Binary files /dev/null and b/filesystem/root/.tmux/plugins/tmux-resurrect/video/screencast_img.png differ 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