add(tmux): cross-platform yanking

This commit is contained in:
Léana 江 2023-10-29 15:45:35 +00:00 committed by Léana 江
parent 4ddac62cc9
commit 15cda9ae4a
2 changed files with 74 additions and 1 deletions

81
.tmux/tmux.conf Normal file
View file

@ -0,0 +1,81 @@
# mouse control
set -g mouse on
# focus-events for vim
set-option -g focus-events on
# easy config reload
bind-key r source-file ~/.tmux.conf \; display-message "tmux.conf reloaded."
# enable italics
set -g default-terminal "tmux-256color"
# status bar style
set -g status-style bg=black,fg=white
set -g window-status-current-style bg=white,fg=black
set -g status-position bottom
set -g status-left ""
set -g status-right "#(basename #S) [#(hostname)]"
# status bar
set-option -g status-left '#{?window_name,#I:#W} #{T}'
set-option -g status-position top
# remap prefix
bind C-a send-prefix
set-option -g prefix C-a
unbind C-b
set -g base-index 1
# organic jumping
bind -n C-h select-window -t 1
bind -n C-t select-window -t 2
bind -n C-n select-window -t 3
bind -n C-s select-window -t 4
bind -T copy-mode-vi C-h select-window -t 1
bind -T copy-mode-vi C-t select-window -t 2
bind -T copy-mode-vi C-n select-window -t 3
bind -T copy-mode-vi C-s select-window -t 4
# stop the clock madness
unbind t
# vim-sytle pane jumping
bind h select-pane -L
bind l select-pane -R
bind t select-pane -R
bind j select-pane -D
bind k select-pane -U
# unbind built-in select-pane jumping
unbind Left
unbind Right
unbind Down
unbind Up
# improve window swapping
bind C-l swap-window -t -1
bind C-r swap-window -t +1
# escape delay
set -s escape-time 0
# auto reorder window number
set-option -g renumber-windows on
# Prime says the find window is for chumps. Don't use the find window
bind-key -n C-f run-shell "tmux neww fish -c tmux_sessionizer"
bind-key -n C-g run-shell "tmux neww fish -c tmux_home"
# fast kill
bind-key k confirm-before kill-session
# global vi mode
set-window-option -g mode-keys vi
# who the fuck thought prefix-[ is a good idea ??!?!
yank="~/.tmux/yank.sh"
bind v copy-mode
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "$yank"
bind -T copy-mode-vi ENTER send-keys -X copy-pipe-and-cancel "$yank"

71
.tmux/yank.sh Normal file
View file

@ -0,0 +1,71 @@
#!/usr/bin/env bash
# Credit
# https://github.com/samoshkin/tmux-config/blob/master/tmux/yank.sh
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"