Tmux is a great alternative to gnu screen. I’ve previously posted my cygwin tmux config in 2020, and I figured I’d update with my additions since then, including running under real linux. So here it is. Its features include:
- Uses ctrl+a, like gnu screen, instead of ctrl+b
- Mouse interaction is enabled
- Tab bar/windows:
- Current tab is highlighted in cyan
- Cycle through tabbed windows with a click on its tab or ctrl+shift+alt+arrow_keys
- Reorder tabbed windows with a drag of its tab
or alt+arrow_keys
- ctrl+a,/ to rename a tab on the tab bar
- Create new window with ctrl+a,c
- Panes
- Create split panes with vertical=ctrl+a,| and horizontal=ctrl+a,- (and start in the cwd)
- Move around panes with click or ctrl+shift+arrow_keys
- Resize panes by dragging on the separator bar or use alt+shift+arrow_keys
- Swap panes directionally with alt+arrow_keys
- Panes automatically resize to fit OS window
- Clipboard/highlighting
- Copy text to clipboard by highlighting it
- Paste from clipboard with right click
- Middle mouse button+drag highlights and copies too. I did this since nano takes over normal mouse click+drag.
- Copy mode
Key* | Action |
Ctrl+PageUp | Start copy mode, scroll page up |
Ctrl+PageDown | Start copy mode |
Enter | Copies selected text to clipboard and ends copy mode |
Shift+(Left/Right) | Starts selection mode on previous/next character (or continues selection navigation like normal left/right) |
Escape | If something is selected, end current selection. Otherwise, exit copy mode |
Ctrl+(Home/End) | Go to top/bottom of the buffer |
Ctrl+(Left/Right) | Moves to previous/next word like when not in copy mode |
Ctrl+F3, Ctrl+F3 | Start incremental search in copy mode |
F3/Shift+F3 | Search next/previous (Note, if you use gnome-terminal it may override this) |
* When bolded/cyan the key is for when in copy mode
- Start the session on the current bash directory
- Escape time is lowered for quicker response to copy mode access
To use this, save the file to ~/.tmux.conf
#Mouse interaction
set -g mouse on
#Lower escape timing from 500ms to 50ms for quicker response to copy-mode access
set -s escape-time 50
#Window always takes up largest possible max size
set-window-option -g aggressive-resize
#Highlight active window in tab-bar at bottom in cyan
set-window-option -g window-status-current-style bg=cyan
#Reorder windows in status bar by drag & drop
bind-key -n MouseDrag1Status swap-window -t=
#Copy to clipboard on text selection
bind -Tcopy-mode MouseDragEnd1Pane { send -X copy-selection-and-cancel; run-shell -b "tmux show-buffer | xclip -selection clipboard" }
#Paste from clipboard with right click
bind-key -n MouseDown3Pane { run-shell 'tmux set-buffer -b winclip "$(xclip -o -selection clipboard)"'; paste-buffer -db winclip }
#Middle drag runs copy (Since some programs like nano take control of the mouse for normal selection)
bind -n MouseDrag2Pane copy-mode -M
bind -Tcopy-mode MouseDragEnd2Pane { send -X copy-selection-and-cancel; run-shell -b "tmux show-buffer | xclip -selection clipboard" }
bind-key -n MouseDown2Pane run-shell -b "echo '' > /dev/null"
#Remap prefix to Control+a
set -g prefix C-a
unbind C-b
#bind 'C-a C-a' to type 'C-a'
bind C-a send-prefix
#Start in CWD when creating or splitting tabs; move the splitting planes keys to | and -
bind '|' split-window -h -c '#{pane_current_path}' # Split panes horizontal
bind '\' split-window -h -c '#{pane_current_path}' # Split panes horizontal
bind '-' split-window -v -c '#{pane_current_path}' # Split panes vertically
bind c new-window -c '#{pane_current_path}' # Create new window
unbind '"'
unbind %
#Select next/prev window with Ctrl+Shift+Alt+(Left|Right)
bind-key -n C-S-M-Right next-window
bind-key -n C-S-M-Left previous-window
#Reorder panes with Alt+arrow
bind-key -n M-Left swap-pane -t '{left-of}' -d
bind-key -n M-Right swap-pane -t '{right-of}' -d
bind-key -n M-Up swap-pane -t '{up-of}' -d
bind-key -n M-Down swap-pane -t '{down-of}' -d
#Switch panes using Ctrl+shift+arrow - I rather would have used Ctrl+arrow, but that can interfeer with other programs like nano
bind -n C-S-Left select-pane -L
bind -n C-S-Right select-pane -R
bind -n C-S-Up select-pane -U
bind -n C-S-Down select-pane -D
#Resize panes using Alt+Shift+arrow
bind-key -n M-S-Up resize-pane -U 1
bind-key -n M-S-Down resize-pane -D 1
bind-key -n M-S-Left resize-pane -L 1
bind-key -n M-S-Right resize-pane -R 1
#Ctrl+F3 starts searching in copy mode
bind -n C-F3 { copy-mode; command-prompt -T search -ip'(search down)' -I'#{pane_search_string}' { send -X search-forward-incremental '%%' } }
#prefix, / -- Renames window, but starts blank
bind-key / command-prompt "rename-window '%%'"
#---Copy mode---
#Enter key in copy mode copies to clipboard and ends copy mode
bind-key -Tcopy-mode Enter { send -X copy-selection-and-cancel; run-shell -b "tmux show-buffer | xclip -selection clipboard" }
#Ctrl+PageUp = Copy mode, scroll page up
bind-key -n C-PageUp copy-mode -u
#Ctrl+PageDown = Copy mode
bind-key -n C-PageDown copy-mode
#Shift+Left = Start selection mode on previous character (if selection mode is active, do not restart selection)
bind-key -Tcopy-mode S-Left { run-shell "tmux display-message -p \"#{selection_active}\" | awk '{print ($0 == 1) ? \"\" : \"tmux send -X begin-selection\"}' | sh"; send -X cursor-left }
#Shift+Right = Start selection mode on current character (if selection mode is active, do not restart selection)
bind-key -Tcopy-mode S-Right { run-shell "tmux display-message -p \"#{selection_active}\" | awk '{print ($0 == 1) ? \"\" : \"tmux send -X begin-selection\"}' | sh"; send -X cursor-right }
#Escape = If something is selected, end current selection. Otherwise, exit copy mode.
bind-key -Tcopy-mode Escape run-shell "tmux display-message -p \"#{selection_active}\" | awk '{print ($0 == 1) ? \"tmux send -X clear-selection\" : \"tmux send -X cancel\"}' | sh"
#Ctrl+Home = Go to top of buffer
bind-key -Tcopy-mode C-Home send -X history-top
#Ctrl+End = Go to bottom of buffer
bind-key -Tcopy-mode C-End send -X history-bottom
#Ctrl+Left = Previous work
bind-key -Tcopy-mode C-Left send -X previous-word
#Ctrl+Right = Next work
bind-key -Tcopy-mode C-Right send -X next-word
#Ctrl+F3 = Start incremental search
bind -Tcopy-mode C-F3 { command-prompt -T search -ip'(search down)' -I'#{pane_search_string}' { send -X search-forward-incremental '%%' } }
#F3 = Search next (Note, if you use gnome-terminal it may override this)
bind -Tcopy-mode F3 send -X search-again
#Shift+F3 = Search previous (Note, if you use gnome-terminal it may override this)
bind -Tcopy-mode S-F3 send -X search-reverse
|
Tmux is a great alternative to gnu screen. I can’t believe I’ve never posted my custom Tmux config for Cygwin after all the work I put into it years ago. So here it is. Its features include:
- Uses ctrl+a, like gnu screen, instead of ctrl+b
- Mouse interaction is enabled
- Tab bar/windows:
- Current tab is highlighted in cyan
- Cycle through tabbed windows with a click on its tab or ctrl+arrowkeys
- Reorder tabbed windows with a drag of its tab or alt+arrowkeys
- ctrl+a,/ to rename a tab on the tab bar
- Create new window with ctrl+a,c
- Panes
- Create split panes with vertical=ctrl+a,| and horizontal=ctrl+a,-
- Move around panes with click or ctrl+shift+arrowkeys
- Resize panes by dragging on the separator bar or use ctrl+shift+alt+arrowkeys
- Panes automatically resize to fit OS window
- Clipboard/highlighting
- Copy text to clipboard by highlighting it. Had to use a minor hack to fix a cygwin selection problem
- Paste from clipboard with right click
- Middle mouse button+drag starts copy mode
- When in copy mode, u runs the selection as a command in a separate window (Instead of “cygstart” for cygwin, use “xdg-open” for linux, or “open” for MacOS X)
- Double click selects word
- Double middle click runs the word under the mouse as a command
- Start the session on the current bash directory
- Escape time is lowered for quicker response to scroll buffer access (ctrl+a,pageup)
To use this, save the file to ~/.tmux.conf
#Set current directory setting for cygwin
set-environment -g CHERE_INVOKING 1
#Mouse interaction
set -g mouse on
#Lower escape timing from 500ms to 50ms for quicker response to scroll-buffer access
set -s escape-time 50
#Window always takes up largest possible max size
set-window-option -g aggressive-resize
#Highlight active window in tab-bar at bottom in cyan
set-window-option -g window-status-current-bg cyan
#Reorder windows in status bar by drag & drop
bind-key -n MouseDrag1Status swap-window -t=
#Copy to clipboard on text selection in cygwin. Move cursor position 1 to the right before copy to bypass a bug
bind -Tcopy-mode MouseDragEnd1Pane send-keys -X cursor-right\; send -X copy-selection-and-cancel\; run-shell -b "tmux show-buffer > /dev/clipboard"
#Paste from clipboard with right click in cygwin
bind-key -n MouseDown3Pane run-shell 'tmux set-buffer -b winclip "$(cat /dev/clipboard)"'\; paste-buffer -db winclip
#Middle drag starts copy mode
bind -n MouseDrag2Pane copy-mode -M
#When in copy mode, "u" runs the selection as a command in a separate window (Instead of "cygstart" for cygwin, use "xdg-open" for linux, or "open" for MacOS X)
bind -Tcopy-mode u send -X copy-selection-and-cancel\; run-shell -b "tmux show-buffer | xargs cygstart"
#Double click selects word
bind-key -n DoubleClick1Pane copy-mode -M\; send-keys -X select-word
#Double middle click runs the word under the mouse as a command. See description for MouseDown3Pane above
bind-key -n DoubleClick2Pane copy-mode -M\; send-keys -X select-word\; send -X copy-selection-and-cancel\; run-shell -b "tmux show-buffer | xargs cygstart"
#Remap prefix to Control+a
set -g prefix C-a
unbind C-b
#bind 'C-a C-a' to type 'C-a'
bind C-a send-prefix
#Start in CWD when creating or splitting tabs; move the splitting planes keys to | and -
bind '|' split-window -h -c '#{pane_current_path}' # Split panes horizontal
bind '-' split-window -v -c '#{pane_current_path}' # Split panes vertically
bind c new-window -c '#{pane_current_path}' # Create new window
unbind '"'
unbind %
#prefix, / -- Renames window, but starts blank
bind-key / command-prompt "rename-window '%%'"
#Select next/prev window with Ctrl+(Left|Right)
bind-key -n C-Right next-window
bind-key -n C-Left previous-window
#Reorder window with Alt+(Left|Right)
bind-key -n M-Left swap-window -t -1
bind-key -n M-Right swap-window -t +1
#Switch panes using Ctrl+Shift+arrow
bind -n C-S-Left select-pane -L
bind -n C-S-Right select-pane -R
bind -n C-S-Up select-pane -U
bind -n C-S-Down select-pane -D
#Resize panes using Ctrl+Shift+Alt+arrow
bind-key -n C-S-M-Up resize-pane -U 1
bind-key -n C-S-M-Down resize-pane -D 1
bind-key -n C-S-M-Left resize-pane -L 1
bind-key -n C-S-M-Right resize-pane -R 1
|
Since I’m doing the new install thing, I figured I’d record some of my setup. So here is my cygwin install.
- Internet utilities: wget, curl, ping, openssh, openssl-devel, mysql, nc
- Program compilation stuff: gcc-g++, autoconf, pkg-config, automake
- Programming languages: perl, python
- Other utilities for programming: git, sqlite3
- Text editor: nano
Mintty [non-default] options:
- Text->Locale=en_US UTF-8
- Mouse->Copy on select=Off
- Mouse->Clicks place command line cursor=On
I also haven’t decided yet if I will do apache or PHP via cygwin or windows installs yet. May do a post about that later. |
As of 2010, if you wanted to set up a MySQL replication configuration with multiple servers which could all update and send the updates to the other servers, a replication ring was the only solution (in which every server has a master and a slave in a ring configuration). While there are new (probably better) solutions as of late including using MariaDB’s multi-source replication, and tungsten-replicator (which I was referred to in late April and have not yet tried), I still find a replication ring to be an easy to use solution in some circumstances. However, there are some major disadvantages including:
- If one node in the ring goes down, the entire ring stops replicating at that point until the node is brought back up
- If a node goes down in the ring and has corrupted or incomplete data, say, from a power outdate, the entire ring may have to be painstakingly synced and rebuilt.
Anywho, the following is my basic MySQL configurations for setting up a replication ring, which needs to be put on every server node in the ring: (See MySQL docs for more information on each configuration)
[mysqld]
#---GENERAL REPLICATION VARIABLES--- (These should never change)
log_bin=mysql-bin.log #Turn on the binary log, which is used to hold queries that are propagated to other machines
slave-skip-errors = 1062 #Do not stop replication if a duplicate key is found (which shouldn’t happen anyways). You may want to turn this off to verify integrity, but then your replication ring will stop if a duplicate key is found
#master-connect-retry = 5 #How often to keep trying to reconnect to the master node of the current machine after a connection is lost. This has been removed as of MySQL 5.5, and needs to instead be included in the “CHANGE MASTER” command
sync_binlog = 100 #After how many queries, sync to the binlog
slave_net_timeout = 120 #The number of seconds to wait for more data from a master/slave before restarting the connection
max_binlog_size = 1000M #The maximum size the binlog can get before creating a new binlog
log-slave-updates #Log slave updates to the binary log. If there are only 2 nodes in the ring, this is not required
slave_exec_mode = IDEMPOTENT #Suppression of duplicate-key and no-key-found errors
replicate-same-server-id = 0 #Skip running SQL commands received via replication that were generated by the current server node
#---INDEPENDENT REPLICATION VARIABLES--- (These should change per setup)
binlog-do-db = DATABASE_NAME #Only add statements from this database to the binlog. You can have multiple of these configurations
replicate-do-db = DATABASE_NAME #Only read statements from this database during replication. You can have multiple of these configurations
auto_increment_increment = 2 #After ever auto-increment, add this to its number. Set this to the number of nodes. This helps assures no duplicate IDs
#---SERVER CONFIGURATION--- (These numbers should match)
server-id = 1 #The current node number in the ring. Every node needs to have its own incremental server number starting at 1
auto_increment_offset = 1 #What to start auto-increment numbers at for this server. Set this to the server-id. This helps assures no duplicate IDs
|