bc9625aba1716ac45be5a619cacaba55746dd8ca
[screen-lua.git] / src / drafts / scripting
blobbc9625aba1716ac45be5a619cacaba55746dd8ca
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 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.
23 B. Event hooking
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
46 itself.
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
74 string.
76 III. The scripting interface
78 There are several kinds of objects that may be interested to scripts.
80 A. Display
82 Stands for a user interface.
84 ----------
85 Properties:
86 ----------
88 tty:
89  mode: read only.
90  type: String.
91  description: The tty that this attach runs on.
93 term:
94  mode: read only. 
95  type: String. 
96  description: The TERM env of that tty.
98 fore:
99  mode: read only. 
100  type: Window. 
101  description: The fore window.
103 other:
104  mode: read only. 
105  type: Window. 
106  description: List of windows other than the fore.
108 width:
109  mode: read only. 
110  type: Int. 
111  description: As the name suggests
113 height:
114  mode: read only. 
115  type: Int. 
116  description:  As the name suggests
118 user:
119  mode: read only. 
120  type: User. 
121  description: The owner of this display.
123 layout:
124  mode: read only. 
125  type: Layout. 
126  description: Active layout on this display.
128 idle_timeout:
129  mode: write only.
130  type: Int.
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.
136 ----------
137 Methods:
138 ----------
140 get_canvases: Get a list of canvases on this display.
142 top_canvas: Get the top (or top-left) canvas on the display.
144 bottom_canvas: Get the bottom canvas on the display.
146 ----------
147 Events:
148 ----------
150 on_idle: (Display)
151         Triggerred whenever the idle timeout is reached. The handler will be
152         called with a reference to the idling display. If the handler returns
153         non-zero, the internal idle processing will be overriden. Please note
154         that the The idle timeout is not reseted on such a situation, remember to
155         setup idle timout in the handler if multiple activation is needed.. 
157 B. Window
159 Stands for the sub-terminal(PTY, telnet etc) that processes runs on.
161 ----------
162 Properties:
163 ----------
165 title:
166  mode: read write
167  type: String.
168  description: The title of the window.
170 number:
171  mode: read write
172  type: int.
173  description: The index in the window slots. Assigning new value to the number
174               changes the position of this window in the window list. If the
175               new window is occupied by some other window, they are changed by
176               position.
178 dir:
179  mode: read only
180  type: String.
181  description: The initial directory of the first 
182               application (typically the shell) in that window.
184 tty:
185  mode: read only
186  type: String
187  description: the associated terminal device for that window.
189 pid:
190  mode: read only
191  type: int
192  description: the pid of of the slave end of the pty.
194 group:
195  mode: read only
196  type: Window
197  description: The window group we belongs to. (*This seems in-active?*)
199 bell:
200  mode: read only
201  type: int
202  description: The bell status of the window.
204 ----------
205 Methods:
206 ----------
208 int get_monitor_status(bool activity);
209  Returns the status of the specified monitor type. Either activity or silence.
210  When the silence monitor is active, the threshold is returned.
212 void set_monitor_status(bool activity, int status);
213  Set the status of activity/silence monitor. The number of status for the
214  silence monitor is the seconds of threshold.
216 void stuff(string buf);
217  put the string into the input buffer.
219 void activate();
220  Show the window in current focused canvas.
222 int waitfor(string pattern);
223  Waiting for a specified output pattern. The pattern is limited to plain text. 
224  NOTICE: This is an asynchronous method call and can only be called in
225  asynchronous mode.
227 hook([obj], event, handler, [priv])
228  See the description in Screen object.
230 ----------
231 Events
232 ----------
234 on_activity (display, window)
235   triggered when the activity monitor got fired. This will be triggered for
236   each display on which the window is hidden. Return non-zero in the handler
237   will override the default activity message.
238   
239 onsilent (display, window)
240   triggered when the silence monitor got fired. This will be triggered for
241   each display on which the window is hidden. Return non-zero in the handler
242   will override the default silent message.
244 on_focus (display, window)
245  Triggered when the window gets input focus on a display.
246  Differs from the global event forechange, it's associated with a specific
247  window.
249 on_leave (display, window)
250  Triggered after the window lost input focus on a display.
251  Differs from the global event forechange, it's associated with a specific
252  window.
254 on_show (display, window)
255  Triggered after the first view of this window show up on a display.
256  Differs from on_focus when there are many regions on a display.
258 on_hide (display, window)
259  Triggered after the last view of this window disappeared from a display.
260  Differs from on_leave when there are many regions on a display.
262 on_close (window)
263  Triggered before the window close. Can be used to free any references to
264  the window.
266 can_resize
267 on_resize
269 C. User
271 --------
272 Property:
273 --------
275 name:
276  mode: read only
277  type: String.
278  description: The login name.
280 uid:
281  mode: read only
282  type: int
283  description: The index in the ACL bit fields.
285 esc:
286 metaesc:
287  mode: read only
288  type: int
289  description: The escape character
291 umask:
292  mode: read only
293  type: String.
294  description: The access for the window created by this user to other users.
295               The result will be in a form of 'rwx'.
297 D. Display
300 ----------
301 Methods:
302 ----------
304 E. Canvas
306 ----------
307 Methods:
308 ----------
310 select()
311   Get input focus for this canvas.
313 showwin(win)
314   Show window 'win' on this canvas.
316 F. Screen
318  This is a pseudo object standing for the whole screen object. All other
319  objects can be obtained starting from this one.
321 --------
322 Methods:
323 --------
324 windows
325 displays
326 command
327 windowbyname
329 hook([obj], event, handler, [priv])
330 or obj:hook(event, handler,[priv])
332  listen to the event notification. The event is associated with the specified
333  obj. If the obj is omitted, the event is a global event. An optional privilege
334  can be specified through the priv parameter. The privilege determines the
335  position of this handler in the chain. A smaller value has higher privilege.
337  This method returns a ticket (or handle) of the registration. This is used to
338  unregister the notification, using the syntax: ticket:unhook().
340 input(prompt, callback, [prefill])
341  get input from user asynchronously with a callback.
342  This call returns immediately, with a input line poped up. The input prompt
343  is set to the first parameter and the buffer can be pre-filled with the third
344  parameter. Once the input is done with an enter, the callback function is
345  called with the inputed string to enable further process.
347  The input happens at the active canvas of the current display. If there is no
348  current display input line appears in all canvas that shows the current
349  layer. FIXME!!!
351 --------
352 Events:
353 --------
354 cmdexecuted
355 detached (display, is_remote)
357 For detach-events, it's not enough to just listen to 'cmdexecuted'
358 command, since this command is not used for remote detaches. So
359 scripts looking to do something on a detach event need to hook to
360 this event, instead of hooking to 'cmdexecuted' event and looking
361 for 'detach' command.
363 ===================
364 The Implementation
365 ===================
367 Bindings are in fact script interpretors. We can have several different
368 language bindings at the same time, with each registered at the compiling time
369 and loaded (initialized) dynamically at runtime. It's an bridge between
370 scripts and screen itself.
372 ---------------
373 Binding related.
374 ---------------
376 ---------------
377 Binding independent
378 ---------------