From d7a97dd0854c5b4754c95b9d567362d7d6f0c1c8 Mon Sep 17 00:00:00 2001 From: Anton Zadvorny Date: Sat, 24 Feb 2018 17:19:17 +0300 Subject: [PATCH] New tmux config --- home/.tmux.conf | 263 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 203 insertions(+), 60 deletions(-) diff --git a/home/.tmux.conf b/home/.tmux.conf index cfb991b..d37d6c2 100644 --- a/home/.tmux.conf +++ b/home/.tmux.conf @@ -1,78 +1,221 @@ -# status bar -set -g status-right-length 20 -set -g status-right '#[fg=red]#H#[fg=green]:#[fg=white]#S #[fg=green]][#[default]' -set -g status-left '' +################################################################################ +#### Unbreak things -# default statusbar colors -set -g status-fg white -set -g status-bg default -set -g status-attr bright +# Prevent tmux from messing up keybindings and colors. +# This is witchcraft, I have no explanation for the following commands. +set-option -g xterm-keys on +set-window-option -g xterm-keys on +set-option -g default-terminal "xterm-256color" -# default window title colors -set-window-option -g window-status-fg white -set-window-option -g window-status-bg default -set-window-option -g window-status-attr dim +# Prevent tmux from waiting half a second before processing the ESC key, see: +# http://unix.stackexchange.com/a/25638/176805 +set-option -s escape-time 0 -# active window title colors -set-window-option -g window-status-current-fg white -set-window-option -g window-status-current-bg default -set-window-option -g window-status-current-attr bright +# Enable proper mouse support: +# http://www.hamvocke.com/blog/a-guide-to-customizing-your-tmux-conf/ +set-option -g mouse on -# C-b is not acceptable -- Vim uses it -# set-option -g prefix C-a -# bind-key C-a last-window +# The following line prevents a weird OS X problem that otherwise +# keeps the "open" command from working (and has several other +# undesirable properties; see issue #120). For more details on the +# issue, see [1]-[5]. +# +# The exact version of the solution below is the only way I have found +# to satisfy all of the following properties: +# +# * It fixes the problem, i.e. "open" works correctly. +# +# * When opening a new window in tmux, the window name is correctly +# set to zsh initially. It does not briefly flash +# "reattach-to-user-namespace", and it does not display +# "/usr/local/bin/zsh" either. +# +# * The "automatic-rename" property is still set to "on" in new tmux +# windows, meaning that if you run another program, the window name +# will change to reflect that (unless you manually rename the +# window). +# +# * Exiting the shell (e.g. with Control+D) will immediately kill the +# tmux window instead of dropping you into another shell. +# +# * It works for all shells, and doesn't hardcode any particular one. +# +# * It still works when reattach-to-user-namespace is unavailable. +# +# Yes, it's horrible. I think we can all agree on that, no need to +# point it out. +# +# Unfortunately, tmux appears to be remarkably unintelligent when it +# comes to determining the string to show as the window title. +# Basically, about as unintelligent as shebang parsing, and anyone +# involved in the virtualenv-can't-handle-spaces fiasco will know +# that's pretty darn unintelligent. In particular, it grabs characters +# literally from the beginning of the command string until it hits a +# space, then discards until the first slash, if there is one. This +# means it's impossible to quote the executable name, so if your shell +# has spaces in its name, you're screwed. Making this whole fiasco +# work for paths with double quotes in it is an exercise in futility, +# I think. +# +# [1]: http://superuser.com/q/834525/326239 +# [2]: http://www.economyofeffort.com/2013/07/29/reattach-to-user-namespace-the-fix-for-your-tmux-in-os-x-woes/ +# [3]: https://www.elmund.io/osx/2015/07/10/open-command-in-osx-tmux/ +# [4]: https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard +# [5]: https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard/issues/10 -# Start numbering at 1 -set -g base-index 1 +run-shell 'command -v reattach-to-user-namespace > /dev/null && tmux set-option -g default-command "$SHELL -c \"reattach-to-user-namespace -l \\\"$(basename "$SHELL")\\\"\"" || true' -# Allows for faster key repetition -set -s escape-time 0 +################################################################################ +#### Keybindings -# Rather than constraining window size to the maximum size of any client -# connected to the *session*, constrain window size to the maximum size of any -# client connected to *that window*. Much more reasonable. -setw -g aggressive-resize on +# Use ` instead of C-b as prefix key, see: +# http://www.hamvocke.com/blog/a-guide-to-customizing-your-tmux-conf/ +unbind-key C-b +set-option -g prefix ` +bind-key ` send-prefix -# Allows us to use C-a a to send commands to a TMUX session inside -# another TMUX session -bind-key a send-prefix +# Force tmux to use Emacs keybindings, see: +# http://stackoverflow.com/q/18240683/3538165 +# http://stackoverflow.com/a/18247437/3538165 +set-option -g status-keys emacs +set-window-option -g mode-keys emacs -# Activity monitoring -setw -g monitor-activity on -set -g visual-activity on +# Turn off repeatability for moving between panes. Otherwise, if you split +# horizontally and switch panes, you will have to wait for the 'repeat period' +# to expire before you can use and to page through shell history. +# +# Doing it this way instead of using 'set-option -g repeat-time 0' makes it +# so that Control+Arrows and Meta+Arrows (for resizing panes) are still +# repeatable. +# +# See: http://superuser.com/a/325579/326239 +bind-key Up select-pane -U +bind-key Down select-pane -D +bind-key Left select-pane -L +bind-key Right select-pane -R -# Highlight active window -set-window-option -g window-status-current-bg red +# Keybinding for reloading .tmux.conf. +bind-key R source-file ~/.tmux.conf -# VI keybindings please -setw -g mode-keys vi +# Keybinding for swapping the current and marked windows. +bind-key \ swap-window -# VI for splitting -bind s split-window -v -bind v split-window -h +# Keybindings for swapping adjacent windows. +bind-key < swap-window -t -1 +bind-key > swap-window -t +1 -# Vi copypaste mode -set-window-option -g mode-keys vi -bind-key -T copy-mode-vi 'v' begin-selection -bind-key -T copy-mode-vi 'y' copy-selection +# Keybinding for inserting a window. +# Adapted from http://superuser.com/a/704551/326239 +bind-key I command-prompt -p 'Insert window at:' ' \ + run-shell " \ + if tmux select-window -t %1; then \ + tmux new-window -a; \ + tmux swap-window -s %1 -t \$((%1+1)); \ + else \ + tmux new-window; \ + tmux move-window -t %1; \ + fi; \ + tmux select-window -t #{window_id}; \ + tmux select-window -t %1; \ + "' -# hjkl pane traversal -bind h select-pane -L -bind j select-pane -D -bind k select-pane -U -bind l select-pane -R +################################################################################ +#### Status bar -# reload config -bind r source-file ~/.tmux.conf \; display-message "Config reloaded..." +# The following code is adapted from: +# https://coderwall.com/p/trgyrq/make-your-tmux-status-bar-responsive +# It provides the same appearance as https://github.com/powerline/powerline, +# but sidesteps the environment/configuration hell which that project +# introduces. -# auto window rename -set-window-option -g automatic-rename +# Format to display on the left-hand side of the status bar. +# Note that the conditional #{?cond,true,false} operator does not do any +# fancy parsing, so you can't have literal commas in the conditions -- +# this will cause the conditions to be split up. So we have to use multiple +# style #[attr=value] directives. +set-option -g status-left '#{?client_prefix,#[fg=colour254]#[bg=colour31],#[fg=colour16]#[bg=colour254]#[bold]} #{=80:session_name} #{?client_prefix,#[fg=colour31],#[fg=colour254]}#[bg=colour234,nobold] ' -# color -set -g default-terminal "screen-256color" +# Maximum length of the format displayed on the left-hand side. +# Since the maximum length of the session name is limited in the above +# format string, this number is unimportant -- it just needs to be a +# bit larger than what is allocated for the session name, to allow for +# the surrounding characters. +set-option -g status-left-length 90 -# Pane resizing -bind-key J resize-pane -D 10 -bind-key K resize-pane -U 10 -bind-key H resize-pane -L 10 -bind-key L resize-pane -R 10 +# Format to display on the right-hand side of the status bar. +set-option -g status-right '' + +# Format to display for the current window. +set-option -g window-status-current-format "#[fg=colour117,bg=colour31] #{window_index}#{window_flags} #[fg=colour231,bold]#{window_name} #[fg=colour31,bg=colour234,nobold] " + +# Format to display for other windows. +set-option -g window-status-format "#[fg=colour244,bg=colour234]#{window_index}#{window_flags} #[fg=colour249]#{window_name} " + +# Background color for parts of the status bar not specified by the above +# formats. For instance, the empty space to the right, and the single +# spaces between instances of window-status-format. +set-option -g status-bg colour234 + +# Inhibit the default styling for windows with unseen activity, which +# looks blatantly incorrect with the "powerline" theme we are trying to +# emulate. +set-window-option -g window-status-activity-attr none + +# Update the status bar every second, instead of the default 15(!) +# seconds. It doesn't look like it's possible to update more than +# once per second, unfortunately. +set-option -g status-interval 1 + +################################################################################ +#### Appearance + +# Attempt to set the title of the terminal emulator. +set-option -g set-titles on +set-option -g set-titles-string '#{session_name} - #{window_name}' + +# Show an indicator in the status bar on windows with unseen activity. +set-option -g monitor-activity on + +# Make the borders of the current pane the same color as the borders +# of other panes. This is because the borders of the marked pane are +# *inverted*, and while different foreground colors in different parts +# of the frame are not too objectionable, different background colors +# look very bad. +set-option -g pane-active-border-style none + +################################################################################ +#### Miscellaneous + +# When the current session is killed, switch to another session instead of +# detaching. +set-option -g detach-on-destroy off + +# Show messages until they are dismissed, instead of for 750 milliseconds(!). +# Actually it is only for an hour, because it doesn't seem like you can turn +# off the time limit. +set-option -g display-time 36000000 + +# Open new windows in the same directory as the current pane. +bind-key c new-window -c "#{pane_current_path}" + +# Automatically renumber windows when one is deleted, see: +# http://unix.stackexchange.com/a/51879/176805 +set-option -g renumber-windows on + +# Number windows and panes from 1, instead of 0; see: +# http://unix.stackexchange.com/a/35932/176805 +set-option -g base-index 1 +set-window-option -g pane-base-index 1 + +# Open new panes in the same directory as the current pane. +bind-key % split-window -h -c "#{pane_current_path}" +bind-key '"' split-window -v -c "#{pane_current_path}" + +# Increase the scrollback buffer size from 2000 to a larger size, but +# not one so large that tmux begins to lag. +set-option -g history-limit 10000 + +################################################################################ +#### Local overrides + +if-shell "[[ -f ~/.tmux.local.conf ]]" "source ~/.tmux.local.conf" \ No newline at end of file