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 A. Query & control interface
15 Currently, screen provides a way to control a running session through the -X
16 command switch, which sends the specified command through the sever socket.
17 It's quite useful and can already do automation to some degree, (e.g. [1]).
18 However, the problem is that, there is no way to get enough feedback to make
19 decision in your script in such a scheme. The first job is to provide an
20 interface for scripts to query internal status of Screen. The second job is to
21 provide an interface to control Screen, with reasonable feedback.
25 When the internal status of Screen changed, we say that an event happened.
26 Events are also interesting to scripts, but are not covered by the query
27 interface. A hook / callback system is needed to notify scripts about
28 interested events. With the callback that triggers before an event, the script
29 should be able to stop the event from happening.
31 C. Asynchronous scripting
33 So far, with the described scripting support, we can write small functions
34 that provide enhanced functionality to a screen command, or write event
35 handler that handles interested events. But we are restricted to finish our
36 work quickly. The problem is that, Screen itself is a single threaded
37 application, utilizing asynchronous I/O to provide services to all windows
38 running inside. So you simply can not do time-consuming work in any of the
39 processing path, including the scripts.
41 Sometimes we may need to wait for something in a script, such as emulating
42 Expect in a Screen script [2]. The core of this use case is to wait for an
43 output pattern and react upon it. One possible way is to provide an event
44 callback for it. But it's not a pleasant way to do a series of interaction.
45 A natural solution is to make the script able to run asynchronously to Screen
48 [1] http://github.com/rblackwe/yapc--na-2007--making-an-ajax-gui-for-gnu-screen
49 [2] http://lists.gnu.org/archive/html/screen-users/2009-05/msg00006.html
51 II. The Screen interface
53 Screen needs to provide a user interface to source and run scripts.
55 script source [-async|-a] [-binding|-b <binding>] script.
57 This command sources the specified script. This command can be used several
58 times to source multiple scripts. Use the -async switch if the
59 script is supposed to run asynchronously , e.g. it needs to wait for
60 external events. Asynchronous scripts running mode needs to acquire a
61 lock before playing on Screen itself. As a result, it pays more overhead
62 than synch ones. Moreover, asynchronous scripts may be isolated from other
63 scripts and may not share any information with them. In other words, normal
64 scripts may share the same context. (Note: the isolation between scripts may
65 be implementation dependent. Which is more desirable?)
67 script call func arg1 arg2 ...
69 Call functions defined by scripts. If the same function are defined in
70 multiple scripting context, the last one applies. Call to normal script
71 returns synchronously. And call to asynchronous one will return immediately.
73 Special invoke interface, such as those embedded in caption/hstatus format
76 III. The scripting interface
78 There are several kinds of objects that may be interested to scripts.
82 Stands for a user interface.
91 description: The tty that this attach runs on.
96 description: The TERM env of that tty.
101 description: The fore window.
106 description: List of windows other than the fore.
111 description: As the name suggests
116 description: As the name suggests
121 description: The owner of this display.
126 description: Active layout on this display.
131 description: Set the idle timeout for this display, and actives the idle
132 event. It differs from the idle command, which uses a global
133 value for all attached displays.
140 get_canvases: Get a list of canvases on this display.
141 top_canvas: Get the top (or top-left) canvas on the display.
142 bottom_canvas: Get the bottom canvas on the display.
149 Triggerred whenever the idle timeout is reached. The handler will be
150 called with a reference to the idling display. If the handler returns
151 non-zero, the internal idle processing will be overriden. Please note that the
152 The idle timeout is not reseted on such a situation, remember to setup
153 idle timout in the handler if multiple activation is needed..
157 Stands for the sub-terminal(PTY, telnet etc) that processes runs on.
166 description: The title of the window.
171 description: The index in the window slots. Assigning new value to the number
172 changes the position of this window in the window list. If the
173 new window is occupied by some other window, they are changed by
179 description: The initial directory of the first
180 application (typically the shell) in that window.
185 description: the associated terminal device for that window.
190 description: the pid of of the slave end of the pty.
195 description: The window group we belongs to. (*This seems in-active?*)
200 description: The bell status of the window.
206 int get_monitor_status(bool activity);
207 Returns the status of the specified monitor type. Either activity or silence.
208 When the silence monitor is active, the threshold is returned.
210 void set_monitor_status(bool activity, int status);
211 Set the status of activity/silence monitor. The number of status for the
212 silence monitor is the seconds of threshold.
214 void stuff(string buf);
215 put the string into the input buffer.
218 Show the window in current focused canvas.
220 int waitfor(string pattern);
221 Waiting for a specified output pattern. The pattern is limited to plain text.
222 NOTICE: This is an asynchronous method call and can only be called in
225 hook([obj], event, handler, [priv])
226 See the description in Screen object.
234 triggered when the silence monitor got fired.
236 on_focus (display, window)
237 Triggered when the window gets input focus on a display.
238 Differs from the global event forechange, it's associated with a specific
241 on_leave (display, window)
242 Triggered after the window lost input focus on a display.
243 Differs from the global event forechange, it's associated with a specific
246 on_show (display, window)
247 Triggered after the first view of this window show up on a display.
248 Differs from on_focus when there are many regions on a display.
250 on_hide (display, window)
251 Triggered after the last view of this window disappeared from a display.
252 Differs from on_leave when there are many regions on a display.
266 description: The login name.
271 description: The index in the ACL bit fields.
277 description: The escape character
282 description: The access for the window created by this user to other users.
283 The result will be in a form of 'rwx'.
299 Get input focus for this canvas.
302 Show window 'win' on this canvas.
306 This is a pseudo object standing for the whole screen object. All other
307 objects can be obtained starting from this one.
317 hook([obj], event, handler, [priv])
318 or obj:hook(event, handler,[priv])
320 listen to the event notification. The event is associated with the specified
321 obj. If the obj is omitted, the event is a global event. An optional privilege
322 can be specified through the priv parameter. The privilege determines the
323 position of this handler in the chain. A smaller value has higher privilege.
325 This method returns a ticket (or handle) of the registration. This is used to
326 unregister the notification, using the syntax: ticket:unhook().
328 input(prompt, callback, [prefill])
329 get input from user asynchronously with a callback.
330 This call returns immediately, with a input line poped up. The input prompt
331 is set to the first parameter and the buffer can be pre-filled with the third
332 parameter. Once the input is done with an enter, the callback function is
333 called with the inputed string to enable further process.
335 The input happens at the active canvas of the current display. If there is no
336 current display input line appears in all canvas that shows the current
343 detached (display, is_remote)
345 For detach-events, it's not enough to just listen to 'cmdexecuted'
346 command, since this command is not used for remote detaches. So
347 scripts looking to do something on a detach event need to hook to
348 this event, instead of hooking to 'cmdexecuted' event and looking
349 for 'detach' command.
355 Bindings are in fact script interpretors. We can have several different
356 language bindings at the same time, with each registered at the compiling time
357 and loaded (initialized) dynamically at runtime. It's an bridge between
358 scripts and screen itself.