This document describes in text the changes made and their motivations. At the end, I make recommendations on how to split this up into multiple smaller commits.
New Files -------------- There are four new files: 1. control.c Handles basic I/O with control clients, including: - Queuing spontaneous message notifications - Sending spontaneous messages Spontaneous messages are tmux-originated messages that tell the client that something changed: the number of sessions changed, the number of windows changed, a window's layout changed, a pty produced output, etc. Because notifications may arrive while a command is being executed, notifications are queued and then processed when no command is running. - Managing the key-value store The key-value store is a client-owned dictionary. It's used to remember window coordinates and which tmux windows appear as tabs in the same native window, for example. 2. cmd-control.c The one command used by control clients for all nonstandard functions. - control -e -t pane-id Prints a list of key-value pairs describing the internal state of tmux's vt100 emulator so that the client can sync up. - control -h -t pane-id -l num-lines [-a] Outputs up to "num-lines" lines of history including the current screen contents. If -a is given then the alternate screen is output. See below for a description of the encoding of history output. - control -k key Returns the value associated with "key" in the key-value store, or empty string. - control -s width,height Sets the size of the client. Windows cannot exceed this size. - control -s ready Marks the client as ready to receive spontaneous messages. - control -s set key=value Set the key "key" equal to the value "value" in the key-value store. 3. cmd-move-pane.c Like join-pane but doesn't mandate that the panes be in separate windows. Necessary to support dragging and dropping of panes. 4. dstring.c Dynamic-length strings. This simplifies various other bits of code. History ---------- The control -h command outputs a pane's history. The goals here were compactness, 7-bit cleanliness, and simplicity. The encoding is: HISTORY ::= CONTEXT REPEATED_LINES REPEATED_LINES ::= HISTORY_LINE "\n" | HISTORY_LINE "\n" REPEATED_LINES HISTORY_LINE ::= CELLS | CELLS CONTEXT HISTORY_LINE CONTEXT ::= ":" HEX "," HEX "," HEX "," HEX CELLS ::= CELLVALUE | CELLVALUE CELLS CELLVALUE ::= HEX | "[" REPEATED_HEX "]" REPEATED_HEX ::= HEX | HEX REPEATED_HEX HEX := [0-9A-F]{2} The CONTEXT's values are cell attributes, a subset of cell flags (FG256, BG256, and PADDING), foreground color, and background color. The idea is to output the cell's attributes (color, etc.) once and then as many character values as possible. Character values are either ASCII, held in one byte represented as a 2-digit hex value, or a UTF-8 char which is a string of 2-digit hex values inside square brackets. Changes to Existing Files ------------------------------------- client.c -------- Ensures that a TTY is attached and turns off echo. If echo can't be disabled then the protocol won't work because the client's echo will be intermingled with server output. Sends MSG_IDENTIFY after STDOUT and STDERR so that it can send the escape code. Outputs %exit instead of the standard exit messages for control clients. When a control client quits not by issuing the detach command (e.g., the server dies or the last pty dies), sleep for a bit and read all available input. The client may have sent some not-yet-received commands before getting the %exit message, and we don't want those to go to the shell--who knows what they would do!--so read and discard all available input for a few seconds. The side effect of this is that a short delay is introduced to try to wait for the input to arrive, but it doesn't happen in the common case of detaching cleanly. I'd prefer for tmux to wait for acknowledgment of %exit, but because the server may or may not be dead, it's very hard to do this cleanly (it might still be reading the file descriptor). cmd-attach-session --------------------------- Performs handshake and sends session-change notifications. Various tweaks to terminal usage to avoid stepping on control clients. cmd-break-pane ---------------------- Change assignments to window->name to window_set_name(). cmd-join-pane -------------------- Gains the -b flag to join a pane in before the target (left of or above). Adds various notifications. Refactored, gaining an argument that controls whether the different-window requirement is in force--this will serve as the meat of the new move-pane command. cmd-link-window ----------------------- Don't allow a window to be linked twice to the same session with the link-window command. I think this is undesirable, but I'm not totally sure? It certainly makes it harder to write a sane control mode client. cmd-list-windows ------------------------ Takes a -I argument specifying which window to list by window ID. Control clients use this command frequently, and if the user has a huge number of windows, it's much faster this way. cmd-list ----------- For control clients, wrap output in %begin…%end to make it parseable. Spontaneous messages are disabled while a command is running. They are queued and output after the command finishes. cmd-new-session ------------------------ Add handshake, remove check for tty (which is done in the client). cmd-new-window ------------------------ Add some notifications and a -I option which outputs a window ID. cmd-rename-session ----------------------------- Add a notification. cmd-rename-window ----------------------------- Use window_set_name cmd-resize-pane ----------------------- For control clients, output session layouts. cmd-send-keys --------------------- Add a -h option, which expects 2-char hex values for keys. This avoids problems with sending newlines or dealing with encoding issues on the wire. cmd-split-window ----------------------- Add notifications, pass extra arg to layout_split_pane. cmd.c -------- Support looking up windows and window panes by ID (see IDs below). format.c ----------- Gains window_id and window_layout_ex formats. window_layout_ex (a window layout including the window pane id) input.c --------- Keeps track of input received after leaving the ground state so that if a control client attaches in the middle of receiving an escape code, it can know what has been received but not reflected in any other state. Added a call to rebroadcast output received from a pty. layout-custom.c --------------------- Added layout that includes window pane ids and notifications. layout.c ------------- Added notifications and the ability for layout_split_pane() to insert before (left of or on top of) a pane rather than always right/below. names.c ---------- window_set_name refactor. resize.c ------------- Don't include status line in calculation of available space for control clients. Add notification. server-client.c ------------------- Avoid changing the tty for control clients. Set CLIENT_CONTROL flag on client when IDENTIFY_CONTROL message is recvd and don't set CLIENT_TERMINAL for control clients. server-fn.c -------------- Don't do server_lock_client() for control clients. It's not supported. Add notifications. server-window.c ---------------------- Don't ring the bell for control clients (let the client handle it). server.c ---------- Initialize control module session.c ------------ assign session IDs. Add notifications. tmux.c --------- Add -C argument. tty.c ----- Move setting tty size into tty_set_size() window.c ----------- Add window IDs. Add window_set_name(). IDs ---- Windows had no race-free identifier. I defined window IDs as a monotonically increasing integer assigned at window creation time, and referenced with an @ sign. For instance "unlink window -t @1". Sessions had no unique identifier. Add a monotonically increasing session ID assigned at creation time. Window panes had no race-free identifier. I defined pane IDs as a monotonically increasing integer assigned at creation time, and referenced with a % sign. For instance "break-pane -t %1". Flags -------- The client flag CLIENT_TERMINAL will be false for control clients. Although they must have tty's as far as client.c is concerned, the server should never manipulate the tty. Recommendations --------------------------- Based on the dependency graph, these changes can be split into a few smaller patches. This is approximate, but with minor changes I think this can be split into 5 checkins. 1. Files with very limited dependencies. tty.c window.c names.c cmd-send-keys.c cmd-link-window.c control.c dstring.c 2. Files that depend only on flags & control.c resize.c server-client.c server-window.c 3. Files that depend only on window.c: cmd-break-pane.c cmd-rename-window.c cmd-list-windows.c 4. File that depend on control.c, flags, and window.c: cmd-list.c cmd-attach-session.c cmd-rename-session.c input.c server.c session.c cmd-control.c cmd-new-session.c server-fn.c cmd-new-window.c cmd-resize-pane.c layout-custom.c 5. Everything else cmd-move-pane.c cmd-join-pane.c cmd.c cmd-split-window.c layout.c format.c tmux.c ------------------------------------------------------------------------------ Try before you buy = See our experts in action! The most comprehensive online learning library for Microsoft developers is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3, Metro Style Apps, more. Free future releases when you subscribe now! http://p.sf.net/sfu/learndevnow-dev2 _______________________________________________ tmux-users mailing list tmux-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tmux-users