-
Notifications
You must be signed in to change notification settings - Fork 166
Plugins
Since 0.4, Scripted now has a plugin architecture. This page provides an introduction to the Scripted plugin model and APIs. The information is intended to convey the general architectural ideas and help you get started but won't document the API in detail.
A Scripted plugin is an AMD module that is autoloaded by the Scripted-client when it starts up.
The easiest way to explain what a Scripted plugin looks like is with an example. Simple plugins just consists of single JavaScript file. The entire source-code of a very simple plugin is shown below:
define(function(require) {
var editorExt = require('scripted/api/editor-extensions');
//Defines an editor action.
editorExt.setAction('allCaps', {
name: 'All Caps', // readable description
handler: function (editor) {
var sel = editor.getSelection();
var text = editor.getText(sel.start, sel.end);
text = text.toUpperCase();
editor.setText(text, sel.start, sel.end);
}
});
});
This plugin contributes an action
to the editor. When the action is executed, it converts the currently
selected text into upper-case letters.
Let's disect the code a little as it's structure is pretty typical.
define(function (require) {
... your actual code goes here ...
});
If you have used requirejs/AMD before you will already know what this is. Essentially you need this little-bit of boilerplate so an AMD module loader like requirejs can load your module and keep track of its dependencies.
The next bit of code at the start of your plugin usually makes one or more calls to the require
function
to import various APIs/libraries the plugin wants to use. A typical plugin will want to contribute some
kind of extension to the Scripted editor. This is done by calling functions in the
editor-extensions
apis. Our plugin has this line:
var editorExt = require('scripted/api/editor-extensions');
Anywhere below this line we can call functions in the api with editorExt.<functon-name>(...)
.
The editor-extensions
API contains several functions plugins can call to add different kinds of functionality to Scripted editors.
Our example plugin calls setAction
to associate the actionID allCaps
with a handler function that
converts the current editor selection into upper case.
Other things you can do via the editor-extensions
API include:
- transform the contents of the editor just before a save (e.g. to remove trailing-white-space or
perform code cleanups). - contribute gutter annotations
- define keybindings
- ...
To install a plugin you simply need to drop it in the right place. You will also need to reload the browser if Scripted is already running.
The plugin loader will look in these two places:
- USER_HOME/.scriptedrc/plugins/
- SCRIPTED_HOME/plugins
SCRIPTED_HOME is whichever directory you installed Scripted in. Normally you would find any
plugins that come pre-installed with Scripted in SCRIPTED_HOME/plugins
and you would install
your own plugins under USER_HOME.
The simplest plugin consist of only a single JavaScript file.
More complex plugins may consist of multiple files. Some of the files may contain JavaScript, but others may be CSS or text snippets used by your plugin code.
To support this, we allow a plugin to be packaged as a directory. You can browse a typical example here.
A "directorified" plugin needs at least a plugin.json
file and a index.js
file.
Unlike a single-file plugin, a directorified plugin is not activated by default but
needs to be explicitly turned on by adding some code like this to the plugin.json
:
{
"scripted" : {
"plugin" : true
}
}
Instead of having an index.js
file, a 'main' property can be added to point to your
plugin's main JavaScript file. Effectively, the 'main' file will be the one that Scripted loads
when your plugin is activated. All the other files in the directory are
entirely yours to manage and load in whatever way you need them to support your plugin's
functionality.
Note that some of the more complex plugins in the SCRIPTED_HOME/plugins
folder are shipped as
example code, but are disabled by default. To see them in action you will have switch them
on by editing their plugin.json
and changing the plugin property to true.
A Scripted plugin is just an ordinary AMD module. The Scripted-client itself is entirely built
out of AMD modules. Thus your plugin can, in theory, do anything any other Scripted client code
can do through internal APIs. However, these internal APIs are neither stable, well-documented
nor easy to use. While we don't want to stop you from reading our code and using those APIs,
we want to make things easier for you. Therefore, we are developing a growing set
of public APIs scripted/api/<some-name>
. These are the APIs we intend plugin authors to use
and they are being designed to make doing the things typical plugins may want to do easy.
To find out what public APIs are available you can browse their source code.
Also, when you have already imported an API like editor-extensions
in your plugin module.
You can get good content assist from Scripted about its functions. For example:
You can also see the corresponding JSDoc when hovering over an API call with the mouse:
Hovers and content assist work quite well for APIs imported via an explicit require
call.
Unfortunately, due to current limitations it doesn't yet work so well
for APIs that are implicitly passed as arguments to callback functions. Many
callbacks in the Scripted API receive an editor
instance. The JSDoc will probably tell you this
fact, however it won't help you to discover what functions are available on editor instances.
To find out about this you will currently need to refer to the source code
here.
Evidently, we intend to solve this problem in a future version of Scripted.
Another good way to learn about the plugin-apis is looking at our example plugins.
They are part of the Scripted distribution in the SCRIPTED_HOME/plugins
folder.
You can browse their code with Scripted. Or you can
browse them on github.
At the moment you need to copy them into plugins into the right place. We are currently thinking about easier ways to install them (via URL) and better ways to share them (a repository).