diff --git a/plugins/pilot/lib/cli.js b/plugins/pilot/lib/cli.js index a747678f..b7bb1419 100644 --- a/plugins/pilot/lib/cli.js +++ b/plugins/pilot/lib/cli.js @@ -97,7 +97,7 @@ oop.inherits(ConversionHint, Hint); * @constructor */ function Argument(text, start, end, priorSpace) { - this.text = text; + this.setText(text); this.start = start; this.end = end; this.priorSpace = priorSpace; @@ -114,26 +114,55 @@ Argument.prototype = { }, setText: function(text) { + if (text == null) { + throw new Error('Illegal text for Argument: ' + text); + } this.text = text; } }; /** * Merge an array of arguments into a single argument. */ -Argument.mergeAll = function(argArray) { +Argument.merge = function(argArray, start, end) { + start = (start === undefined) ? 0 : start; + end = (end === undefined) ? argArray.length : end; + var joined; - argArray.forEach(function(arg) { + for (var i = start; i < end; i++) { + var arg = argArray[i]; if (!joined) { joined = arg; } else { joined = joined.merge(arg); } - }); + } return joined; }; +/** + * CLI / UI Interface + * The Cli interacts with the UI via an instance of CliUi. + * This implementation is designed as a template rather than to be used. + * It is expected that we will have a number of implementations of this: + * - A firebug/webkit inspector cli shim + * - A simple input[type=text] version + * - A possible Cloud9 UI version + * - A possible Skywriter UI version + * This class will probably need refactoring as time goes on. + * + * TODO: Who should own the Requisition? + */ +function CliUi() { +} +CliUi.prototype = { + getSelection: function() {}, + setHints: function() {}, + setRequisition: function() {} +}; + + /** * An object used during command line parsing to hold the various intermediate * data steps. @@ -143,7 +172,7 @@ Argument.mergeAll = function(argArray) { *
The other output value is input.requisition which gives access to an * args object for use in executing the final command. * - * The majority of the functions in this class are called in sequence by the + *
The majority of the functions in this class are called in sequence by the * constructor. Their task is to add to hints fill out the requisition. *
The general sequence is:
Default: ' + param.type.defaultValue + '
'); } - }); + }, this); } return docs.join(''); @@ -665,10 +716,8 @@ Requisition.prototype = { getHints: function() { var hints = []; Object.keys(this._assignments).map(function(name) { - var hint = this._assignments[name].getHint(); - if (hint) { - hints.push(hint); - } + // Append the assignments hints to our list + hints.push.apply(hints, this._assignments[name].getHints()); }, this); return hints; }, @@ -729,7 +778,7 @@ Assignment.prototype = { /** * The current value (i.e. not the string representation) - * @readonly - use setValue() to mutate + * Use setValue() to mutate */ value: undefined, setValue: function(value) { @@ -739,18 +788,20 @@ Assignment.prototype = { if (value === undefined) { value = this.param.defaultValue; } - var text = (value === null) ? '' : this.param.type.stringify(value); + this.value = value; + + var text = (value == null) ? '' : this.param.type.stringify(value); if (this.arg) { this.arg.setText(text); } - this.value = value; - this.conversion = new Conversion(value, Status.VALID, '', []); + + this.conversion = undefined; //this._dispatchEvent('change', { assignment: this }); }, /** * The textual representation of the current value - * @readonly - use setValue() to mutate + * Use setValue() to mutate */ arg: undefined, setArgument: function(arg) { @@ -763,13 +814,27 @@ Assignment.prototype = { //this._dispatchEvent('change', { assignment: this }); }, - getHint: function() { - if (this.conversion.status === Status.VALID && - this.conversion.message === '') { - return undefined; + /** + * Create a list of this hints associated with this parameter assignment + */ + getHints: function() { + var hints = []; + if (this.conversion != null && + (this.conversion.status !== Status.VALID || + this.conversion.message)) { + hints.push(new ConversionHint(this.conversion, this.arg)); } - return new ConversionHint(this.conversion, this.arg); + var argProvided = this.arg != null && this.arg.text !== ''; + var dataProvided = this.value !== undefined || argProvided; + + if (this.param.defaultValue === undefined && !dataProvided) { + // If the there is no data provided, we have no start/end. Use -1 + hints.push(new Hint(Status.INVALID, + 'Argument for ' + param.name + ' is required' + -1, -1)); + } + return hints; }, /**