prompt.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. 'use strict';
  2. const readline = require('readline');
  3. const _require = require('../util'),
  4. action = _require.action;
  5. const EventEmitter = require('events');
  6. const _require2 = require('sisteransi'),
  7. beep = _require2.beep,
  8. cursor = _require2.cursor;
  9. const color = require('kleur');
  10. /**
  11. * Base prompt skeleton
  12. * @param {Stream} [opts.stdin] The Readable stream to listen to
  13. * @param {Stream} [opts.stdout] The Writable stream to write readline data to
  14. */
  15. class Prompt extends EventEmitter {
  16. constructor(opts = {}) {
  17. super();
  18. this.firstRender = true;
  19. this.in = opts.stdin || process.stdin;
  20. this.out = opts.stdout || process.stdout;
  21. this.onRender = (opts.onRender || (() => void 0)).bind(this);
  22. const rl = readline.createInterface({
  23. input: this.in,
  24. escapeCodeTimeout: 50
  25. });
  26. readline.emitKeypressEvents(this.in, rl);
  27. if (this.in.isTTY) this.in.setRawMode(true);
  28. const isSelect = ['SelectPrompt', 'MultiselectPrompt'].indexOf(this.constructor.name) > -1;
  29. const keypress = (str, key) => {
  30. let a = action(key, isSelect);
  31. if (a === false) {
  32. this._ && this._(str, key);
  33. } else if (typeof this[a] === 'function') {
  34. this[a](key);
  35. } else {
  36. this.bell();
  37. }
  38. };
  39. this.close = () => {
  40. this.out.write(cursor.show);
  41. this.in.removeListener('keypress', keypress);
  42. if (this.in.isTTY) this.in.setRawMode(false);
  43. rl.close();
  44. this.emit(this.aborted ? 'abort' : this.exited ? 'exit' : 'submit', this.value);
  45. this.closed = true;
  46. };
  47. this.in.on('keypress', keypress);
  48. }
  49. fire() {
  50. this.emit('state', {
  51. value: this.value,
  52. aborted: !!this.aborted,
  53. exited: !!this.exited
  54. });
  55. }
  56. bell() {
  57. this.out.write(beep);
  58. }
  59. render() {
  60. this.onRender(color);
  61. if (this.firstRender) this.firstRender = false;
  62. }
  63. }
  64. module.exports = Prompt;