TMUX
TMUX == GNU Screen x 2.. here is a screenshot from my Arch Linux ThinkPenguin.com laptop back in 2014. That bg image, taken from the International Space Station is now one of my favorite grub boot bg images.
tmux usage
Note: This is primarily an article of my notes taken from reading the tmux source code. I'll add some good practical usage another time perhaps.
usage: %s [-2lquvV] [-c shell-command] [-f file] [-L socket-name] [-S socket-path] [command [flags]]
tmux.conf
Per my usual habit, I downloaded the tmux source code and poured over it for weeks. The purpose of that wasn't abstract, I work to find and build systems that once built will enable and empower my computing for a long time. In this case, for me that meant building a super optimized and understood tmux.conf -- here is the one I am using at the moment. tmux.conf
Tmux Command Aliases
grep -h 'const struct cmd_entry' -A1 cmd-*.c|nobb|grep -v '^const'|grep -v '^\-\-'|trs|nobb| sed 's,^"\([^"]\+\)"\, *"\([^"]\+\)"..*$,\2:
- attach: attach-session
- bind: bind-key
- breakp: break-pane
- capturep: capture-pane
- clearhist: clear-history
- confirm: confirm-before
- deleteb: delete-buffer
- detach: detach-client
- display: display-message
- displayp: display-panes
- findw: find-window
- has: has-session
- if: if-shell
- joinp: join-pane
- killp: kill-pane
- killw: kill-window
- last: last-window
- lastp: last-pane
- linkw: link-window
- loadb: load-buffer
- lock: lock-server
- lockc: lock-client
- locks: lock-session
- ls: list-sessions
- lsb: list-buffers
- lsc: list-clients
- lscm: list-commands
- lsk: list-keys
- lsp: list-panes
- lsw: list-windows
- movep: move-pane
- movew: move-window
- new: new-session
- neww: new-window
- next: next-window
- nextl: next-layout
- pasteb: paste-buffer
- pipep: pipe-pane
- prev: previous-window
- prevl: previous-layout
- refresh: refresh-client
- rename: rename-session
- renamew: rename-window
- resizep: resize-pane
- respawnp: respawn-pane
- respawnw: respawn-window
- rotatew: rotate-window
- run: run-shell
- saveb: save-buffer
- selectl: select-layout
- selectp: select-pane
- selectw: select-window
- send: send-keys
- set: set-option
- setb: set-buffer
- setenv: set-environment
- setw: set-window-option
- show: show-options
- showb: show-buffer
- showenv: show-environment
- showmsgs: show-messages
- showw: show-window-options
- source: source-file
- splitw: split-window
- start: start-server
- suspendc: suspend-client
- swapp: swap-pane
- swapw: swap-window
- switchc: switch-client
- unbind: unbind-key
- unlinkw: unlink-window
- wait: wait-for
- info: server-info
Default Templates
- CHOOSE_BUFFER_TEMPLATE
- Default template for choose-buffer.
"#{line}: #{buffer_size} bytes: #{buffer_sample}"
- CHOOSE_CLIENT_TEMPLATE
- Default template for choose-client.
"#{client_tty}: #{session_name} [#{client_width}x#{client_height} #{client_termname}]#{?client_utf8, (utf8),}#{?client_readonly, (ro),} (last used #{client_activity_string})"
- CHOOSE_TREE_SESSION_TEMPLATE
- Default templates for choose-tree.
"#{session_name}: #{session_windows} windows#{?session_grouped, (group ,}#{session_group}#{?session_grouped,),}#{?session_attached, (attached),}"
- CHOOSE_TREE_WINDOW_TEMPLATE
"#{window_index}: #{window_name}#{window_flags} \"#{pane_title}\""
- DISPLAY_MESSAGE_TEMPLATE
- Default template for display-message.
"[#{session_name}] #{window_index}:#{window_name}, current pane #{pane_index} - (%H:%M %d-%b-%y)"
- FIND_WINDOW_TEMPLATE
- Default template for find-window.
"#{window_index}: #{window_name} [#{window_width}x#{window_height}] (#{window_panes} panes) #{window_find_matches}"
- LIST_BUFFERS_TEMPLATE
- Default template for list-buffers.
"#{line}: #{buffer_size} bytes: \"#{buffer_sample}\""
- LIST_CLIENTS_TEMPLATE
- Default template for list-clients.
"#{client_tty}: #{session_name} [#{client_width}x#{client_height} #{client_termname}]#{?client_utf8, (utf8),} #{?client_readonly, (ro),}"
- LIST_SESSIONS_TEMPLATE
- Default template for list-sessions.
"#{session_name}: #{session_windows} windows (created #{session_created_string}) [#{session_width}x#{session_height}]#{?session_grouped, (group ,}#{session_group}#{?session_grouped,),}#{?session_attached, (attached),}"
- LIST_WINDOWS_TEMPLATE
- Default templates for list-windows.
"#{window_index}: #{window_name}#{window_flags} (#{window_panes} panes) [#{window_width}x#{window_height}] [layout #{window_layout}] #{window_id}#{?window_active, (active),}"
- LIST_WINDOWS_WITH_SESSION_TEMPLATE
"#{session_name}:#{window_index}: #{window_name}#{window_flags} (#{window_panes} panes) [#{window_width}x#{window_height}] "
- NEW_SESSION_TEMPLATE
"#{session_name}:"
- BREAK_PANE_TEMPLATE
"#{session_name}:#{window_index}.#{pane_index}"
- NEW_WINDOW_TEMPLATE
"#{session_name}:#{window_index}.#{pane_index}"
- SPLIT_WINDOW_TEMPLATE
"#{session_name}:#{window_index}.#{pane_index}"
tmux main() processing order:
struct options global_options; /* server options */ struct options global_s_options; /* session options */ struct options global_w_options; /* window options */ struct environ global_environ;
- Parse cmd line options
while ((opt = getopt(argc, argv, "2c:Cdf:lL:qS:uUVv")) != -1)
- Setup global environment
for (var = environ; *var != NULL; var++) environ_put(&global_environ, *var);
- Set PWD
if (getcwd(tmp, sizeof tmp) != NULL) environ_set(&global_environ, "PWD", tmp);
- Populate Server Options
options_table_populate_tree(server_options_table, &global_options)
- Populate Session Options
options_table_populate_tree(session_options_table, &global_s_options);
- Set default-shell in global session option to the current shell
options_set_string(&global_s_options, "default-shell", "%s", getshell());
- Populate Window Options
options_table_populate_tree(window_options_table, &global_w_options);
- Enable UTF-8 if first client is on UTF-8 terminal
if (flags & CLIENT_UTF8) { options_set_number(&global_s_options, "status-utf8", 1); options_set_number(&global_s_options, "mouse-utf8", 1); options_set_number(&global_w_options, "utf8", 1); }
- Override keys to vi if VISUAL or EDITOR are set
if ((s = getenv("VISUAL")) != NULL || (s = getenv("EDITOR")) != NULL) { if (strrchr(s, '/') != NULL) s = strrchr(s, '/') + 1; if (strstr(s, "vi") != NULL) keys = MODEKEY_VI; else keys = MODEKEY_EMACS; options_set_number(&global_s_options, "status-keys", keys); options_set_number(&global_w_options, "mode-keys", keys); }
- Locate the configuration file.
- Get path from environment
s = getenv("TMUX"); if (s != NULL && sscanf(s, "%255[^,],%lld,%d", in, &pid, &session) == 3) environ_path = xstrdup(in);
- Figure out the socket path and use.
- Set process title.
#ifdef HAVE_SETPROCTITLE setproctitle("%s (%s)", __progname, socket_path);
- Pass control to the client
ev_base = osdep_event_init(); exit(client_main(argc, argv, flags));
tmux.c
makesocketpath
makesocketpath sets the socketpath in this order.
- TMUX_TMPDIR
- TMPDIR
char * makesocketpath(const char *label) { char base[MAXPATHLEN], realbase[MAXPATHLEN], *path, *s; struct stat sb; u_int uid; uid = getuid(); if ((s = getenv("TMUX_TMPDIR")) != NULL && *s != '\0') xsnprintf(base, sizeof base, "%s/", s); else if ((s = getenv("TMPDIR")) != NULL && *s != '\0') xsnprintf(base, sizeof base, "%s/tmux-%u", s, uid); else xsnprintf(base, sizeof base, "%s/tmux-%u", _PATH_TMP, uid); if (mkdir(base, S_IRWXU) != 0 && errno != EEXIST) return (NULL); if (lstat(base, &sb) != 0) return (NULL); if (!S_ISDIR(sb.st_mode)) { errno = ENOTDIR; return (NULL); } if (sb.st_uid != uid || (!S_ISDIR(sb.st_mode) && sb.st_mode & (S_IRWXG|S_IRWXO)) != 0) { errno = EACCES; return (NULL); } if (realpath(base, realbase) == NULL) strlcpy(realbase, base, sizeof realbase); xasprintf(&path, "%s/%s", realbase, label); return (path); }
shell_exec
__dead void shell_exec(const char *shell, const char *shellcmd) { const char *shellname, *ptr; char *argv0; ptr = strrchr(shell, '/'); if (ptr != NULL && *(ptr + 1) != '\0') shellname = ptr + 1; else shellname = shell; if (login_shell) xasprintf(&argv0, "-%s", shellname); else xasprintf(&argv0, "%s", shellname); setenv("SHELL", shell, 1); setblocking(STDIN_FILENO, 1); setblocking(STDOUT_FILENO, 1); setblocking(STDERR_FILENO, 1); closefrom(STDERR_FILENO + 1); execl(shell, argv0, "-c", shellcmd, (char *) NULL); fatal("execl failed"); }
tmux.h
extern struct options global_options; extern struct options global_s_options; extern struct options global_w_options; extern struct environ global_environ;
notify.c
void notify_enable(void); void notify_disable(void); void notify_input(struct window_pane *, struct evbuffer *); void notify_window_layout_changed(struct window *); void notify_window_unlinked(struct session *, struct window *); void notify_window_linked(struct session *, struct window *); void notify_window_renamed(struct window *); void notify_attached_session_changed(struct client *); void notify_session_renamed(struct session *); void notify_session_created(struct session *); void notify_session_closed(struct session *);
options-table.c
extern const struct options_table_entry server_options_table[]; extern const struct options_table_entry session_options_table[]; extern const struct options_table_entry window_options_table[];
Default Templates
key codes
/* Special key codes. */ #define KEYC_NONE 0xfff #define KEYC_BASE 0x1000 /* Key modifier bits. */ #define KEYC_ESCAPE 0x2000 #define KEYC_CTRL 0x4000 #define KEYC_SHIFT 0x8000 #define KEYC_PREFIX 0x10000 /* Mask to obtain key w/o modifiers. */ #define KEYC_MASK_MOD (KEYC_ESCAPE|KEYC_CTRL|KEYC_SHIFT|KEYC_PREFIX) #define KEYC_MASK_KEY (~KEYC_MASK_MOD) /* Other key codes. */ enum key_code { /* Mouse key. */ KEYC_MOUSE = KEYC_BASE, /* Backspace key. */ KEYC_BSPACE, /* Function keys. */ KEYC_F1, KEYC_F2, KEYC_F3, KEYC_F4, KEYC_F5, KEYC_F6, KEYC_F7, KEYC_F8, KEYC_F9, KEYC_F10, KEYC_F11, KEYC_F12, KEYC_F13, KEYC_F14, KEYC_F15, KEYC_F16, KEYC_F17, KEYC_F18, KEYC_F19, KEYC_F20, KEYC_IC, KEYC_DC, KEYC_HOME, KEYC_END, KEYC_NPAGE, KEYC_PPAGE, KEYC_BTAB, /* Arrow keys. */ KEYC_UP, KEYC_DOWN, KEYC_LEFT, KEYC_RIGHT, /* Numeric keypad. */ KEYC_KP_SLASH, KEYC_KP_STAR, KEYC_KP_MINUS, KEYC_KP_SEVEN, KEYC_KP_EIGHT, KEYC_KP_NINE, KEYC_KP_PLUS, KEYC_KP_FOUR, KEYC_KP_FIVE, KEYC_KP_SIX, KEYC_KP_ONE, KEYC_KP_TWO, KEYC_KP_THREE, KEYC_KP_ENTER, KEYC_KP_ZERO, KEYC_KP_PERIOD, KEYC_FOCUS_IN, KEYC_FOCUS_OUT, };
Termcap codes
enum tty_code_code { TTYC_AX = 0, TTYC_ACSC, /* acs_chars, ac */ TTYC_BEL, /* bell, bl */ TTYC_BLINK, /* enter_blink_mode, mb */ TTYC_BOLD, /* enter_bold_mode, md */ TTYC_CIVIS, /* cursor_invisible, vi */ TTYC_CLEAR, /* clear_screen, cl */ TTYC_CNORM, /* cursor_normal, ve */ TTYC_COLORS, /* max_colors, Co */ TTYC_CR, /* restore cursor colour, Cr */ TTYC_CS, /* set cursor colour, Cs */ TTYC_CSR, /* change_scroll_region, cs */ TTYC_CUB, /* parm_left_cursor, LE */ TTYC_CUB1, /* cursor_left, le */ TTYC_CUD, /* parm_down_cursor, DO */ TTYC_CUD1, /* cursor_down, do */ TTYC_CUF, /* parm_right_cursor, RI */ TTYC_CUF1, /* cursor_right, nd */ TTYC_CUP, /* cursor_address, cm */ TTYC_CUU, /* parm_up_cursor, UP */ TTYC_CUU1, /* cursor_up, up */ TTYC_DCH, /* parm_dch, DC */ TTYC_DCH1, /* delete_character, dc */ TTYC_DIM, /* enter_dim_mode, mh */ TTYC_DL, /* parm_delete_line, DL */ TTYC_DL1, /* delete_line, dl */ TTYC_E3, TTYC_ECH, /* erase_chars, ec */ TTYC_EL, /* clr_eol, ce */ TTYC_EL1, /* clr_bol, cb */ TTYC_ENACS, /* ena_acs, eA */ TTYC_FSL, /* from_status_line, fsl */ TTYC_HOME, /* cursor_home, ho */ TTYC_HPA, /* column_address, ch */ TTYC_ICH, /* parm_ich, IC */ TTYC_ICH1, /* insert_character, ic */ TTYC_IL, /* parm_insert_line, IL */ TTYC_IL1, /* insert_line, il */ TTYC_INVIS, /* enter_secure_mode, mk */ TTYC_IS1, /* init_1string, i1 */ TTYC_IS2, /* init_2string, i2 */ TTYC_IS3, /* init_3string, i3 */ TTYC_KCBT, /* key_btab, kB */ TTYC_KCUB1, /* key_left, kl */ TTYC_KCUD1, /* key_down, kd */ TTYC_KCUF1, /* key_right, kr */ TTYC_KCUU1, /* key_up, ku */ TTYC_KDC2, TTYC_KDC3, TTYC_KDC4, TTYC_KDC5, TTYC_KDC6, TTYC_KDC7, TTYC_KDCH1, /* key_dc, kD */ TTYC_KDN2, TTYC_KDN3, TTYC_KDN4, TTYC_KDN5, TTYC_KDN6, TTYC_KDN7, TTYC_KEND, /* key_end, ke */ TTYC_KEND2, TTYC_KEND3, TTYC_KEND4, TTYC_KEND5, TTYC_KEND6, TTYC_KEND7, TTYC_KF1, /* key_f1, k1 */ TTYC_KF10, /* key_f10, k; */ TTYC_KF11, /* key_f11, F1 */ TTYC_KF12, /* key_f12, F2 */ TTYC_KF13, /* key_f13, F3 */ TTYC_KF14, /* key_f14, F4 */ TTYC_KF15, /* key_f15, F5 */ TTYC_KF16, /* key_f16, F6 */ TTYC_KF17, /* key_f17, F7 */ TTYC_KF18, /* key_f18, F8 */ TTYC_KF19, /* key_f19, F9 */ TTYC_KF2, /* key_f2, k2 */ TTYC_KF20, /* key_f20, F10 */ TTYC_KF3, /* key_f3, k3 */ TTYC_KF4, /* key_f4, k4 */ TTYC_KF5, /* key_f5, k5 */ TTYC_KF6, /* key_f6, k6 */ TTYC_KF7, /* key_f7, k7 */ TTYC_KF8, /* key_f8, k8 */ TTYC_KF9, /* key_f9, k9 */ TTYC_KHOM2, TTYC_KHOM3, TTYC_KHOM4, TTYC_KHOM5, TTYC_KHOM6, TTYC_KHOM7, TTYC_KHOME, /* key_home, kh */ TTYC_KIC2, TTYC_KIC3, TTYC_KIC4, TTYC_KIC5, TTYC_KIC6, TTYC_KIC7, TTYC_KICH1, /* key_ic, kI */ TTYC_KLFT2, TTYC_KLFT3, TTYC_KLFT4, TTYC_KLFT5, TTYC_KLFT6, TTYC_KLFT7, TTYC_KMOUS, /* key_mouse, Km */ TTYC_KNP, /* key_npage, kN */ TTYC_KNXT2, TTYC_KNXT3, TTYC_KNXT4, TTYC_KNXT5, TTYC_KNXT6, TTYC_KNXT7, TTYC_KPP, /* key_ppage, kP */ TTYC_KPRV2, TTYC_KPRV3, TTYC_KPRV4, TTYC_KPRV5, TTYC_KPRV6, TTYC_KPRV7, TTYC_KRIT2, TTYC_KRIT3, TTYC_KRIT4, TTYC_KRIT5, TTYC_KRIT6, TTYC_KRIT7, TTYC_KUP2, TTYC_KUP3, TTYC_KUP4, TTYC_KUP5, TTYC_KUP6, TTYC_KUP7, TTYC_MS, /* modify xterm(1) selection */ TTYC_OP, /* orig_pair, op */ TTYC_REV, /* enter_reverse_mode, mr */ TTYC_RI, /* scroll_reverse, sr */ TTYC_RMACS, /* exit_alt_charset_mode */ TTYC_RMCUP, /* exit_ca_mode, te */ TTYC_RMKX, /* keypad_local, ke */ TTYC_SE, /* reset cursor style, Se */ TTYC_SETAB, /* set_a_background, AB */ TTYC_SETAF, /* set_a_foreground, AF */ TTYC_SGR0, /* exit_attribute_mode, me */ TTYC_SITM, /* enter_italics_mode, it */ TTYC_SMACS, /* enter_alt_charset_mode, as */ TTYC_SMCUP, /* enter_ca_mode, ti */ TTYC_SMKX, /* keypad_xmit, ks */ TTYC_SMSO, /* enter_standout_mode, so */ TTYC_SMUL, /* enter_underline_mode, us */ TTYC_SS, /* set cursor style, Ss */ TTYC_TSL, /* to_status_line, tsl */ TTYC_VPA, /* row_address, cv */ TTYC_XENL, /* eat_newline_glitch, xn */ TTYC_XT, /* xterm(1)-compatible title, XT */ }; #define NTTYCODE (TTYC_XT + 1) /* Termcap types. */ enum tty_code_type { TTYCODE_NONE = 0, TTYCODE_STRING, TTYCODE_NUMBER, TTYCODE_FLAG, };
Message codes
enum msgtype { MSG_VERSION = 12, MSG_IDENTIFY_FLAGS = 100, MSG_IDENTIFY_TERM, MSG_IDENTIFY_TTYNAME, MSG_IDENTIFY_CWD, MSG_IDENTIFY_STDIN, MSG_IDENTIFY_ENVIRON, MSG_IDENTIFY_DONE, MSG_COMMAND = 200, MSG_DETACH, MSG_DETACHKILL, MSG_EXIT, MSG_EXITED, MSG_EXITING, MSG_LOCK, MSG_READY, MSG_RESIZE, MSG_SHELL, MSG_SHUTDOWN, MSG_STDERR, MSG_STDIN, MSG_STDOUT, MSG_SUSPEND, MSG_UNLOCK, MSG_WAKEUP, };
Mode key commands
enum mode_key_cmd { MODEKEY_NONE, MODEKEY_OTHER, /* Editing keys. */ MODEKEYEDIT_BACKSPACE, MODEKEYEDIT_CANCEL, MODEKEYEDIT_COMPLETE, MODEKEYEDIT_CURSORLEFT, MODEKEYEDIT_CURSORRIGHT, MODEKEYEDIT_DELETE, MODEKEYEDIT_DELETELINE, MODEKEYEDIT_DELETETOENDOFLINE, MODEKEYEDIT_DELETEWORD, MODEKEYEDIT_ENDOFLINE, MODEKEYEDIT_ENTER, MODEKEYEDIT_HISTORYDOWN, MODEKEYEDIT_HISTORYUP, MODEKEYEDIT_NEXTSPACE, MODEKEYEDIT_NEXTSPACEEND, MODEKEYEDIT_NEXTWORD, MODEKEYEDIT_NEXTWORDEND, MODEKEYEDIT_PASTE, MODEKEYEDIT_PREVIOUSSPACE, MODEKEYEDIT_PREVIOUSWORD, MODEKEYEDIT_STARTOFLINE, MODEKEYEDIT_SWITCHMODE, MODEKEYEDIT_SWITCHMODEAPPEND, MODEKEYEDIT_SWITCHMODEAPPENDLINE, MODEKEYEDIT_SWITCHMODEBEGINLINE, MODEKEYEDIT_SWITCHMODECHANGELINE, MODEKEYEDIT_SWITCHMODESUBSTITUTE, MODEKEYEDIT_SWITCHMODESUBSTITUTELINE, MODEKEYEDIT_TRANSPOSECHARS, /* Menu (choice) keys. */ MODEKEYCHOICE_BACKSPACE, MODEKEYCHOICE_BOTTOMLINE, MODEKEYCHOICE_CANCEL, MODEKEYCHOICE_CHOOSE, MODEKEYCHOICE_DOWN, MODEKEYCHOICE_ENDOFLIST, MODEKEYCHOICE_PAGEDOWN, MODEKEYCHOICE_PAGEUP, MODEKEYCHOICE_SCROLLDOWN, MODEKEYCHOICE_SCROLLUP, MODEKEYCHOICE_STARTNUMBERPREFIX, MODEKEYCHOICE_STARTOFLIST, MODEKEYCHOICE_TOPLINE, MODEKEYCHOICE_TREE_COLLAPSE, MODEKEYCHOICE_TREE_COLLAPSE_ALL, MODEKEYCHOICE_TREE_EXPAND, MODEKEYCHOICE_TREE_EXPAND_ALL, MODEKEYCHOICE_TREE_TOGGLE, MODEKEYCHOICE_UP, /* Copy keys. */ MODEKEYCOPY_APPENDSELECTION, MODEKEYCOPY_BACKTOINDENTATION, MODEKEYCOPY_BOTTOMLINE, MODEKEYCOPY_CANCEL, MODEKEYCOPY_CLEARSELECTION, MODEKEYCOPY_COPYPIPE, MODEKEYCOPY_COPYLINE, MODEKEYCOPY_COPYENDOFLINE, MODEKEYCOPY_COPYSELECTION, MODEKEYCOPY_DOWN, MODEKEYCOPY_ENDOFLINE, MODEKEYCOPY_GOTOLINE, MODEKEYCOPY_HALFPAGEDOWN, MODEKEYCOPY_HALFPAGEUP, MODEKEYCOPY_HISTORYBOTTOM, MODEKEYCOPY_HISTORYTOP, MODEKEYCOPY_JUMP, MODEKEYCOPY_JUMPAGAIN, MODEKEYCOPY_JUMPREVERSE, MODEKEYCOPY_JUMPBACK, MODEKEYCOPY_JUMPTO, MODEKEYCOPY_JUMPTOBACK, MODEKEYCOPY_LEFT, MODEKEYCOPY_MIDDLELINE, MODEKEYCOPY_NEXTPAGE, MODEKEYCOPY_NEXTSPACE, MODEKEYCOPY_NEXTSPACEEND, MODEKEYCOPY_NEXTWORD, MODEKEYCOPY_NEXTWORDEND, MODEKEYCOPY_OTHEREND, MODEKEYCOPY_PREVIOUSPAGE, MODEKEYCOPY_PREVIOUSSPACE, MODEKEYCOPY_PREVIOUSWORD, MODEKEYCOPY_RECTANGLETOGGLE, MODEKEYCOPY_RIGHT, MODEKEYCOPY_SCROLLDOWN, MODEKEYCOPY_SCROLLUP, MODEKEYCOPY_SEARCHAGAIN, MODEKEYCOPY_SEARCHDOWN, MODEKEYCOPY_SEARCHREVERSE, MODEKEYCOPY_SEARCHUP, MODEKEYCOPY_SELECTLINE, MODEKEYCOPY_STARTNUMBERPREFIX, MODEKEYCOPY_STARTOFLINE, MODEKEYCOPY_STARTSELECTION, MODEKEYCOPY_TOPLINE, MODEKEYCOPY_UP, };
Modes
#define MODE_CURSOR 0x1 #define MODE_INSERT 0x2 #define MODE_KCURSOR 0x4 #define MODE_KKEYPAD 0x8 /* set = application, clear = number */ #define MODE_WRAP 0x10 /* whether lines wrap */ #define MODE_MOUSE_STANDARD 0x20 #define MODE_MOUSE_BUTTON 0x40 #define MODE_MOUSE_ANY 0x80 #define MODE_MOUSE_UTF8 0x100 #define MODE_MOUSE_SGR 0x200 #define MODE_BRACKETPASTE 0x400 #define MODE_FOCUSON 0x800 #define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ANY)
Grid attributes
#define GRID_ATTR_BRIGHT 0x1 #define GRID_ATTR_DIM 0x2 #define GRID_ATTR_UNDERSCORE 0x4 #define GRID_ATTR_BLINK 0x8 #define GRID_ATTR_REVERSE 0x10 #define GRID_ATTR_HIDDEN 0x20 #define GRID_ATTR_ITALICS 0x40 #define GRID_ATTR_CHARSET 0x80 /* alternative character set */
Layout direction
enum layout_type { LAYOUT_LEFTRIGHT, LAYOUT_TOPBOTTOM, LAYOUT_WINDOWPANE };
Mouse
/* Mouse button masks. */ #define MOUSE_MASK_BUTTONS 3 #define MOUSE_MASK_SHIFT 4 #define MOUSE_MASK_META 8 #define MOUSE_MASK_CTRL 16 #define MOUSE_MASK_DRAG 32 #define MOUSE_MASK_WHEEL 64 /* Mouse wheel states. */ #define MOUSE_WHEEL_UP 0 #define MOUSE_WHEEL_DOWN 1 /* Mouse event bits. */ #define MOUSE_EVENT_DOWN 0x1 #define MOUSE_EVENT_DRAG 0x2 #define MOUSE_EVENT_UP 0x4 #define MOUSE_EVENT_CLICK 0x8 #define MOUSE_EVENT_WHEEL 0x10 /* Mouse flag bits. */ #define MOUSE_RESIZE_PANE 0x1
Option table entries
/* * Option table entries. The option table is the user-visible part of the * option, as opposed to the internal options (struct option) which are just * number or string. */ enum options_table_type { OPTIONS_TABLE_STRING, OPTIONS_TABLE_NUMBER, OPTIONS_TABLE_KEY, OPTIONS_TABLE_COLOUR, OPTIONS_TABLE_ATTRIBUTES, OPTIONS_TABLE_FLAG, OPTIONS_TABLE_CHOICE, OPTIONS_TABLE_STYLE };
Common command usages
/* Common command usages. */ #define CMD_TARGET_PANE_USAGE "[-t target-pane]" #define CMD_TARGET_WINDOW_USAGE "[-t target-window]" #define CMD_TARGET_SESSION_USAGE "[-t target-session]" #define CMD_TARGET_CLIENT_USAGE "[-t target-client]" #define CMD_SRCDST_PANE_USAGE "[-s src-pane] [-t dst-pane]" #define CMD_SRCDST_WINDOW_USAGE "[-s src-window] [-t dst-window]" #define CMD_SRCDST_SESSION_USAGE "[-s src-session] [-t dst-session]" #define CMD_SRCDST_CLIENT_USAGE "[-s src-client] [-t dst-client]" #define CMD_BUFFER_USAGE "[-b buffer-index]"
colour.c
Colour to string conversion functions. Bit 8 of the colour means it is one of the 256 colour palette.
/* An RGB colour. */ struct colour_rgb { u_char r; u_char g; u_char b; }; /* 256 colour RGB table, generated on first use. */ struct colour_rgb *colour_rgb_256; void colour_rgb_generate256(void); u_int colour_rgb_distance(struct colour_rgb *, struct colour_rgb *); int colour_rgb_find(struct colour_rgb *);
Generate 256 colour RGB table.
void colour_rgb_generate256(void) { struct colour_rgb *rgb; u_int i, r, g, b; /* * Allocate the table. The first 16 colours are often changed by users * and terminals so don't include them. */ colour_rgb_256 = xcalloc(240, sizeof *colour_rgb_256); /* Add the colours first. */ r = g = b = 0; for (i = 240; i > 24; i--) { rgb = &colour_rgb_256[240 - i]; if (r != 0) rgb->r = (r * 40) + 55; if (g != 0) rgb->g = (g * 40) + 55; if (b != 0) rgb->b = (b * 40) + 55; b++; if (b > 5) { b = 0; g++; } if (g > 5) { g = 0; r++; } } /* Then add the greys. */ for (i = 24; i > 0; i--) { rgb = &colour_rgb_256[240 - i]; rgb->r = 8 + (24 - i) * 10; rgb->g = 8 + (24 - i) * 10; rgb->b = 8 + (24 - i) * 10; } }
Get colour RGB distance.
u_int colour_rgb_distance(struct colour_rgb *rgb1, struct colour_rgb *rgb2) { int r, g, b; r = rgb1->r - rgb2->r; g = rgb1->g - rgb2->g; b = rgb1->b - rgb2->b; return (r * r + g * g + b * b); }
Work out the nearest colour from the 256 colour set.
int colour_rgb_find(struct colour_rgb *rgb) { u_int distance, lowest, colour, i; if (colour_rgb_256 == NULL) colour_rgb_generate256(); colour = 16; lowest = UINT_MAX; for (i = 0; i < 240; i++) { distance = colour_rgb_distance(&colour_rgb_256[i], rgb); if (distance < lowest) { lowest = distance; colour = 16 + i; } } return (colour); }
Convert colour to a string.
const char * colour_tostring(int c) { static char s[32]; if (c & 0x100) { xsnprintf(s, sizeof s, "colour%u", c & ~0x100); return (s); } switch (c) { case 0: return ("black"); case 1: return ("red"); case 2: return ("green"); case 3: return ("yellow"); case 4: return ("blue"); case 5: return ("magenta"); case 6: return ("cyan"); case 7: return ("white"); case 8: return ("default"); case 90: return ("brightblack"); case 91: return ("brightred"); case 92: return ("brightgreen"); case 93: return ("brightyellow"); case 94: return ("brightblue"); case 95: return ("brightmagenta"); case 96: return ("brightcyan"); case 97: return ("brightwhite"); } return (NULL); }
Convert colour from string.
int colour_fromstring(const char *s) { const char *errstr; const char *cp; struct colour_rgb rgb; int n; if (*s == '#' && strlen(s) == 7) { for (cp = s + 1; isxdigit((u_char) *cp); cp++) ; if (*cp != '\0') return (-1); n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &rgb.r, &rgb.g, &rgb.b); if (n != 3) return (-1); return (colour_rgb_find(&rgb) | 0x100); } if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) { n = strtonum(s + (sizeof "colour") - 1, 0, 255, &errstr); if (errstr != NULL) return (-1); return (n | 0x100); } if (strcasecmp(s, "black") == 0 || (s[0] == '0' && s[1] == '\0')) return (0); if (strcasecmp(s, "red") == 0 || (s[0] == '1' && s[1] == '\0')) return (1); if (strcasecmp(s, "green") == 0 || (s[0] == '2' && s[1] == '\0')) return (2); if (strcasecmp(s, "yellow") == 0 || (s[0] == '3' && s[1] == '\0')) return (3); if (strcasecmp(s, "blue") == 0 || (s[0] == '4' && s[1] == '\0')) return (4); if (strcasecmp(s, "magenta") == 0 || (s[0] == '5' && s[1] == '\0')) return (5); if (strcasecmp(s, "cyan") == 0 || (s[0] == '6' && s[1] == '\0')) return (6); if (strcasecmp(s, "white") == 0 || (s[0] == '7' && s[1] == '\0')) return (7); if (strcasecmp(s, "default") == 0 || (s[0] == '8' && s[1] == '\0')) return (8); if (strcasecmp(s, "brightblack") == 0 || (s[0] == '9' && s[1] == '0' && s[1] == '\0')) return (90); if (strcasecmp(s, "brightred") == 0 || (s[0] == '9' && s[1] == '1' && s[1] == '\0')) return (91); if (strcasecmp(s, "brightgreen") == 0 || (s[0] == '9' && s[1] == '2' && s[1] == '\0')) return (92); if (strcasecmp(s, "brightyellow") == 0 || (s[0] == '9' && s[1] == '3' && s[1] == '\0')) return (93); if (strcasecmp(s, "brightblue") == 0 || (s[0] == '9' && s[1] == '4' && s[1] == '\0')) return (94); if (strcasecmp(s, "brightmagenta") == 0 || (s[0] == '9' && s[1] == '5' && s[1] == '\0')) return (95); if (strcasecmp(s, "brightcyan") == 0 || (s[0] == '9' && s[1] == '6' && s[1] == '\0')) return (96); if (strcasecmp(s, "brightwhite") == 0 || (s[0] == '9' && s[1] == '7' && s[1] == '\0')) return (97); return (-1); }
Convert 256 colour palette to 16.
u_char colour_256to16(u_char c) { static const u_char table[256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 4, 4, 4, 12, 12, 2, 6, 4, 4, 12, 12, 2, 2, 6, 4, 12, 12, 2, 2, 2, 6, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14, 1, 5, 4, 4, 12, 12, 3, 8, 4, 4, 12, 12, 2, 2, 6, 4, 12, 12, 2, 2, 2, 6, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14, 1, 1, 5, 4, 12, 12, 1, 1, 5, 4, 12, 12, 3, 3, 8, 4, 12, 12, 2, 2, 2, 6, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14, 1, 1, 1, 5, 12, 12, 1, 1, 1, 5, 12, 12, 1, 1, 1, 5, 12, 12, 3, 3, 3, 7, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14, 9, 9, 9, 9, 13, 12, 9, 9, 9, 9, 13, 12, 9, 9, 9, 9, 13, 12, 9, 9, 9, 9, 13, 12, 11, 11, 11, 11, 7, 12, 10, 10, 10, 10, 10, 14, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 13, 11, 11, 11, 11, 11, 15, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15 }; return (table[c]); }More Reading
- TMUX FAQ - Trunk
- TMUX Examples
- https://wiki.archlinux.org/index.php/Tmux
- http://mutelight.org/articles/practical-tmux
- Terminal ZEN
JWR
tmux.conf examples
URXVT
« Caching WordPress with Batcache and MemcacheApache Logging for Remote Addresses using X-Forwarded-For »
Comments