# orion.edit.command

The `orion.edit.command` service allows plugins to provide a command that operates on the editor. Typically, the command that takes some editor text as input, performs some operation or transformation on the text, and generates a new text value. The command can also optionally receive and return selection information for changing the editor selection. The transformation can happen directly, or indirectly through a <dfn>delegated UI</dfn> provided by the plugin.

## Service methods (Orion 4.0)

The 4.0 version of the command API allows a command to take arbitrary action using the editorContext.

execute(editorContext, options)
  editorContext `ObjectReference` The Editor Context object.
  options `Object`
    options.contentType `String` The Content Type ID of the file being edited.
    options.input `String` Path and filename being edited.

The `execute()` method should return a Promise, which the provider is expected to resolve when it has finished performing the command action. The command action should be performed using the Editor Context object: for example, use `editorContext.setText()`to change the editor text, or `editorContext.setSelection()` to change the editor selection. The fulfillment value of the promise is ignored.

Note: Future versions of Orion will expose delegated UI functionality through the EditorContext object. This is currently not supported, due to Bug 419764.

## Service methods (Orion 3.0)

run(selectedText, text, selection, resource)
  selectedText `String`. The text that is currently selected in the editor.
  text `String`. Provides the entire buffer being edited.
  selection `orion.editor.Selection` The current selection in the editor.
  resource `String` The full path and filename of the file being edited.

The return value of `run()` is a CommandResult object.

### The CommandResult object

A CommandResult object is either a simple `String` which will replace the current editor selection, or an `object`.

- The object must either have a `text` property or a `uriTemplate` property.
  - If it has a `text` property, then the text is a replacement string for the entire editor buffer.
  - If it has a `uriTemplate` property, then a delegated UI iframe will be opened on the specified URI.
- It may optionally have a `width` and/or `height` property that describes the desired size of the UI. Width and height are specified in CSS units, such as "100px" or "50em". The delegated UI must post a message back to the host window with an object that identifies itself as a delegatedUI and contains a `result` property that describes the new selection text or the replacement text object. (See example).
- It may optionally have a `selection` object indicating the new selection value.
- It may optionally have a [[#The_Status_object|`status` field]] giving status information to show in the notification area.

### The Status object

A Status object has the following fields:

  Severity `String`. Allowed values are: `"Warning"`, `"Error"`.
  Message `String`. The status message to display. May include hyperlinks, given in Markdown syntax.

## Service attributes

Implementations of `orion.edit.command` must define the following attributes:

name
  `String` The command text to show to the user.
id
  `String` The id of the command contribution.
tooltip

`String` Optional. A tooltip describing the command.

img
  `String` Optional. The URL of an icon to associate with the command. The icon may not appear in all situations. For example, the main toolbar may not show the icon, but a menu item might show the icon.
key
  `Array` Optional. A key binding for the command. The structure of this array matches the arguments of the `orion.textview.KeyBinding` constructor. See its entry in the Client API reference for details.
validationProperties
  `Array` Optional. An array Validation Properties that must match the editor's file in order for the command to appear.
contentType
  `Array` Optional. An array of Content Type IDs for which this command is valid.

## Examples

The following examples start with the simplest editor command and then add more complexity.

### Replacing the selection

This example converts the selected text to upper case. The function return value is a simple string, so this is interpreted by the editor as replacement for the original editor selection. In the service properties, we see the command provides a key binding of Ctrl+U (or Cmd+U on Mac).

     var provider = new eclipse.PluginProvider();
     provider.registerServiceProvider("orion.edit.command", {
       run : function(text) {
         return text.toUpperCase();
       }
     }, {
       name : "UPPERCASE",
       id : "uppercase.example"
       img : "/images/gear.gif",
       key : [ "u", true ]
     });
     provider.connect();

### Replacing the editor contents

This example takes the selection and wraps it in C-style block comments. In this example the function returns a complex object with both `text` and `selection` fields. These are interpreted by the editor as the new editor buffer contents, and the new editor selection. A content type is used so that this command is only available for javascript files.

     contentType: ["application/javascript"],
     run : function(selectedText, text, selection) {
       return {text: text.substring(0,selection.start) + "/*" +
         text.substring(selection.start,selection.end) + "*/" +
         text.substring(selection.end),
         selection: {start:selection.start,end:selection.end+4}};
     }

### Delegating a UI before manipulating the editor

Here is an example of a delegated UI run function that computes a URL for the delegated UI based on the file name of the edited file. In this example, the function returns a complex object with a `uriTemplate` field and `width` and `height` properties. The UI that is opened will be responsible for posting a message back to the editor with a result object that contains either a String for the selected text or a complex object with replacement content.

     id: "delegatedUI.example",
     run : function(selectedText, text, selection, fileName) {
       return {uriTemplate: "http://com.example/myDelegatedUI#" + fileName, width: "600px", height: "400px"};
     }

The delegated UI would post a message identifying itself and including a result. The message must include a `pageService` property of "orion.page.delegatedUI", a `source` that matches the orion.edit.command service id, and either a `result` or a `cancelled` property. The following examples illustrate the different ways the result could be returned.

    /* a message containing replacement selected text */
    window.parent.postMessage(JSON.stringify({
       pageService: "orion.page.delegatedUI",
       source: "delegatedUI.example",
       result: replacementSelection
    }), "*");

    /* a message containing new content for the editor */
    window.parent.postMessage(JSON.stringify({
       pageService: "orion.page.delegatedUI",
       source: "delegatedUI.example",
       result: JSON.stringify({text: replacementText})
    }), "*");

    /* a message signifying user cancellation of the delegated UI */
    window.parent.postMessage(JSON.stringify({
       pageService: "orion.page.delegatedUI",
       source: "delegatedUI.example",
       cancelled: true
    }), "*");

### Google Picker example

The Google Picker is a fully functioning example of a delegated UI in an editor command. It opens a Google Picker allowing the user to pick a resource, and then inserts a link to that resource into the editor text. To install the plug-in, open this link. The code is available here.