This simple script will first make sure that the BeIDE application (the Be Integrated Development Environment, available with the system development tools) is currently running on the system. The script will then ask the BeIDE for its scripting capabilities, display the program about box, pause one second, start talking to and retrieve the title of the third window (all indices start at zero), move this window to the upper-left corner of the screen and activate it, display the BeIDE preferences, and finally terminate.
A script can consist of any number of TELL blocks. A TELL block can be addressed only to an already running application. LAUNCH statements are needed when we don't know whether the application whom we want to talk to is currently running. Any number of commands, all addressed to the same remote application, can be given in a TELL block: this represents the desired action(s) to be performed by the target application. At the moment, a program in BeScript is mainly a way to control the behaviour of remote applications at a command-issue level. Support is planned for standard programming language features including control flow, symbol tables (variables, possibly functions) and expressions. BeScript, unlike "hey", is a real language in the sense that it has an actual syntax and a formal grammar: the language is "compiled" into scripting messages. By contrast, "hey" is basically a parser and interpreter. BeScript is not based on "hey", although it uses some of Attila's code for message display and properties management. This is not to discount "hey" in any way: it is a great application and I've learnt a lot from Attila's work. BeScript is simply a larger project than "hey", but they share the same purpose. Note that "hey" is still the fastest method to send a single scripting message to a remote object. Moreover, since BeScript currently lacks standard programming language features, operations such as iterating over a collection of objects are not available yet: currently they must be expressed using "hey" from a standard shell script. Hopefully this situation won't last too long.
I have included some sample scripts to help users get started with the language. All of them are reasonably easy to understand because BeScript is essentially English. BeScript has been tested somewhat extensively but certainly not enough. Users are encouraged to explore the possibilities offered by easy BeOS scripting and to contact me for help and further discussion. Below please find a description of the general grammar and also of all currently available commands. This is an alpha release so all standard caveats apply.
Grammar
BeScript programs are normal text files. UTF8 characters are supported in strings and elsewhere. Program formatting is not enforced but commands and blocks must be separated by whitespace.
The BeScript syntax is very similar to "hey" because it closely resembles the system. Most BeScript commands are in the form
command [specifier [value [with data]]]
where specifier is sometimes optional, value is often optional, and data is almost always optional. All commands are in lowercase only; specifiers are either in MixedCase (all system ones), or in lowercase/UPPERCASE (some application-defined ones). Commands need only be separated by whitespace; there is no "end-of-statement" character (such as semicolon in C/C++). System commands include do (alias execute or exec), get, set, create, delete, count, getsuites, about, quit, save, and load. BeScript commands currently include click, type, choose, pause, print, and assign. Custom commands defined by scriptable objects (including both Be and third-party objects) are also available but must be addressed directly to the object that supports them. A common example is MoveBy defined by Window objects: you cannot ask an application or a View to do a MoveBy on a Window, you have to talk to the Window itself. This is a design choice of the native BeOS scripting system and, once again, it makes sense, so you should get used to thinking of talking to the right object.
Constructing a specifier that refers to the desired object is easy: just follow the system rules.
Each basic specifier can be: direct e.g. Shelf; name e.g. View "listview"; index e.g. Window 3 or -3 for reverse index; and range e.g. Text [0 to 6] or Text [-3 to 4] for reverse range. The latter form of specifier considers the first value as the starting index (counted from the end if negative) and the second value as the number of objects specified. Indices and ranges are always integers.
Specifiers can be regular, partial, complete, or dynamic.
Regular specifiers are standard Be specifiers, such as:
Window 4
Window "Network"
View 0 of Window 3
MenuBar of Window "Deskbar"
View "someview" of Window "Untitled"
View "listview" of View 0 of Window 3
View "scroller" of View "superview" of View "baseview" of View 4
Text [0 to 100] of View "TextField:" of Window "Text Settings"
Selection [-1 to 4] of View "listview"
Regular specifiers can also have additional with blocks; see below for more information.
Partial specifiers are similar to regular specifiers, but they lack the initial property. Partial specifiers can also be dynamic. Examples are:
"Screen size" of View "Preferences"
"Host name:" in Window "Network"
"Square size" of View "Settings" of Window "Render"
Complete specifiers are like regular specifiers but they always contain the entire path to an object. Usually they are given with indices and used mainly when examining the system with BeScriptPeek.
Dynamic specifiers are indentified by using in rather than of for the last item. Usually there are two items in a dynamic specifier: the object to be resolved and the container object. Dynamic specifiers can also be partial (e.g. not start with View/Window). Currently, a Window object must follow the in keyword: that is, currently only Window objects can be containers. Support is planned for View-based dynamic specifiers as well. Dynamic specifiers can also be partial. Some examples of currently available dynamic specifiers:
"Host name:" in Window "Network"
View "Manual" in Window "About Box"
button "Use an external editor" in Window "Environment Preferences"
Here, button is a reserved keyword in BeScript -- not a Be-defined property.
Values can be either simple (like integers, floating point numbers, strings, and boolean values) or Be-defined (like int16, BRect, and so on). Currently BeScript supports the following values:
VALUE EXAMPLE
---------------------------------------------------------------------------------
integer (32-bit) 27480
floating point -457.3
string "text" or string("text")
boolean true/false or bool(true/false) [Mixed/UPPER case too]
integer 8-bit int8(127)
integer 16-bit int16(49152)
integer 32-bit int32(-67045231)
single precision float float(5678.364)
double precision float double(829.9098947)
point BPoint(45.0,120.0) [floating point only]
rectangle BRect(100.0,150.0,300.0,350.0) [floating point only]
RGB color rgb_color(240,200,160,255) [integer only]
filename file("/path/to/file")
WITH blocks
Data can be added to some commands with the construct
with [name=]value [and [name=]value ...]
If you do not specify the name, it is taken to be "data". An example of a with block comes from Becasso:
create Canvas with name=MyCanvas and size=BRect(100.0,100.0,300.0,300.0)
The best way to get acquainted with the commands is to look at the sample sources, currently be_apps.bs and becasso.bs. Below please find a quick list of all available commands: I apologize for the lack of a more satisfying discussion but this is an alpha release and the language is not finalized yet.
Commands
Optional items are shown between square brackets ("[" and "]"). Alternate items are separated by a pipe character ("|"). The examples given do not always correspond to something meaningful: they are merely samples of correct grammar constructs in BeScript.
TELL blocks
BeScript commands are grouped within tell blocks:
tell application | MIME signature
command
[command ...]
endtell
This constructs informs BeScript that we will talk to the given application, possibly identified via its MIME signature, which must be running at the time when the tell block is executed. Once again, proper formatting is not enforced but strongly suggested. The endtell keyword may be abbreviated as endt.
Command:
let specifier do
command
[command ...]
end
tell specifier to command
Examples:
let View "Server:" in Window "Connection" do
get Value
set Value to "http://www.be.com"
end
tell Window "Untitled" to choose "Save..."
Description
Select the current object to whom BeScript will talk to when running the commands contained in the block. The specifier can be a regular, complete, or dynamic system specifier (not a partial one), or an application-defined specifier with custom syntax. The second form, with the tell keyword, is meant for a single command only and does not require an end keyword -- but it does require the to keyword just like let requires the do keyword. If the let or tell block refers to (i.e. specifier is) a Window, it will be used implicitly while resolving dynamic specifiers for commands contained in the block (if necessary).
Command:
pause milliseconds
Examples:
pause 2500 # Two and a half seconds.
Description
Pause execution for the given number of milliseconds (an integer value).
Command:
print "string"
Examples:
print "Hello, world!\n"
Description
Print the given string on the console (stdout).
Command:
getsuites [specifier]
Examples:
tell "Gobe Productive" getsuites endtell
getsuites of Shelf of View "Status" of Window "Deskbar"
getsuites of View "Okay"
Description
Return the scripting capabilities of the given specifier and display them on the console. The specifier can be a regular, complete, or dynamic system specifier (not a partial one), or an application-defined specifier with custom syntax. The result is printed in a human-readable form: each available property, specifier, and/or command is displayed for all suites supported by the object.
Command:
do specifier | 'what' [with data]
Aliases:
execute
exec
Examples:
do Item 1 of View "Programs List" in Window "List"
do '_ABR' of Window 3
exec MenuItem "Settings..." of Window 0
Description
Execute the given specifier or 'what' verb. The specifier can be a regular, complete, or dynamic system specifier (not a partial one), or an application-defined specifier with custom syntax. An optional with block may be appended to the specifier. If the specifier is a custom property defined by the currently selected object, an alternate form is supported:
do property be_value
Examples:
tell Window "Database" to do MoveBy BPoint(-50.0,50.0)
where be_value is any kind of value explicity qualified (i.e. "string" is not allowed: string("thestring") must be used instead; 244567 is wrong, int32(244567) is correct; ...)
Command:
get specifier
Examples:
get Title of Window 2
get Shelf of View "Status" of Window "Deskbar"
get Value of View "Rotation:"
Description
Return the contents of the given specifier and display them on the console. The specifier can be a regular, complete, or dynamic system specifier (not a partial one), or an application-defined specifier with custom syntax. The result is printed according to its type; messengers are displayed as sequences of hexadecimal values.
Command:
set specifier to value
Examples:
set Hidden to true
set Foreground to rgb_color(255,0,128,255)
set Value of View "Frame rate:" to 60
set Label of View "unnamed_button" to "OurButton"
set Title of Window 3 to "OurWindow"
Description
Set the contents of the given specifier to the given value. The latter can be any kind of value, even implicity qualified. The specifier can be a regular, complete, or dynamic system specifier (not a partial one), or an application-defined specifier with custom syntax.
Command:
count specifier
Examples:
count Window
count View of View "listview" in Window "Document"
count MenuItem of Menu "File"
tell Shelf of View "Status" of Window "Deskbar" to count Replicant
Description
Count the number of instances of the given specifier and display it on the console. The specifier can be a regular, complete, or dynamic system specifier (not a partial one), or an application-defined specifier with custom syntax.
Command:
delete specifier
Alias:
del
Examples:
delete MenuItem "Settings"
delete Replicant "PPPDeskBar" of View "Status" of Window "Deskbar"
Description
Remove the given specifier. The specifier can be a regular, complete, or dynamic system specifier (not a partial one), or an application-defined specifier with custom syntax.
Command:
create specifier [with data]
Examples:
create Palette
create Document with name=MyDocument
create Canvas with name = MyCanvas and size = BRect(100.0,100.0,200.0,200.0)
Description
Create the given specifier. The specifier can be a regular, complete, or dynamic system specifier (not a partial one), or an application-defined specifier with custom syntax. An optional with block may be appended to the specifier.
Command:
quit [specifier]
Examples:
quit
quit Window 3
quit Canvas "MyCanvas"
Description
Quit the current target or the given specifier. The specifier can be a regular, complete, or dynamic system specifier (not a partial one), or an application-defined specifier with custom syntax.
Command:
about [specifier]
Examples:
about
about Window "Untitled"
Description
Ask the current target or the given specifier for its about box. The specifier can be a regular, complete, or dynamic system specifier (not a partial one), or an application-defined specifier with custom syntax.
Command:
save [specifier]
Examples:
save
save Window "ProjectFile"
Description
Save on disk the current target or the given specifier, usually a Window object. The specifier can be a regular, complete, or dynamic system specifier (not a partial one), or an application-defined specifier with custom syntax. Currently the message sent to the target is not always understood: I am aware of the problem and will fix it soon.
Command:
load "file"
load file("file")
Examples:
tell Eddie load file("/boot/home/.profile") endt
load "MyImage.jpg"
Description
Ask the current target to load the given file, which is a path name as appropriate for the context. This command will always work when addressed to applications that support it; some Windows, however, do not accept it correctly. Currently I don't know how to fix this but am working on it.
Command:
click [button] specifier
Examples:
click button "Manual" in Window "About"
click "Save Changes" in Window "Preferences"
Description
Simulate a button-click on the given specifier. Note that this is not a mouse-click. The specifier can be a regular, complete, partial, or dynamic system specifier. button is an optional keyword.
Command:
type "string" into [field] specifier
Examples:
type "128.197.13.20" into field "URL:" of Window "Browser"
type "OurHostName" into "Host name:"
Description
Transfer the text string into the field specifier. The specifier can be a system regular, complete, partial, or dynamic specifier. field is an optional keyword.
Command:
choose "item" [specifier]
choose item_number specifier
Examples:
choose "Settings"
choose "Preferences..." of Window 0
choose "Save" of Menu "File"
choose 3 of Menu "Insert Frame" of Menu "Frame"
Description
Invoke the given menu item or item_number. The specifier can be a system regular, complete, partial, or dynamic specifier, and it must be present in the second form of the command. It is usually a Window, or a particular Menu of a given Window. The MenuBar object must not be expressed explicitly: BeScript does it automatically. This implies that a choose command cannot appear in a let block that addresses a MenuBar; however, the command is meant exactly to avoid the need for such a block.
Command:
assign value to specifier
Examples:
assign 100 to "Size:"
assign "http://www.benews.com" to "URL:"
assign 0.5 to View "Panning" of Window "Mixer"
Description
Write the given value to the given specifier. The specifier can be a system regular, complete, partial, or dynamic specifier. The advantage over set is that there is no need of prepending "Value of" to the specifier, and that the latter can be partial. As you can see from the examples above, using assign with simple strings is equivalent to the type command.
Support for other commands is planned, but it is too early now to commit to any specific command. Users are once again encouraged to try out the language and submit bugs and features requests to Dario Accornero.
Please read the Version History in the README file before using BeScript.