diff --git a/README.md b/README.md index a5b420c..ccc5e78 100644 --- a/README.md +++ b/README.md @@ -9,19 +9,19 @@ var form = require('terminal-forms.js').create(process.stdin, process.stdout); Input types presently supported: -* `form.ask(prompt, handlers)` - * i.e. `form.ask("What is your quest? ", form.inputs.text).then(fn);` +* `form.ask(label, type)` where `type` is one of `form.inputs` + * i.e. `form.ask("What is your quest? ", 'text').then(fn);` * `form.setStatus(msg)` * i.e. `form.setStatus("(hint: you seek the Grail!)")` * `form.inputs` - * `.text` (no constraints) - * `.email` (checks format and looks up MX records) - * `.url` (checks format and looks up A/AAAA/CNAME records) + * `text` (no constraints) + * `email` (checks format and looks up MX records) + * `url` (checks format and looks up A/AAAA/CNAME records) Handlers ======== -A handler may implement any or all of these interfaces: +An input `type` handler may implement any or all of these interfaces: * `onReturnAsync(rs, ws, input, ch)` * `onDebounceAsync(rs, ws, input, ch)` diff --git a/index.js b/index.js index d35fd94..c934b4d 100644 --- a/index.js +++ b/index.js @@ -20,7 +20,10 @@ var ARROW_LEFT = '\u001b[D'; // 37 // \033[0m RESET var form = { - createWs: function (rrs, rws) { + PromiseA: PromiseA +, createWs: function (rrs, rws) { + rws = PromiseA.promisifyAll(rws); + // the user just hit enter to run a program, so the terminal is at x position 0, // however, we have no idea where y is, so we just make it really really negative var startY = -65537; @@ -90,8 +93,7 @@ var form = { } ws._inputIndex += 1; ws._x = ws._prompt.length + ws._inputIndex; - rws.write(str); - return; + return rws.writeAsync(str); case ARROW_LEFT: form.setStatus(rrs, ws, colors.dim( @@ -105,8 +107,7 @@ var form = { ws._inputIndex = Math.max(0, ws._inputIndex - 1); //ws._x = Math.max(0, ws._x - 1); ws._x = Math.max(0, ws._x - 1); - rws.write(str); - return; + return rws.writeAsync(str); } if (rows.length > 1) { @@ -120,7 +121,7 @@ var form = { ws._x += len; } - rws.write(str); + return rws.writeAsync(str); } , moveCursor: function (dx, dy) { if ('number' !== typeof dx || (0 !== dx && !dx)) { @@ -142,11 +143,30 @@ var form = { return ws; } -, ask: function (rrs, ws, prompt, cbs) { - ws._prompt = prompt; +, ask: function (rrs, ws, label, cbs) { + ws._prompt = label.label || label; ws._input = []; ws._inputIndex = 0; + if ('object' === typeof label) { + cbs = label; + } + + if ('string' === typeof cbs) { + cbs = { type: cbs }; + } + + if (cbs.type) { + if (!form.inputs[cbs.type]) { + return form.PromiseA.reject(new Error("input type '" + cbs.type + "' is not implemented")); + } + Object.keys(form.inputs[cbs.type]).forEach(function (key) { + if (!cbs[key]) { + cbs[key] = form.inputs[cbs.type][key]; + } + }); + } + return new PromiseA(function (resolve) { var ch; @@ -203,7 +223,7 @@ var form = { rrs.pause(); - (cbs.onReturnAsync||cbs.onReturn)(rrs, ws, ws._input.join(''), ch).then(function (normalInput) { + form.PromiseA.resolve((cbs.onReturnAsync||cbs.onReturn)(rrs, ws, ws._input.join(''), ch)).then(function (normalInput) { ws.write('\n'); ws.clearLine(); // person just hit enter, they are on the next line // (and this will clear the status, if any) @@ -298,6 +318,7 @@ var form = { rrs.on('data', onData); }); } + , setStatus: function (rrs, ws, msg) { //var errlen = (' ' + err.message).length; var x = ws._x; @@ -313,6 +334,10 @@ var form = { ws.cursorTo(x); ws.moveCursor(0, -1); } + +, println: function (rrs, ws, msg) { + return ws.write((msg||'') + '\n'); + } }; var inputs = { @@ -376,6 +401,7 @@ var inputs = { } }; +form.inputs = inputs; module.exports.inputs = inputs; module.exports.form = form; module.exports.create = function (rrs, rws) { @@ -400,6 +426,7 @@ module.exports.create = function (rrs, rws) { f.inputs = inputs; f.ws = ws; f.rrs = rrs; + f.PromiseA = PromiseA; return f;