-
Notifications
You must be signed in to change notification settings - Fork 15
Scripts Deep Dive
OpenIDE scripts are command extensions to the oi program. It can create new command options and extend existing options. When running oi script you will get a list of available scripts. Available scripts are located in your global active/default profile, your local active/default profile and under enabled languages. To create a simple script run oi script new myscript.py. This will create a script in your local active profile that can be accessed through running oi myscript. Since we chose .py as extension the python template will be used. Scripts can be written in any language supporting stdin and stdout. The script will look like this:
#!/usr/bin/env python
import sys
def print_definitions():
# Definition format usually represented as a single line:
# Script description|
# command1|"Command1 description"
# param|"Param description" end
# end
# command2|"Command2 description"
# param|"Param description" end
# end
print("Script description?")
def run_command(run_location, global_profile, local_profile, args):
# Script parameters
# Param 1: Script run location
# Param 2: global profile name
# Param 3: local profile name
# Param 4-: Any passed argument
#
# When calling oi use the --profile=PROFILE_NAME and
# --global-profile=PROFILE_NAME argument to ensure calling scripts
# with the right profile.
#
# To post back oi commands print command prefixed by command| to standard output
# To post a comment print to std output prefixed by comment|
# To post an error print to std output prefixed by error|
# Place script core here
print("Hello world!")
if __name__ == "__main__":
args = sys.argv
if len(args) > 1 and args[2] == 'get-command-definitions':
print_definitions()
else:
run_command(args[1], args[2], args[3], args[4:])
If we now run oi myscript it will output Hello World! as the code shows.
The first thing we will look at inside this script is the script definition. OpenIDE will expect to have the definitions written to stdout when the script is called with myscript.py TOKEN_PATH get-command-definitions The definition determines how basic docs and auto completion will work for your script. You can run oi help myscript to see what definition has been read from your script. The format is as seen above command|"description" end whith the option of sub commands / params inside.
The command parts of the definition has a few options. When using all lowercase for the command like new it will be interpreted as a command. If writing it in all uppercase like FILENAME it will assume that the user is supposted to input it. When starting the command with - like -g or --global it will assume that these are options. By wrapping the command in square braces like this [new] or [FILENAME] the command is marked as optional. The last option is overriding which is marked with double square braces like this [[script]]. We will look more into overriding command later.
Building up a definition for creating a new file and editing an existing file would look something like this:
Manages files|
new|"Creates a new file"
FILENAME|"The name of the file to create" end
end
edit|"Edit a file"
FILEPATH|"The path to the file you want to edit" end
end
When running a script OpenIDE will pass to it TOKEN_PATH GLOBAL_PROFILE_NAME LOCAL_PROFILE_NAME CMD_ARG1 CMD_ARG2 CMD_ARG3.... Inside the script anything that is written to stdout will be written out to the terminal by OpenIDE when calling the script. Stdin is also forwarded to support scripts getting user input.
Any type of special formatting/command/request is done using the | delimiter inside of a script. Supported are:
-
warning|some textOutputs warning text -
error|some textOutputs error text -
event|some eventPublishes an event -
command|editor goto /my/file.txt|10|5Runs an OpenIDE command.- end-of-command is printed to stdin when command has completed
-
request|editor get-caretRuns a request where result is printed to stdin- end-of-conversation is printed to stdin when command has completed
- editor, codemodel and languages are supported for request
-
command-builtin|command arguments..Forces running a built-in command even though overridden -
command-language|command arguments...Forces running language command even though overridden -
command-languagescript|cmd args...Forces running language script even though overridden -
command-script|cmd args...Forces running script even though overridden -
command-original|cmd args...Runs the command that the given command overrides
When writing scripts you can use the run on save feature to get instant feedback. Run the oi script repl SCRIPT_NAME [ARG1] [ARG2].... Every time you make a change to the script it will run the script with passed arguments and print the output.
As most commands in OpenIDE are positional like oi conf read SETTING_NAME and oi package install PACKAGE this means we end up with a hierarchy of commands. So what if we wanted to add a new option to the C# create command. So for instance for creating a console application you can run oi C# create console MyConsoleProject. If we decided to add a definition for C# like My script|C#|"My thins" ...... end we end up overriding the entire C# command hierarchy. We could do that and then use command-builtin|C# .... to run the original one but what we'd rather do is this:
Creates a Nancy web project|
[[C#]]|""
[[create]]|""
web-project|"Creates a Nancy web project"
PATH|"Relative path to create project at" end
end
end
end
Now we are able to run the command with oi C# create web-project src/TestProj. If there was already a command in there at C# create with the name web-project it would be overridden by this command. When overriding command the configuration points and profiles play an important role. The priority of commands are as follows:
- Scripts active profile
- Language scripts active profile
- Language commands active profile
- Scripts default profile
- Language scripts default profile
- Language commands default profile
- Scripts active global profile
- Language scripts active global profile
- Language commands active global profile
- Scripts default global profile
- Language scripts default global profile
- Language commands default global profile
So let's say that we are not happy with the default behavior of the init command. In the package repository there is an init script overrides init to also create a sublime project and create and load a profile. If you want to take a look at the script run oi package install init-sublime and then oi script edit init. You will see that the script uses command-builtinn|init args.. to run the original init command. It waits for end-of-command before it runs the commands for creating profile, config setup and so on.
All extensions are allowed to have one file in the actual script folder and then whatever files it wants inside a folder called SCRIPT_NAME-files at the same place. If made in to a package any files you want to survive upgrades must be placed inside a SCRIPT_NAME-files/preserved-data folder. Any type of state that the script might have must be placed in a SCRIPT_NAME-files/state folder to not cause constant rebuilds of command definitions.
Any extension is free to have it's own configuration settings. All configuration settings are exposed through the oi conf list command which prints all available configuration options. To have your scripts configuration options show up there create a folder called myscript-files where the myscript.py file is located and place a file called myscript.oicfgoptions in it. The format of the file is one configuration option per line and the option format is myscript.some.config.option|This is the option description.