Created
January 5, 2020 07:29
-
-
Save cowens/77b28c207508d81c953c42f17a1df842 to your computer and use it in GitHub Desktop.
tmux.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# OS specific changes | |
# macOS specific commands | |
if-shell "[[ $(uname) == 'Darwin' ]]" { | |
# makes pbcopy work from the commandline | |
set-option -g default-command "reattach-to-user-namespace -l bash" | |
} | |
# prefix+t brings up a useless clock, make it look nice | |
set-option -w -g clock-mode-style 24 | |
set-option -w -g clock-mode-colour green | |
# vi keybindings forever, when entering copy mode it uses the | |
# copy-mode-vi keybinding table instead of copy-mode keybinding | |
# table | |
set-option -w -g mode-keys vi | |
# when using the main-horizontal or main-vertical layouts | |
# sets the width of the main pane | |
set-option -w -g main-pane-width 120 | |
# tmux waits when it sees an escape character in case it is part | |
# of a escape sequence. This means hitting escape in vi is painfully | |
# slow. So make tmux wait less time (default is 500, half a second). | |
set-option -s escape-time 50 | |
# tmux hides messages a little too fast for me (default is 750) | |
set-option -g display-time 1500 | |
# You can hit prefix-: and get a prompt to enter tmux commands into. | |
# This option lets you use vi style keybindings in the prompt | |
set-option -g status-keys vi | |
# Normally I like things to be 0 indexed, but since my keyboard's number | |
# row starts with 1 it makes more sense to have the first pane be 1 as well | |
# so prefix-1 maps to the first window | |
set-option -g base-index 1 | |
# Just a big old scroll back limit | |
set-option -g history-limit 1000000 | |
# green and black is how I roll | |
set-option -g status-bg green | |
set-option -g status-fg black | |
set-option -g message-style fg=black,bg=green # messages and command mode | |
set-option -g message-command-style fg=black,bg=green # when editing command mode text | |
set-option -g mode-style bg=green,fg=black # selection should be inverse | |
# the left side of the status bar gets truncated if it is more than 10 | |
# characters by default. That may have made sense on an 80x25 terminal | |
# but I have a lot more real estate | |
set-option -g status-left-length 100 | |
# I don't use #H for the hostname because I prefer to use nicknames and hostnames | |
# have become monstrosities like sandbox-chas-01.legacy-dev-uw2.zipaws.com | |
# nested_level is a per-session environment variable I use to keep track | |
# of how nested my tmux session is (see end of config) | |
if-shell "[[ $(uname) == 'Darwin' ]]" { | |
set-option -g status-left '#(cat ~/.hostname) [#{?mouse,on,off}] [#(pbpaste | perl -C -pe "tr/\x0-\x19/\x{2400}-\x{2419}/; \$_ = substr \$_, 0, 10")] [#S] ' | |
} { | |
set-option -g status-left '#(cat ~/.hostname) [#{?mouse,on,off}] [#S] ' | |
} | |
set-option -g status-right "%a %m/%d %H:%M:%S" | |
# eats up more CPU, but I like to see the seconds change for rough timing purposes | |
set-option -g status-interval 1 | |
# I don't like gaps in the numbering of windows, so when window 4 closes, | |
# 5 should become 4, 6 should become 5, etc | |
set-option -g renumber-windows on | |
set-option -g default-terminal "screen-256color" | |
# remove default bindings that I don't use | |
unbind-key C-b | |
unbind-key M | |
unbind-key l | |
unbind-key '"' | |
unbind-key % | |
unbind-key - | |
unbind-key [ | |
unbind-key ] | |
unbind-key C-Left | |
unbind-key C-Right | |
unbind-key C-Up | |
unbind-key C-Down | |
# C-a should be the prefix | |
set-option -g prefix C-a | |
# changed bindings | |
bind-key C-a last-window # was l | |
bind-key - split-window # was " | |
bind-key | split-window -h # was % | |
bind-key p run "~/bin/tpaste" # was ] | |
bind-key Left select-pane -L # no -r so it won't repeat | |
bind-key Right select-pane -R # no -r so it won't repeat | |
bind-key Up select-pane -U # no -r so it won't repeat | |
bind-key Down select-pane -D # no -r so it won't repeat | |
# new bindings | |
bind-key P command-prompt -p 'save history to filename:' -I '~/tmux.history' 'capture-pane -S -32768 ; save-buffer %1' | |
bind-key a send-prefix # a for send the prefix a | |
bind-key m set-option mouse # m for mouse on/off | |
bind-key r source-file ~/.tmux.conf \; display-message "sourced conf" # r for reload conf | |
# simple window navigation, -T root means you don't need to hit prefix first, | |
# this makes scanning for what you want much faster | |
bind-key -T root S-left previous-window | |
bind-key -T root S-right next-window | |
# bring the current environment when attaching to a session | |
# note: this does not fix the environment of existing shells | |
# you need this in the PROMPT_COMMAND environment variable to | |
# PROMPT_COMMAND='eval $(tmux show-environment |grep -v ^- | perl -pe "s/=(.*)/=\x22\$1\x22/")' | |
set-option -g update-environment "SSH_AUTH_SOCK SSH_AGENT_PID SSH_ASKPASS SSH_CONNECTION" | |
# I have my own clipboard solution, so no need to use escape sequences | |
set-option -s set-clipboard off | |
# make vi mode more like vim | |
# I have a TCP server that runs on my macOS machine that exposes my pasteboard | |
# via an ssh tunnel (it is also authenticating and encrypting the messages), so | |
# even under Linux I have a version pbcopy. | |
bind-key Escape copy-mode # was [ | |
bind-key -T copy-mode-vi 'v' send-keys -X begin-selection | |
bind-key -T copy-mode-vi 'y' send-keys -X copy-pipe-and-cancel "~/bin/pbcopy" | |
bind-key -T copy-mode-vi 'C-v' send-keys -X rectangle-toggle | |
bind-key -T copy-mode-vi Escape send-keys -X cancel | |
# Turning mouse on is only viable because of the TCP server mentioned above. | |
# Turning it on gives me nice things like handling selections involving split | |
# panes correctly and the ability to select and resize panes with the mouse | |
set-option -g -s mouse on | |
bind-key -T copy-mode-vi MouseDrag1Pane select-pane \; send-keys -X begin-selection | |
bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "~/bin/pbcopy" | |
# double click to copy word, this sort of sucks in comparison to not having the | |
# mouse on there is no obvious indicator what was selected. | |
bind-key -T root DoubleClick1Pane { | |
select-pane | |
copy-mode | |
send-keys -X select-word | |
send-keys -X copy-pipe-and-cancel "~/bin/pbcopy" | |
refresh-client -S # make the status bar catch the updated buffer quick | |
} | |
# middle mouse paste, uses the same TCP server from above | |
bind-key -T root MouseDown2Pane select-pane \; run "~/bin/tpaste" | |
bind-key -T copy-mode-vi WheelUpPane select-pane \; send-keys -X -N 5 scroll-up | |
bind-key -T copy-mode-vi WheelDownPane select-pane \; send-keys -X -N 5 scroll-down | |
# The following insanity is to enable nested instances of tmux. The most | |
# common case is ssh'ing into a remote host that is running tmux. Hitting | |
# shift-up will cause (almost) all of the keybindings in the current tmux | |
# instance to go away letting the nested tmux see the keypresses. Hitting | |
# shift-down will return control to the parent tmux instance. I am limiting | |
# this to five levels because two should generally be enough and, since there | |
# is no math in tmux config, I have had to do addition/subtraction with | |
# if-shell commands. | |
# this runs every time a session is created. It creates an environment | |
# variable named nested_level that keeps track of how deep we have ceded | |
# control | |
set-hook -g session-created { set-environment nested_level 0 } | |
bind-key -T root S-up { | |
# no need to do math, we have to be going to level one if the root | |
# keybinding table still has shift-up in it | |
set-environment nested_level 1 | |
# turn off the prefix so the prefix can go to the deeper tmux instances | |
set-option prefix None | |
# set the keybinding table name to "nested", there are only two | |
# keybindings in that table and they are below | |
set-option key-table nested | |
# set inverse the window in the status bar so we know which one we were | |
# in | |
set-option window-status-current-style "fg=green,bg=black" | |
# if for some reason we were in copy mode, cancel it | |
if-shell -F '#{pane_in_mode}' { send-keys -X cancel } | |
# might as well update the status bar now instead of in a second | |
refresh-client -S | |
} | |
# since this is in the nested keybinding table, it won't run until unless | |
# the keybinding above has run. We are just doing some basic addition on | |
# nested_level and passing the shift-up on to the deeper level of tmux | |
bind-key -T nested S-up { | |
if-shell -F '#{==:#{nested_level},1}' { | |
set-environment nested_level 2 | |
send-keys S-up | |
} { | |
if-shell -F '#{==:#{nested_level},2}' { | |
send-keys S-up | |
set-environment nested_level 3 | |
} { | |
if-shell -F '#{==:#{nested_level},3}' { | |
send-keys S-up | |
set-environment nested_level 4 | |
} | |
} | |
} | |
} | |
# same as the two above but in reverse | |
bind-key -T nested S-down { | |
if-shell -F '#{==:#{nested_level},4}' { | |
set-environment nested_level 3 | |
send-keys S-down | |
} { | |
if-shell -F '#{==:#{nested_level},3}' { | |
set-environment nested_level 2 | |
send-keys S-down | |
} { | |
if-shell -F '#{==:#{nested_level},2}' { | |
set-environment nested_level 1 | |
send-keys S-down | |
} { | |
if-shell -F '#{==:#{nested_level},1}' { | |
set-environment nested_level 0 | |
set-option -u prefix | |
set-option -u key-table | |
set-option -u window-status-current-style | |
refresh-client -S | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment