6 There are several aspects to deal with when adding scripting support to
8 1. The set of information to expose.
9 2. The command interface to provide.
10 3. The hook on interesting events in Screen.
11 4. The ability to do run asynchronously to Screen itself.
13 [Note: asynchronous scripting support is not supported yet, due to the fact
14 that screen is highly thread-unsafe. One possible solution is to implement an
15 implicit locking through the asynchronous IO mechanism (similar to the one
16 used by attacher <=> back end) that is currently in use.]
18 A. Query & control interface
20 Currently, screen provides a way to control a running session through the -X
21 command switch, which sends the specified command through the sever socket.
22 It's quite useful and can already do automation to some degree, (e.g. [1]).
23 However, the problem is that, there is no way to get enough feedback to make
24 decision in your script in such a scheme. The first job is to provide an
25 interface for scripts to query internal status of Screen. The second job is to
26 provide an interface to control Screen, with reasonable feedback.
30 When the internal status of Screen changed, we say that an event happened.
31 Events are also interesting to scripts, but are not covered by the query
32 interface. A hook / callback system is needed to notify scripts about
33 interested events. With the callback that triggers before an event, the script
34 should be able to stop the event from happening.
36 C. Asynchronous scripting
38 So far, with the described scripting support, we can write small functions
39 that provide enhanced functionality to a screen command, or write event
40 handler that handles interested events. But we are restricted to finish our
41 work quickly. The problem is that, Screen itself is a single threaded
42 application, utilizing asynchronous I/O to provide services to all windows
43 running inside. So you simply can not do time-consuming work in any of the
44 processing path, including the scripts.
46 Sometimes we may need to wait for something in a script, such as emulating
47 Expect in a Screen script [2]. The core of this use case is to wait for an
48 output pattern and react upon it. One possible way is to provide an event
49 callback for it. But it's not a pleasant way to do a series of interaction.
50 A natural solution is to make the script able to run asynchronously to Screen
53 [1] http://github.com/rblackwe/yapc--na-2007--making-an-ajax-gui-for-gnu-screen
54 [2] http://lists.gnu.org/archive/html/screen-users/2009-05/msg00006.html
56 II. The Screen interface
58 Screen needs to provide a user interface to source and run scripts.
60 script source [-async|-a] [-binding|-b <binding>] script.
62 This command sources the specified script. This command can be used several
63 times to source multiple scripts. Use the -async switch if the
64 script is supposed to run asynchronously , e.g. it needs to wait for
65 external events. Asynchronous scripts running mode needs to acquire a
66 lock before playing on Screen itself. As a result, it pays more overhead
67 than synch ones. Moreover, asynchronous scripts may be isolated from other
68 scripts and may not share any information with them. In other words, normal
69 scripts may share the same context. (Note: the isolation between scripts may
70 be implementation dependent. Which is more desirable?)
72 script call func arg1 arg2 ...
74 Call functions defined by scripts. If the same function are defined in
75 multiple scripting context, the last one applies. Call to normal script
76 returns synchronously. And call to asynchronous one will return immediately.
78 Special invoke interface, such as those embedded in caption/hstatus format
81 III. The scripting interface
83 There are several kinds of objects that may be interested to scripts.
88 Stands for a user view that presented by an attacher.
97 description: The tty that this attach runs on.
102 description: The TERM env of that tty.
107 description: The fore window.
112 description: List of windows other than the fore.
117 description: As the name suggests
122 description: As the name suggests
127 description: The owner of this display.
132 description: Active layout on this display.
137 description: Set the idle timeout of the next activation for this display,
138 and actives the idle event. It differs from the idle command,
139 which uses a global value for all attached displays.
145 table get_canvases();
146 Returns a list/table of canvases on this display.
149 Returns the top (or top-left) canvas on the display.
151 Canvas bottom_canvas();
152 Returns the bottom canvas on the display.
159 Triggered whenever the idle timeout is reached. The handler will be
160 called with a reference to the idling display. If the handler returns
161 non-zero, the internal idle processing will be overridden. Please note
162 that the The idle timeout is not reseted on such a situation, remember to
163 setup idle timeout in the handler if multiple activation is needed..
169 Stands for the sub-terminal(PTY, telnet etc) that processes runs on.
178 description: The title of the window.
183 description: The index in the window slots. Assigning new value to the number
184 changes the position of this window in the window list. If the
185 new window is occupied by some other window, they are changed by
191 description: The initial directory of the first
192 application (typically the shell) in that window.
197 description: the associated terminal device for that window.
202 description: the pid of of the slave end of the pty.
207 description: The window group we belongs to. (*This seems in-active?*)
212 description: The bell status of the window.
218 int get_monitor_status(bool activity);
219 Returns the status of the specified monitor type. Either activity or silence.
220 When the silence monitor is active, the threshold is returned.
222 void set_monitor_status(bool activity, int status);
223 Set the status of activity/silence monitor. The number of status for the
224 silence monitor is the seconds of threshold.
227 Return the content on the window as an array of string. Each string represent
230 char ** get_history();
231 Return the history buffer of the window as an array of string. Each string
232 represent a single line.
234 void stuff(string buf);
235 put the string into the input buffer. This can be used to interactive with
236 the application within the window
239 Show the window in current focused canvas.
241 int waitfor(string pattern);
243 Waiting for a specified output pattern. The pattern is limited to plain text.
244 NOTICE: This is an asynchronous method call and can only be called in
247 hook([obj], event, handler, [priv])
248 See the description in Screen object.
254 onactivity (display, window)
255 triggered when the activity monitor got fired. This will be triggered for
256 each display on which the window is hidden. Return non-zero in the handler
257 will override the default activity message.
259 onsilent (display, window)
260 triggered when the silence monitor got fired. This will be triggered for
261 each display on which the window is hidden. Return non-zero in the handler
262 will override the default silent message.
264 onfocus (display, window)
265 Triggered when the window gets input focus on a display.
266 Differs from the global event forechange, it's associated with a specific
269 onleave (display, window)
270 Triggered after the window lost input focus on a display.
271 Differs from the global event forechange, it's associated with a specific
274 onshow (display, window)
275 Triggered after the first view of this window show up on a display.
276 Differs from on_focus when there are many regions on a display.
278 onhide (display, window)
279 Triggered after the last view of this window disappeared from a display.
280 Differs from on_leave when there are many regions on a display.
283 Triggered before the window close. Can be used to free any references to
287 Triggered after the window is resized.
289 onoutput (window, string)
290 Triggered when the window has new output. This output is not cooked to on
291 line basis. Please be careful when using this hook. The system speed can be
292 significantly slowed down due to ill use of this.
304 description: The login name.
309 description: The index in the ACL bit fields.
315 description: The escape character
320 description: The access for the window created by this user to other users.
321 The result will be in a form of 'rwx'.
322 NOTE: NOT IMPLEMENTED YET.
334 description: The next canvas on display.
340 description: The x/y offset of canvas on the display.
344 description: The bottom right coordinate of the canvas.
348 description: The window currently showing on the canvas.
349 Can be used to select a new window to show.
350 The new window can also be NULL, so that the
351 canvas shows nothing.
355 description: The display that this canvas belongs to.
359 description: The caption string for this canvas. The string set to caption
360 can contain screen escapes and will be expended before show
369 Get input focus for this canvas.
372 Split the canvas into two part. If the horizontal flag is not set, the split
378 The layout of canvases on a display. Can be used to emulate the tab feature
388 description: The title of a layout.
394 description: The number of the layout in the layout list.
399 description: Specify whether the layout will be automatically updated on
407 Use this layout on current display. Does nothing whenever the current display
413 This is a pseudo object standing for the whole screen object. All other
414 objects can be obtained starting from this one. Since this is not a real
415 object, there's no property for it.
421 Returns a list/table of windows in screen. The table/list is not necessary
422 indexed by the window number. But the order of the windows should keep the
426 Returns a list/table of attached displays in screen.
429 Returns a list/table of defined layouts.
432 Invoke a screen command specified as a string.
435 The display that currently has internal events happening. Can be null.
437 append_msg(string msg);
438 Show a message on the status/caption line.
440 schedule(int timeout, handler);
441 Schedule an handler to be triggered in 'timeout' seconds later.
443 hook([obj], event, handler, [priv]);
444 or obj:hook(event, handler,[priv])
446 listen to the event notification. The event is associated with the specified
447 obj. If the obj is omitted, the event is a global event. An optional privilege
448 can be specified through the priv parameter. The privilege determines the
449 position of this handler in the chain. A smaller value has higher privilege.
451 This method returns a ticket (or handle) of the registration. This is used to
452 unregister the notification, using the syntax: ticket:unhook().
454 input(prompt, callback, [prefill]);
455 get input from user asynchronously with a callback.
456 This call returns immediately, with a input line poped up. The input prompt
457 is set to the first parameter and the buffer can be pre-filled with the third
458 parameter. Once the input is done with an enter, the callback function is
459 called with the inputed string to enable further process.
461 The input happens at the active canvas of the current display. If there is no
462 current display input line appears in all canvas that shows the current
468 cmdexecuted(command, args)
469 An SCREEN command is executed with a list of arguments (args). This has
470 nothing to do with the shell command in user window.
472 detached (display, is_remote)
474 For detach-events, it's not enough to just listen to 'cmdexecuted'
475 command, since this command is not used for remote detaches. So
476 scripts looking to do something on a detach event need to hook to
477 this event, instead of hooking to 'cmdexecuted' event and looking
478 for 'detach' command.
480 forechanged(display, window)
481 Triggered when a new window has been set on the display.
484 Triggered after a new display is attached.
486 oncreatewindow(window)
487 Triggered after a new window is created. Can be used to hook other events on
490 processcaption(canvas)
491 Triggered whenever the caption for the canvas needs to be updated.
497 Bindings are in fact script interpretors. We can have several different
498 language bindings at the same time, with each registered at the compiling time
499 and loaded (initialized) dynamically at runtime. It's an bridge between
500 scripts and screen itself.