prompt.js 1.8 KB

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