diff --git a/.tmux.conf b/.tmux.conf index b8a7639..99a10dc 100644 --- a/.tmux.conf +++ b/.tmux.conf @@ -109,8 +109,12 @@ set -g default-terminal "screen-256color" # Mode set -g mode-style bg=colour100,fg=colour235 -# List of plugins -#set -g @plugin 'tmux-plugins/tpm' +# List of plugins and their settings +set -g @plugin 'tmux-plugins/tpm' + +set -g @plugin 'nhdaly/tmux-better-mouse-mode' +set -g @scroll-speed-num-lines-per-scroll 2 + #set -g @plugin 'tmux-plugins/tmux-sensible' #set -g @plugin 'kristijanhusak/tmux-simple-git-status' @@ -120,5 +124,5 @@ set -g mode-style bg=colour100,fg=colour235 # set -g @plugin 'git@bitbucket.com/user/plugin' # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) -#run -b '~/.tmux/plugins/tpm/tpm' +run -b '~/.tmux/plugins/tpm/tpm' diff --git a/.tmux/plugins/tmux-better-mouse-mode/.travis.yml b/.tmux/plugins/tmux-better-mouse-mode/.travis.yml new file mode 100644 index 0000000..a874cc3 --- /dev/null +++ b/.tmux/plugins/tmux-better-mouse-mode/.travis.yml @@ -0,0 +1,10 @@ +language: bash + +before_script: + - curl -L "https://github.com/tmux/tmux/releases/download/2.2/tmux-2.2.tar.gz" | tar zx + - cd tmux-2.2; ./configure && make; cd .. + - curl -L "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/shunit2/shunit2-2.1.6.tgz" | tar zx + +script: + - bash tests/*.sh + diff --git a/.tmux/plugins/tmux-better-mouse-mode/LICENSE.md b/.tmux/plugins/tmux-better-mouse-mode/LICENSE.md new file mode 100644 index 0000000..6755fc0 --- /dev/null +++ b/.tmux/plugins/tmux-better-mouse-mode/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Nathan Daly + +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/.tmux/plugins/tmux-better-mouse-mode/README.md b/.tmux/plugins/tmux-better-mouse-mode/README.md new file mode 100644 index 0000000..3b9b408 --- /dev/null +++ b/.tmux/plugins/tmux-better-mouse-mode/README.md @@ -0,0 +1,103 @@ +# Tmux Better Mouse Mode +A tmux plugin to better manage the mouse. + +Provides options to control mouse behavior in tmux, so it will behave exactly how you want: + - Emulate mouse-support for full-screen programs like `less` that don't provide built in mouse support. + - Exit `copy-mode` and return to your prompt by scrolling back all the way down to the bottom. + - Adjust your scrolling speed. + - And more! + +Finally, `tmux` version 2.1 introduced backwards-incompatible changes to the mouse behavior, and this plugin restores the old mouse behavior. `tmux` version 2.2 mostly restores the 2.0 mouse behavior, but this plugin improves tmux mouse mode beyond those changes and provides you with more control. + +### Requirements + +This plugin is intended for `tmux` version 2.1 and higher. It does not work for 2.0 or below. + +NOTE: This plugin provides options to *change* the mouse-mode behavior, but does not enable mouse-mode. + +To enable mouse-mode in tmux 2.1+, put the following line in your `~/.tmux.conf`: + + set-option -g mouse on + +### Key bindings + +This plugin will overwrite the values for `WheelUpPane` and `WheelDownPane` in tmux in order to configure mouse scrolling. + +To see your current setting for these variables, check the output of `tmux list-keys -T root`. + +### Installation with [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm) (recommended) + +1. Add this plugin to the list of TPM plugins in `.tmux.conf`: + + set -g @plugin 'nhdaly/tmux-better-mouse-mode' + +1. Press `prefix` + I or run `$TMUX_PLUGIN_MANAGER_PATH/tpm/scripts/install_plugins.sh` to fetch the plugin and source it. You should now be able to +use the plugin. + +1. To enable mouse-mode in tmux 2.1+, put the following line in your `.tmux.conf`: + + set-option -g mouse on + +### Manual Installation + +1. Clone the repo: + + $ git clone https://github.com/nhdaly/tmux-better-mouse-mode ~/clone/path + +1. Add this line to the bottom of `.tmux.conf`: + + run-shell ~/clone/path/scroll_copy_mode.tmux + +1. Reload TMUX environment: + + # type this in terminal + $ tmux source-file ~/.tmux.conf + +You should now be able to use the plugin. + +### Configuration + +Set these options in `.tmux.conf`. For example, `set -g @scroll-down-exit-copy-mode "off"` to disable scrolling down exits copy-mode. + +- `scroll-down-exit-copy-mode` - When enabled, the pane exits `copy-mode` when scrolling hits the bottom of the scroll-back history. + - "on" (default) - Scrolling can exit `copy-mode`. + - "off" - Scrolling to bottom will stay in `copy-mode`. + +- `scroll-without-changing-pane` - When enabled, scrolling the mouse will not select the moused-over pane, allowing you to scroll a window just to read previous output and then keep typing in the current pane. Enabling this feature is a change from `tmux 2.0` settings, but may be an improvement. + - "on" - Scroll events are sent to moused-over pane. + - "off" (default) - Scroll events stay in currently selected pane. + +- `scroll-in-moused-over-pane` - When enabled, scrolling with your mouse over a pane will perform the scroll in that pane, instead of the currently selected one. If `scroll-without-changing-pane` is set to `"off"`, this will also select the moused-over pane. + - "on" (default) - Scroll events select and scroll the moused-over pane. + - "off" - Scroll events are ingored unless the mouse is over the currently selected pane. + +- `scroll-speed-num-lines-per-scroll` - Sets the number of lines to scroll per mouse wheel scroll event. The default option is 3, which was the scroll speed in `tmux 2.0`. Larger numbers scroll faster. To slow down scrolling to slower than one line per wheel click, set the value to a decimal between 0.0 and 1.0. With a decimal value, only that fraction of wheel events will take effect. The value must be > 0. Examples: + - "3" (default) - Scroll three lines per every mouse wheel click. + - "1" - One line per mouse wheel scroll click (smoothest). + - "0.5" - Scroll one line only on every other mouse wheel scroll click. + - "0.25" - Scroll one line only on every fourth mouse wheel scroll click. + +- `emulate-scroll-for-no-mouse-alternate-buffer` - When enabled, tmux will emulate scrolling for "full-screen", alternate buffer programs, such as `less`, `man`, or `vi` that don't themselves already support mouse interactions. It will not enter `copy-mode` and will not scroll through pane output history, but will instead send `` () and ``() keys to the application. The scroll speed is also set by `@scroll-speed-num-lines-per-scroll` above. +This option defaults to "off", which matches the behavior in `tmux 2.0`. Note, though, that this default behavior may be undesirable since the pane history gets munged when entering a full-screen alternate buffer program. It's a pretty great option is all I'm saying. + - "on" - and keys are passed to the alternate buffer program on scroll events. + - "off" (default) - Scroll event causes scrollback in pane output. + +### Contributions +[@nhdaly](https://github.com/nhdaly) +[@corv89](https://github.com/corv89) +[@pallxk ](https://github.com/pallxk ) +[@hughdavenport](https://github.com/hughdavenport) +[@giddie](https://github.com/giddie) +[@pochemuto](https://github.com/pochemuto) +[@zeorin](https://github.com/zeorin) +[@alcesleo](https://github.com/alcesleo) +[@iamjamestl](https://github.com/iamjamestl) + +### Inspiration + +Inspired by David Verhasselt's in depth article on Tmux 2.1's changes to Mouse support and scrolling: +http://www.davidverhasselt.com/better-mouse-scrolling-in-tmux/ + +### License +[MIT](LICENSE.md) + diff --git a/.tmux/plugins/tmux-better-mouse-mode/only_scroll_sometimes.sh b/.tmux/plugins/tmux-better-mouse-mode/only_scroll_sometimes.sh new file mode 100755 index 0000000..5edf63b --- /dev/null +++ b/.tmux/plugins/tmux-better-mouse-mode/only_scroll_sometimes.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +num_scrolls_to_scroll=$1 + +get_count_cmd=`tmux show-environment -g __scroll_copy_mode__slow_scroll_count` +eval $get_count_cmd + +# Save the current count so we can use it in the return statement at the end. +CURRENT_COUNT=$__scroll_copy_mode__slow_scroll_count + +# Now increment and loop around if we've finished the scroll cycle. +__scroll_copy_mode__slow_scroll_count=$(( (__scroll_copy_mode__slow_scroll_count + 1) % num_scrolls_to_scroll)) + + +# Store the new value in tmux. +tmux set-environment -g __scroll_copy_mode__slow_scroll_count $__scroll_copy_mode__slow_scroll_count + +# Return true if this is the first scroll for this scroll-cycle, and false if we haven't hit the end of the cycle. +[ $CURRENT_COUNT -eq 0 ] + + + diff --git a/.tmux/plugins/tmux-better-mouse-mode/scripts/helpers.sh b/.tmux/plugins/tmux-better-mouse-mode/scripts/helpers.sh new file mode 100644 index 0000000..2c263c4 --- /dev/null +++ b/.tmux/plugins/tmux-better-mouse-mode/scripts/helpers.sh @@ -0,0 +1,15 @@ +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 +} + +get_tmux_version() { + tmux -V | cut -d " " -f 2 +} + diff --git a/.tmux/plugins/tmux-better-mouse-mode/scroll_copy_mode.tmux b/.tmux/plugins/tmux-better-mouse-mode/scroll_copy_mode.tmux new file mode 100755 index 0000000..0d7dfbc --- /dev/null +++ b/.tmux/plugins/tmux-better-mouse-mode/scroll_copy_mode.tmux @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( dirname "$0" )" + +. "$CURRENT_DIR/scripts/helpers.sh" + +scroll_down_exit_copy_mode_option="@scroll-down-exit-copy-mode" +scroll_in_moused_over_pane_option="@scroll-in-moused-over-pane" +scroll_without_changing_pane_option="@scroll-without-changing-pane" +scroll_speed_num_lines_per_scroll_option="@scroll-speed-num-lines-per-scroll" +deprecated_prevent_scroll_for_fullscreen_alternate_buffer_option="@prevent-scroll-for-fullscreen-alternate-buffer" +emulate_scroll_for_no_mouse_alternate_buffer_option="@emulate-scroll-for-no-mouse-alternate-buffer" + +get_repeated_scroll_cmd() { + local scroll_speed_num_lines_per_scroll=$(get_tmux_option "$scroll_speed_num_lines_per_scroll_option" "3") + local cmd="" + if echo - | awk "{ if ($scroll_speed_num_lines_per_scroll >= 1) { exit 0 } else { exit 1 } }" ; then # Positive whole number speed (round down). + for ((i = 1; i <= scroll_speed_num_lines_per_scroll; i++)); do + cmd=$cmd"send-keys $1 ; " + done + elif echo - | awk "{ if ($scroll_speed_num_lines_per_scroll > 0) { exit 0 } else { exit 1 } }" ; then # Positive decimal between 0 and 1 (treat as percent). + # Skip enough scrolls so that we scroll only on the specified percent of scrolls. + local num_scrolls_to_scroll=`echo - | awk "{print int( 1/$scroll_speed_num_lines_per_scroll ) }"` + tmux set-environment __scroll_copy_mode__slow_scroll_count 0; + cmd="if -t = \\\"$CURRENT_DIR/only_scroll_sometimes.sh $num_scrolls_to_scroll\\\" \\\"send-keys $1\\\" \\\"\\\""; + fi + echo "$cmd" +} + +better_mouse_mode_main() { + local scroll_down_to_exit=$(get_tmux_option "$scroll_down_exit_copy_mode_option" "on") + local scroll_in_moused_over_pane=$(get_tmux_option "$scroll_in_moused_over_pane_option" "on") + local scroll_without_changing_pane=$(get_tmux_option "$scroll_without_changing_pane_option" "off") + local deprecated_prevent_scroll_for_fullscreen_alternate_buffer=$(get_tmux_option "$deprecated_prevent_scroll_for_fullscreen_alternate_buffer_option" "off") + local emulate_scroll_for_no_mouse_alternate_buffer=$(get_tmux_option "$emulate_scroll_for_no_mouse_alternate_buffer_option" "$deprecated_prevent_scroll_for_fullscreen_alternate_buffer") + + local enter_copy_mode_cmd="copy-mode" + local select_moused_over_pane_cmd="" + local check_for_fullscreen_alternate_buffer="" + if [ "$scroll_down_to_exit" = 'on' ] ; then + enter_copy_mode_cmd="copy-mode -e" + fi + if [ "$scroll_in_moused_over_pane" = 'on' ] ; then + select_moused_over_pane_cmd="select-pane -t= ;" + fi + if [ "$scroll_without_changing_pane" = 'on' ] ; then + enter_copy_mode_cmd="$enter_copy_mode_cmd -t=" + select_moused_over_pane_cmd="" + fi + if [ "$emulate_scroll_for_no_mouse_alternate_buffer" = 'on' ] ; then + check_for_fullscreen_alternate_buffer="#{alternate_on}" + fi + + # Start copy mode when scrolling up and exit when scrolling down to bottom. + # The "#{mouse_any_flag}" check just sends scrolls to any program running that + # has mouse support (like vim). + # NOTE: the successive levels of quoting commands gets a little confusing + # here. Tmux uses quoting to denote levels of the if-blocks below. The + # pattern used here for consistency is " \" ' \\\" \\\" ' \" " -- that is, + # " for top-level quotes, \" for the next level in, ' for the third level, + # and \\\" for the fourth (note that the fourth comes from inside get_repeated_scroll_cmd). + tmux bind-key -n WheelUpPane \ + if -Ft= "#{mouse_any_flag}" \ + "send-keys -M" \ + " \ + if -Ft= '$check_for_fullscreen_alternate_buffer' \ + \"$(get_repeated_scroll_cmd "-t= up")\" \ + \" \ + $select_moused_over_pane_cmd \ + if -Ft= '#{pane_in_mode}' \ + '$(get_repeated_scroll_cmd -M)' \ + '$enter_copy_mode_cmd ; $(get_repeated_scroll_cmd -M)' \ + \" \ + " + # Enable sending scroll-downs to the moused-over-pane. + # NOTE: the quoting pattern used here and in the above command for + # consistency is " \" ' \\\" \\\" ' \" " -- that is, " for top-level quotes, + # \" for the next level in, ' for the third level, and \\\" for the fourth + # (note that the fourth comes from inside get_repeated_scroll_cmd). + tmux bind-key -n WheelDownPane \ + if -Ft= "#{mouse_any_flag}" \ + "send-keys -M" \ + " \ + if -Ft= \"$check_for_fullscreen_alternate_buffer\" \ + \"$(get_repeated_scroll_cmd "-t= down")\" \ + \"$select_moused_over_pane_cmd $(get_repeated_scroll_cmd -M)\" \ + " + + # For tmux 2.4+ you have to set the mouse wheel options seperately for copy-mode than from root. + local tmux_version=$(get_tmux_version) + if echo - | awk "{ if ($tmux_version >= 2.4) { exit 0 } else { exit 1 } }" ; then # Use copy-mode tables to set scroll speed. + local scroll_speed_num_lines_per_scroll=$(get_tmux_option "$scroll_speed_num_lines_per_scroll_option" "3") + tmux bind-key -Tcopy-mode WheelUpPane send -N"$scroll_speed_num_lines_per_scroll" -X scroll-up + tmux bind-key -Tcopy-mode WheelDownPane send -N"$scroll_speed_num_lines_per_scroll" -X scroll-down + tmux bind-key -Tcopy-mode-vi WheelUpPane send -N"$scroll_speed_num_lines_per_scroll" -X scroll-up + tmux bind-key -Tcopy-mode-vi WheelDownPane send -N"$scroll_speed_num_lines_per_scroll" -X scroll-down + fi +} + +better_mouse_mode_main diff --git a/.tmux/plugins/tmux-better-mouse-mode/tests/basic_functionality_test.sh b/.tmux/plugins/tmux-better-mouse-mode/tests/basic_functionality_test.sh new file mode 100644 index 0000000..6e53097 --- /dev/null +++ b/.tmux/plugins/tmux-better-mouse-mode/tests/basic_functionality_test.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +# Setup +#tmux() { +# # Forward the "getter" calls to actual tmux, but change the setters to just +# # echo, so we can test what its setting. +# if [[ "$1" == "show-option" ]] ; then +# tmux-2.2/tmux "$@" +# else +# echo "$@" +# fi +#} +tmux() { + tmux-2.2/tmux "$@" +} +export -f tmux + +# ------ Unit Tests ----------------------- + + +testBasicBindKeysAreCalled() { + bash scroll_copy_mode.tmux + + assertNotNull "`tmux list-keys -T root | grep 'WheelUpPane'`" + assertNotNull "`tmux list-keys -T root | grep 'WheelDownPane'`" +} + +checkScrollSpeedSetCorrectly() { + testSpeed="$1" + expectedValue="$2" + tmux set -g @scroll-speed-num-lines-per-scroll $testSpeed + + bash scroll_copy_mode.tmux + + # Make sure send-keys shows up correct number of times in up and down scroll bindings. + assertEquals 'number of `send-keys` per scroll up not equal to user setting' $expectedValue `tmux list-keys -T root | grep 'WheelUpPane' | grep -o "'send-keys[^']*'" | head -n 1 | grep -o 'send-keys' | wc -l` + assertEquals 'number of `send-keys` per scroll down not equal to user setting' $expectedValue `tmux list-keys -T root | grep 'WheelDownPane' | grep -o "'send-keys[^']*'" | head -n 1 | grep -o 'send-keys' | wc -l` +} + +testValidIntegerScrollSpeeds() { + checkScrollSpeedSetCorrectly 1 1 + checkScrollSpeedSetCorrectly 2 2 + checkScrollSpeedSetCorrectly 10 10 + checkScrollSpeedSetCorrectly 0 0 + checkScrollSpeedSetCorrectly 2.5 2 +} + +testInvalidIntegerScrollSpeeds() { + checkScrollSpeedSetCorrectly "-1" 0 + checkScrollSpeedSetCorrectly "-10" 0 + checkScrollSpeedSetCorrectly "-0.1" 0 +} + +checkFractionalScrollSpeedSetCorrectly() { + testSpeed="$1" + expectedNumScrollsBeforeScroll="$2" + tmux set -g @scroll-speed-num-lines-per-scroll $testSpeed + + bash scroll_copy_mode.tmux + + assertNotNull "`tmux list-keys -T root | grep 'WheelUpPane' | grep \"only_scroll_sometimes.sh $expectedNumScrollsBeforeScroll\"`" + assertNotNull "`tmux list-keys -T root | grep 'WheelDownPane' | grep \"only_scroll_sometimes.sh $expectedNumScrollsBeforeScroll\"`" + + assertNotNull "`tmux show-environment __scroll_copy_mode__slow_scroll_count`" +} + +testValidFractionalScrollSpeeds() { + checkFractionalScrollSpeedSetCorrectly 0.5 2 + checkFractionalScrollSpeedSetCorrectly 0.25 4 + checkFractionalScrollSpeedSetCorrectly 0.33 3 +} + +# --------- Run tests command ------------- +. shunit2-2.1.6/src/shunit2