diff --git a/tmux/local.conf b/tmux/local.conf index 305a592..aa036fc 100644 --- a/tmux/local.conf +++ b/tmux/local.conf @@ -28,7 +28,6 @@ setw -g pane-base-index 1 # Enable mouse support set -g mouse on - # ========================== # === Key bindings === # ========================== @@ -52,20 +51,18 @@ unbind o # focus thru panes unbind & # kill-window unbind "#" # list-buffer unbind = # choose-buffer -#unbind z # zoom-pane unbind M-Up # resize 5 rows up unbind M-Down # resize 5 rows down unbind M-Right # resize 5 rows right unbind M-Left # resize 5 rows left - # Edit configuration and reload bind C-e new-window -n 'tmux.conf' "sh -c '\${EDITOR:-vim} ~/.tmux.conf && tmux source ~/.tmux.conf && tmux display \"Config reloaded\"'" # Reload tmux configuration bind C-w source-file ~/.tmux.conf \; display "Config reloaded" -# new window and retain cwd +# New window and retain cwd bind c new-window -c "#{pane_current_path}" # Prompt to rename window right after it's created @@ -87,17 +84,14 @@ bind -r ] select-pane -t :.+ bind -r Tab last-window # cycle thru MRU tabs bind -r C-o swap-pane -D -# Zoom pane -#bind + resize-pane -Z - # Link window bind L command-prompt -p "Link window from (session:window): " "link-window -s %% -a" # Swap panes back and forth with 1st pane # When in main-(horizontal|vertical) layouts, the biggest/widest panel is always @1 bind \ if '[ #{pane_index} -eq 1 ]' \ - 'swap-pane -s "!"' \ - 'select-pane -t:.1 ; swap-pane -d -t 1 -s "!"' + 'swap-pane -s "!"' \ + 'select-pane -t:.1 ; swap-pane -d -t 1 -s "!"' # Kill pane/window/session shortcuts bind x kill-pane @@ -110,41 +104,39 @@ bind Q confirm-before -p "kill-session #S? (y/n)" kill-session # but don't want to create a lot of small unnamed 1-window sessions around # move all windows from current session to main named one (dev, work, etc) bind C-u command-prompt -p "Session to merge with: " \ - "run-shell 'yes | head -n #{session_windows} | xargs -I {} -n 1 tmux movew -t %%'" + "run-shell 'yes | head -n #{session_windows} | xargs -I {} -n 1 tmux movew -t %%'" # Detach from session bind d detach bind D if -F '#{session_many_attached}' \ - 'confirm-before -p "Detach other clients? (y/n)" "detach -a"' \ - 'display "Session has only 1 client attached"' + 'confirm-before -p "Detach other clients? (y/n)" "detach -a"' \ + 'display "Session has only 1 client attached"' # Hide status bar on demand bind C-s if -F '#{s/off//:status}' 'set status off' 'set status on' - - # ================================================== # === Window monitoring for activity and silence === # ================================================== + bind m setw monitor-activity \; display-message 'Monitor window activity [#{?monitor-activity,ON,OFF}]' bind M if -F '#{monitor-silence}' \ - 'setw monitor-silence 0 ; display-message "Monitor window silence [OFF]"' \ - 'command-prompt -p "Monitor silence: interval (s)" "setw monitor-silence %%"' + 'setw monitor-silence 0 ; display-message "Monitor window silence [OFF]"' \ + 'command-prompt -p "Monitor silence: interval (s)" "setw monitor-silence %%"' # Activity bell and whistles set -g visual-activity on # TODO: Does not work as well, check on newer versions -# set -g visual-silence on +set -g visual-silence on # BUG: bell-action other ignored · Issue #1027 · tmux/tmux · GitHub - https://github.com/tmux/tmux/issues/1027 -# set -g visual-bell on -# setw -g bell-action other +set -g visual-bell on +setw -g bell-action other # ================================================ # === Copy mode, scroll and clipboard === # ================================================ -set -g @copy_use_osc52_fallback on # Prefer vi style key table setw -g mode-keys vi @@ -167,36 +159,6 @@ bind -T copy-mode-vi PageUp send-keys -X page-up bind -T copy-mode-vi WheelUpPane select-pane \; send-keys -X -N 2 scroll-up bind -T copy-mode-vi WheelDownPane select-pane \; send-keys -X -N 2 scroll-down -# wrap default shell in reattach-to-user-namespace if available -# there is some hack with `exec & reattach`, credits to "https://github.com/gpakosz/.tmux" -# don't really understand how it works, but at least window are not renamed to "reattach-to-user-namespace" -if -b "command -v reattach-to-user-namespace > /dev/null 2>&1" \ - "run 'tmux set -g default-command \"exec $(tmux show -gv default-shell) 2>/dev/null & reattach-to-user-namespace -l $(tmux show -gv default-shell)\"'" - -yank="~/.dots/tmux/utils/yank.sh" - -# Copy selected text -bind -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "$yank" -bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "$yank" -bind -T copy-mode-vi Y send-keys -X copy-line \;\ - run "tmux save-buffer - | $yank" -bind-key -T copy-mode-vi D send-keys -X copy-end-of-line \;\ - run "tmux save-buffer - | $yank" -bind -T copy-mode-vi C-j send-keys -X copy-pipe-and-cancel "$yank" -bind-key -T copy-mode-vi A send-keys -X append-selection-and-cancel \;\ - run "tmux save-buffer - | $yank" - -# Copy selection on drag end event, but do not cancel copy mode and do not clear selection -# clear select on subsequence mouse click -bind -T copy-mode-vi MouseDragEnd1Pane \ - send-keys -X copy-pipe "$yank" -bind -T copy-mode-vi MouseDown1Pane select-pane \;\ - send-keys -X clear-selection - -# iTerm2 works with clipboard out of the box, set-clipboard already set to "external" -# tmux show-options -g -s set-clipboard -# set-clipboard on|external - # ===================================== # === Theme === # ===================================== @@ -233,13 +195,13 @@ color_window_off_status_current_bg="colour254" set -g mode-style "fg=default,bg=$color_main" -# command line style +# Command line style set -g message-style "fg=$color_main,bg=$color_dark" -# status line style +# Status line style set -g status-style "fg=$color_status_text,bg=$color_dark" -# window segments in status line +# Window segments in status line set -g window-status-separator "" separator_powerline_left="" separator_powerline_right="" @@ -249,21 +211,21 @@ setw -g window-status-format " #I:#W " setw -g window-status-current-style "fg=$color_light,bold,bg=$color_main" setw -g window-status-current-format "#[fg=$color_dark,bg=$color_main]$separator_powerline_right#[default] #I:#W# #[fg=$color_main,bg=$color_dark]$separator_powerline_right#[default]" -# when window has monitoring notification +# When window has monitoring notification setw -g window-status-activity-style "fg=$color_main" -# outline for active pane +# Outline for active pane setw -g pane-active-border-style "fg=$color_main" -# general status bar settings +# General status bar settings set -g status on set -g status-interval 5 set -g status-position top set -g status-justify left set -g status-right-length 100 -# define widgets we're going to use in status bar -# note, that this is not the complete list, some of them are loaded from plugins +# Define widgets we're going to use in status bar +# Note, that this is not the complete list, some of them are loaded from plugins wg_session="#[fg=$color_session_text] #S #[default]" wg_battery="#{battery_status_fg} #{battery_icon} #{battery_percentage}" wg_date="#[fg=$color_secondary]%h %d %H:%M#[default]" @@ -275,7 +237,7 @@ wg_is_keys_off="#[fg=$color_light,bg=$color_window_off_indicator]#([ $(tmux show set -g status-left "$wg_session" set -g status-right "#{prefix_highlight} $wg_is_keys_off $wg_is_zoomed #{sysstat_cpu} | #{sysstat_mem} | #{sysstat_loadavg} | $wg_user_host | $wg_date $wg_battery #{online_status}" -# online and offline icon for tmux-online-status +# Online and offline icon for tmux-online-status set -g @online_icon "#[fg=$color_level_ok]●#[default]" set -g @offline_icon "#[fg=$color_level_stress]●#[default]" @@ -295,7 +257,6 @@ set -g @sysstat_swap_color_low "$color_level_ok" set -g @sysstat_swap_color_medium "$color_level_warn" set -g @sysstat_swap_color_stress "$color_level_stress" - # Configure tmux-battery widget colors set -g @batt_color_full_charge "#[fg=$color_level_ok]" set -g @batt_color_high_charge "#[fg=$color_level_ok]" @@ -310,10 +271,10 @@ set -g @prefix_highlight_bg "$color_secondary" set -g @prefix_highlight_show_copy_mode 'on' set -g @prefix_highlight_copy_mode_attr "fg=$color_dark,bg=$color_secondary" - # ===================================== # === Renew environment === # ===================================== + set -g update-environment \ "DISPLAY\ SSH_ASKPASS\ @@ -326,57 +287,41 @@ set -g update-environment \ bind '$' run "~/.dots/tmux/utils/renew_env.sh" - # ============================ # === Plugins === # ============================ -#set -g @plugin 'tmux-plugins/tpm' - -#set -g @plugin 'tmux-plugins/tmux-battery' -#set -g @plugin 'tmux-plugins/tmux-prefix-highlight' -#set -g @plugin 'tmux-plugins/tmux-online-status' -#set -g @plugin 'tmux-plugins/tmux-sidebar' -#set -g @plugin 'tmux-plugins/tmux-copycat' -#set -g @plugin 'tmux-plugins/tmux-open' -#set -g @plugin 'samoshkin/tmux-plugin-sysstat' - -#set -g @plugin 'tmux-plugins/tmux-resurrect' -#set -g @plugin 'tmux-plugins/tmux-continuum' # Plugin properties set -g @sidebar-tree 't' set -g @sidebar-tree-focus 'T' -set -g @sidebar-tree-command 'tree -C' +set -g @sidebar-tree-command 'tree -C -L 2 --dirsfirst' set -g @continuum-restore 'on' set -g @open-S 'https://www.google.com/search?q=' - # ============================================== # === Nesting local and remote sessions === # ============================================== # Session is considered to be remote when we ssh into host if-shell 'test -n "$SSH_CLIENT"' \ - 'source-file ~/.dots/tmux/remote.conf' + 'source-file ~/.dots/tmux/remote.conf' # We want to have single prefix key "C-a", usable both for local and remote session # we don't want to "C-a" + "a" approach either # Idea is to turn off all key bindings and prefix handling on local session, # so that all keystrokes are passed to inner/remote session -# see: toggle on/off all keybindings · Issue #237 · tmux/tmux - https://github.com/tmux/tmux/issues/237 - # Also, change some visual styles when window keys are off bind -T root F12 \ - set prefix None \;\ - set key-table off \;\ - set status-style "fg=$color_status_text,bg=$color_window_off_status_bg" \;\ - set window-status-current-format "#[fg=$color_window_off_status_bg,bg=$color_window_off_status_current_bg]$separator_powerline_right#[default] #I:#W# #[fg=$color_window_off_status_current_bg,bg=$color_window_off_status_bg]$separator_powerline_right#[default]" \;\ - set window-status-current-style "fg=$color_dark,bold,bg=$color_window_off_status_current_bg" \;\ - if -F '#{pane_in_mode}' 'send-keys -X cancel' \;\ - refresh-client -S \;\ + set prefix None \;\ + set key-table off \;\ + set status-style "fg=$color_status_text,bg=$color_window_off_status_bg" \;\ + set window-status-current-format "#[fg=$color_window_off_status_bg,bg=$color_window_off_status_current_bg]$separator_powerline_right#[default] #I:#W# #[fg=$color_window_off_status_current_bg,bg=$color_window_off_status_bg]$separator_powerline_right#[default]" \;\ + set window-status-current-style "fg=$color_dark,bold,bg=$color_window_off_status_current_bg" \;\ + if -F '#{pane_in_mode}' 'send-keys -X cancel' \;\ + refresh-client -S \;\ bind -T off F12 \ set -u prefix \;\ @@ -387,7 +332,6 @@ bind -T off F12 \ refresh-client -S # Run all plugins' scripts -#run '~/.tmux/plugins/tpm/tpm' run '~/.dots/tmux/plugins/tmux-battery/battery.tmux' run '~/.dots/tmux/plugins/tmux-online-status/online_status.tmux' run '~/.dots/tmux/plugins/tmux-plugin-sysstat/sysstat.tmux' @@ -395,7 +339,7 @@ run '~/.dots/tmux/plugins/tmux-prefix-highlight/prefix_highlight.tmux' run '~/.dots/tmux/plugins/tmux-copycat/copycat.tmux' run '~/.dots/tmux/plugins/tmux-open/open.tmux' run '~/.dots/tmux/plugins/tmux-sidebar/sidebar.tmux' -#run '~/.dots/tmux/plugins/tmux-yank/yank.tmux' +run '~/.dots/tmux/plugins/tmux-yank/yank.tmux' run '~/.dots/tmux/plugins/tmux-ressurect/resurrect.tmux' run '~/.dots/tmux/plugins/tmux-continuum/continuum.tmux' diff --git a/tmux/utils/yank.sh b/tmux/utils/yank.sh deleted file mode 100755 index 83686c6..0000000 --- a/tmux/utils/yank.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env bash - -set -eu - -is_app_installed() { - type "$1" &>/dev/null -} - -# get data either form stdin or from file -buf=$(cat "$@") - -copy_backend_remote_tunnel_port=$(tmux show-option -gvq "@copy_backend_remote_tunnel_port") -copy_use_osc52_fallback=$(tmux show-option -gvq "@copy_use_osc52_fallback") - -# Resolve copy backend: pbcopy (OSX), reattach-to-user-namespace (OSX), xclip/xsel (Linux) -copy_backend="" -if is_app_installed pbcopy; then - copy_backend="pbcopy" -elif is_app_installed reattach-to-user-namespace; then - copy_backend="reattach-to-user-namespace pbcopy" -elif [ -n "${DISPLAY-}" ] && is_app_installed xsel; then - copy_backend="xsel -i --clipboard" -elif [ -n "${DISPLAY-}" ] && is_app_installed xclip; then - copy_backend="xclip -i -f -selection primary | xclip -i -selection clipboard" -elif [ -n "${copy_backend_remote_tunnel_port-}" ] \ - && (netstat -f inet -nl 2>/dev/null || netstat -4 -nl 2>/dev/null) \ - | grep -q "[.:]$copy_backend_remote_tunnel_port"; then - copy_backend="nc localhost $copy_backend_remote_tunnel_port" -fi - -# if copy backend is resolved, copy and exit -if [ -n "$copy_backend" ]; then - printf "%s" "$buf" | eval "$copy_backend" - exit; -fi - - -# If no copy backends were eligible, decide to fallback to OSC 52 escape sequences -# Note, most terminals do not handle OSC -if [ "$copy_use_osc52_fallback" == "off" ]; then - exit; -fi - -# Copy via OSC 52 ANSI escape sequence to controlling terminal -buflen=$( printf %s "$buf" | wc -c ) - -# https://sunaku.github.io/tmux-yank-osc52.html -# The maximum length of an OSC 52 escape sequence is 100_000 bytes, of which -# 7 bytes are occupied by a "\033]52;c;" header, 1 byte by a "\a" footer, and -# 99_992 bytes by the base64-encoded result of 74_994 bytes of copyable text -maxlen=74994 - -# warn if exceeds maxlen -if [ "$buflen" -gt "$maxlen" ]; then - printf "input is %d bytes too long" "$(( buflen - maxlen ))" >&2 -fi - -# build up OSC 52 ANSI escape sequence -esc="\033]52;c;$( printf %s "$buf" | head -c $maxlen | base64 | tr -d '\r\n' )\a" -esc="\033Ptmux;\033$esc\033\\" - -# resolve target terminal to send escape sequence -# if we are on remote machine, send directly to SSH_TTY to transport escape sequence -# to terminal on local machine, so data lands in clipboard on our local machine -pane_active_tty=$(tmux list-panes -F "#{pane_active} #{pane_tty}" | awk '$1=="1" { print $2 }') -target_tty="${SSH_TTY:-$pane_active_tty}" - -printf "$esc" > "$target_tty"