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.

penguin-tmux

Table of Contents

  1. Introduction
    1. tmux usage
    2. tmux.conf
    3. Tmux Command Aliases
    4. Default Templates
    5. tmux main() processing order:
    6. tmux.c
      1. makesocketpath
      2. shell_exec
    7. tmux.h
      1. notify.c
      2. options-table.c
      3. Default Templates
      4. key codes
      5. Termcap codes
      6. Message codes
      7. Mode key commands
      8. Modes
      9. Grid attributes
      10. Layout direction
      11. Mouse
      12. Option table entries
      13. Common command usages
    8. colour.c
      1. Generate 256 colour RGB table.
      2. Get colour RGB distance.
      3. Work out the nearest colour from the 256 colour set.
      4. Convert colour to a string.
      5. Convert colour from string.
      6. Convert 256 colour palette to 16.
    9. More Reading
      1. JWR
      2. tmux.conf examples
      3. URXVT

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:
  • \2: \1
  • ,g'|grep -v NULL|sort -g|cut -d':' -f2-
    • 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;
    
    1. Parse cmd line options while ((opt = getopt(argc, argv, "2c:Cdf:lL:qS:uUVv")) != -1)
    2. Setup global environment for (var = environ; *var != NULL; var++) environ_put(&global_environ, *var);
    3. Set PWD if (getcwd(tmp, sizeof tmp) != NULL) environ_set(&global_environ, "PWD", tmp);
    4. Populate Server Options options_table_populate_tree(server_options_table, &global_options)
    5. Populate Session Options options_table_populate_tree(session_options_table, &global_s_options);
    6. Set default-shell in global session option to the current shell options_set_string(&global_s_options, "default-shell", "%s", getshell());
    7. Populate Window Options options_table_populate_tree(window_options_table, &global_w_options);
    8. 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);
      }
    9. 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);
      }
    10. Locate the configuration file.
    11. Get path from environment
      s = getenv("TMUX");
      if (s != NULL && sscanf(s, "%255[^,],%lld,%d", in, &pid, &session) == 3) environ_path = xstrdup(in);
    12. Figure out the socket path and use.
    13. Set process title. #ifdef HAVE_SETPROCTITLE setproctitle("%s (%s)", __progname, socket_path);
    14. 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.

    1. TMUX_TMPDIR
    2. 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

    1. TMUX FAQ - Trunk
    2. TMUX Examples
    3. https://wiki.archlinux.org/index.php/Tmux
    4. http://mutelight.org/articles/practical-tmux
    5. Terminal ZEN

    JWR

    1. Copy and Paste
    2. tmux multiplexer
    3. tmux sessions

    tmux.conf examples

    1. jasonwryan tmux.conf

    URXVT

    1. http://linux.die.net/man/7/urxvt

    TMUX - AskApache

    Charles Torvalds
    19 Jul 2016

    linux.bash, Screen, shell, tmux

    • Site Map WireShark GNU Non-GNU Tor Project cURL TLDP - Documentation
    • Htaccess Files Hacking Htaccess Javascript Linux Optimization PHP Security Shell Scripting WordPress
    • Base64 Image Converter Raw HTTP Header Debugger Graphical ASCII Text Generator Mac Address Vendor Lookup Who Am I – Your IP Information Request Method Security Scanner .htpasswd file Generator Compress CSS DNS Tracer
    Copyright © 2025 AskApache
    • Site Map
    • Htaccess Files
    • Hacking
    • Htaccess
    • Javascript
    • Linux
    • Optimization
    • PHP
    • Security
    • Shell Scripting
    • WordPress
    • Base64 Image Converter
    • Raw HTTP Header Debugger
    • Graphical ASCII Text Generator
    • Mac Address Vendor Lookup
    • Who Am I – Your IP Information
    • Request Method Security Scanner
    • .htpasswd file Generator
    • Compress CSS
    • DNS Tracer
    Exit mobile version