The Runner API
The Runner API allows extensions to provide custom ways to "run" files or projects as described here. These appear in the run menu and can be used to compile code, launch web previews, or execute scripts.
Runner Types
A Runner is a class that defines how to execute a specific target. There are two main types of runners:
- FileRunner: Targeted at specific files (e.g., running a Python script).
- ProjectRunner: Targeted at a project root (e.g., building a Gradle project).
Implementing a Runner
FileRunner
To create a file-based runner, you simply extend FileRunner:
class MyCustomRunner : FileRunner() {
// ...
// Filter which files this runner can handle
override fun matcher(fileObject: FileObject): Boolean {
return fileObject.getExtension() == "myext"
}
override suspend fun run(activity: Activity, fileObject: FileObject) {
// Run your tool here
}
}ProjectRunner
To create a project-based runner, you instead extend ProjectRunner:
class MyCustomRunner : ProjectRunner() {
// ...
// Filter which projects this runner can handle
override fun matcher(projectRoot: FileObject): Boolean {
return runBlocking { projectRoot.hasChild("package.json") }
}
override suspend fun run(activity: Activity, projectRoot: FileObject) {
// Run your tool here
}
}Basic Properties
Every Runner must also define a unique id and a human-readable label.
Optionally you can provide a custom icon through getIcon(...) or return null to use the default run button icon.
override val id = "com.example.myrunner"
override val label = "Run with MyTool"
override fun getIcon(context: Context): Icon? {
return null
// or better:
return Icon.ExternalResourceIcon(R.drawable.ic_run, context.resources)
}Stopping Runners
If your runner starts a long-running process, you should implement isRunning and stop:
override suspend fun isRunning(): Boolean {
return myProcess?.isAlive == true
}
override suspend fun stop() {
myProcess?.destroy()
}Registering Runners
Use the RunnerManager to make your runner available to the user.
override fun onLoad() {
val myRunner = MyCustomRunner()
RunnerManager.registerRunner(myRunner)
}The app will automatically show your runner in the UI if the matcher returns true for the current file or project.
Unregistering
As with all registrations, remember to clean up in onDispose.
override fun onDispose() {
RunnerManager.unregisterRunner(myRunner)
}