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

Reply via email to