Fill in design document.
[screen-lua.git] / src / drafts / scripting
blobcfeeee14d4d2d602429c604ea47ffa738e3cdc19
1 ===================
2 The design
3 ===================
5 I. Key Factors
6 There are several aspects to deal with when adding scripting support to
7 Screen:
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.
28 B. Event hooking
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
51 itself.
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
79 string.
81 III. The scripting interface
83 There are several kinds of objects that may be interested to scripts.
85 ==========
86 A. Display
88 Stands for a user view that presented by an attacher.
90 ----------
91 Properties:
92 ----------
94 tty:
95  mode: read only.
96  type: String.
97  description: The tty that this attach runs on.
99 term:
100  mode: read only. 
101  type: String. 
102  description: The TERM env of that tty.
104 fore:
105  mode: read only. 
106  type: Window. 
107  description: The fore window.
109 other:
110  mode: read only. 
111  type: Window. 
112  description: List of windows other than the fore.
114 width:
115  mode: read only. 
116  type: Int. 
117  description: As the name suggests
119 height:
120  mode: read only. 
121  type: Int. 
122  description:  As the name suggests
124 user:
125  mode: read only. 
126  type: User. 
127  description: The owner of this display.
129 layout:
130  mode: read only. 
131  type: Layout. 
132  description: Active layout on this display.
134 idle_timeout:
135  mode: write only.
136  type: Int.
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.
141 ----------
142 Methods:
143 ----------
145 table get_canvases();
146  Returns a list/table of canvases on this display.
148 Canvas top_canvas();
149  Returns the top (or top-left) canvas on the display.
151 Canvas bottom_canvas();
152  Returns the bottom canvas on the display.
154 ----------
155 Events:
156 ----------
158 onidle: (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.. 
166 =========
167 B. Window
169 Stands for the sub-terminal(PTY, telnet etc) that processes runs on.
171 ----------
172 Properties:
173 ----------
175 title:
176  mode: read write
177  type: String.
178  description: The title of the window.
180 number:
181  mode: read write
182  type: int.
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
186               position.
188 dir:
189  mode: read only
190  type: String.
191  description: The initial directory of the first 
192               application (typically the shell) in that window.
194 tty:
195  mode: read only
196  type: String
197  description: the associated terminal device for that window.
199 pid:
200  mode: read only
201  type: int
202  description: the pid of of the slave end of the pty.
204 group:
205  mode: read only
206  type: Window
207  description: The window group we belongs to. (*This seems in-active?*)
209 bell:
210  mode: read only
211  type: int
212  description: The bell status of the window.
214 ----------
215 Methods:
216 ----------
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.
226 char ** get_lines();
227  Return the content on the window as an array of string. Each string represent
228  a single line.
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
238 void activate();
239  Show the window in current focused canvas.
241 int waitfor(string pattern);
242  NOT IMPLEMENTED YET
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
245  asynchronous mode.
247 hook([obj], event, handler, [priv])
248  See the description in Screen object.
250 ----------
251 Events
252 ----------
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.
258   
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
267  window.
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
272  window.
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.
282 onclose (window)
283  Triggered before the window close. Can be used to free any references to
284  the window.
286 onresize (window)
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.
294 =======
295 C. User
297 --------
298 Property:
299 --------
301 name:
302  mode: read only
303  type: String.
304  description: The login name.
306 uid:
307  mode: read only
308  type: int
309  description: The index in the ACL bit fields.
311 esc:
312 metaesc:
313  mode: read only
314  type: int
315  description: The escape character
317 umask:
318  mode: read only
319  type: String.
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.
324 =========
325 D. Canvas
327 --------
328 Property:
329 --------
331 next:
332  mode: read only
333  type: Canvas
334  description: The next canvas on display.
336 xoff:
337 yoff:
338  mode: read only
339  type: int
340  description: The x/y offset of canvas on the display.
342 xe/ye:
343  mode: read only
344  description: The bottom right coordinate of the canvas.
346 window:
347  mode: read write
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.
353 display:
354  mode: read only
355  description: The display that this canvas belongs to.
357 caption:
358  mode: write only
359  description: The caption string for this canvas. The string set to caption
360               can contain screen escapes and will be expended before show 
361               up on the display.
364 ----------
365 Methods:
366 ----------
368 select()
369   Get input focus for this canvas.
371 split(horizontal)
372   Split the canvas into two part. If the horizontal flag is not set, the split
373   is done in vertical.
375 =========
376 E. Layout
378  The layout of canvases on a display. Can be used to emulate the tab feature
379  of VIM.
381 ----------
382 Properties:
383 ----------
385 title
386  mode: read write
387  type: string
388  description: The title of a layout.
391 number 
392  mode: read write
393  type: int
394  description: The number of the layout in the layout list.
396 autosave
397  mode: read write
398  type: int
399  description: Specify whether the layout will be automatically updated on
400               switch.
402 --------
403 Methods:
404 --------
406 select();
407  Use this layout on current display. Does nothing whenever the current display
408  is NULL.
410 =========
411 F. Screen
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.
417 --------
418 Methods:
419 --------
420 Table windows();
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
423  same.
425 Table displays();
426  Returns a list/table of attached displays in screen.
428 Table layouts();
429  Returns a list/table of defined layouts.
431 command(string);
432  Invoke a screen command specified as a string.
434 Display display();
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
463  layer.
465 --------
466 Events:
467 --------
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.
483 onattach(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
488  that window.
490 processcaption(canvas)
491  Triggered whenever the caption for the canvas needs to be updated.
493 ===================
494 The Implementation
495 ===================
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.