# orion.shell.command

The `orion.shell.command` service is used to contribute commands to the Shell page. When the service is executed, an object containing the user-supplied argument values is passed to the service's `callback` method. The command then optionally returns a response (a return value) to be displayed in the Shell page.

## Service methods

Implementations of `orion.shell.command` may define the following method:

callback(args, context)
  Takes the user-supplied command-line arguments and optionally returns a response value. The arguments are as follows:
  args
    An object with the user-supplied command-line arguments (if any)
  context
    An object with property {cwd: string}, indicating the user's current working directory in the Shell page

The basic return value types of callback() are:

  string (note that occurrences of `text(link address)` are converted to links when output)
  file object: `{path: string (relative to CWD), isDirectory: boolean (default: false), blob: aBlob (optional)}`
  blob object: `{blob: aBlob}`

Implementations of callback() can return either a value with one of these basic types, or an `orion.Deferred`. Returning an `orion.Deferred` facilitates the asynchronous return of a result value (by invoking `Deferred.resolve()`), the incremental display of progress (by invoking `Deferred.progress(string)`), and the interim use of a delegated UI that is shown in a frame provided by the Shell page.

To make use of a delegated UI, invoke `Deferred.progress({uriTemplate: url, width: string, height: string})`, where url at the content to show in the provided frame ( example). This content is subsequently responsible for sending the command's result value to the Shell page by posting the following message:

  `window.parent.postMessage(JSON.stringify({pageService: "orion.page.delegatedUI", source: theCommandName, result: theResultValue}), "*");`

The only context where a contributed command would not define this service method is to assist with the contribution of sub-commands. For example, to contribute commands "tar create" and "tar extract", a parent command "tar" without a service method must first be contributed.

## Service attributes

Implementations of `orion.shell.command` define the following attributes:

name
  The name that is typed at the command line to invoke the command
description
  (Recommended) A brief description of the command
manual
  (Optional) A longer description of the command
parameters
  (Optional) An array of the parameters that the command accepts

The Shell page currently uses GCLI as its underlying shell widget, and consequently has adopted its syntax for parameter specification. The basic parameter object attributes are:

  name
    The parameter's identifier
  type
    One of { string | boolean | number | array | selection | file | blob | a custom orion.shell.type}
  description
    (Recommended) A brief description of the parameter
  defaultValue
    (Optional) The value assumed by the parameter if the user does not supply a value for it. Specifying this makes the parameter optional.

## Example of Using a Delegated UI

The following "login" command implementation delegates to accompanying file "authenticationPrompter.html":

    callback: function(args, context) {
     var result = new orion.Deferred();
     var url = window.location.href;
     url = url.substring(0, url.lastIndexOf('/')); //$NON-NLS-0$
     setTimeout(function() {
       result.progress({uriTemplate: url + "/authenticationPrompter.html", width: "400px", height: "100px"});
     });
     return result;
    }

authenticationPrompter.html shows simple username/password fields in the frame that has been provided to it by the Shell page. When the page's Submit button is pressed it performs the authentication and posts the result value. The frame showing this page is subsequently removed by the Shell page.

    <head>
    <script>
      function authenticate() {
        /* do authentication here, assume is fine, so post result back to Shell page */
        var result = "Authenticated user: " + document.getElementById("username").value;
        window.parent.postMessage(JSON.stringify({pageService: "orion.page.delegatedUI", source: "login", result: result}), "*");
        return true;
      }
    </script>
    </head>
    <body>
     User name:<input type="text" id="username"><br>
     Password:<input type="password" id="password">
     <button type="button" onclick="authenticate();" value="Submit">Submit</button>
    </body>