prompt.js 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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. /**
  7. * Base prompt skeleton
  8. */
  9. class Prompt extends EventEmitter {
  10. constructor(opts={}) {
  11. super();
  12. this.in = opts.in || process.stdin;
  13. this.out = opts.out || process.stdout;
  14. const rl = readline.createInterface(this.in);
  15. readline.emitKeypressEvents(this.in, rl);
  16. if (this.in.isTTY) this.in.setRawMode(true);
  17. const keypress = (str, key) => {
  18. let a = action(key);
  19. if (a === false) {
  20. this._ && this._(str, key);
  21. } else if (typeof this[a] === 'function') {
  22. this[a](key);
  23. } else {
  24. this.bell();
  25. }
  26. };
  27. const close = () => {
  28. this.out.write(cursor.show);
  29. this.in.removeListener('keypress', keypress);
  30. if (this.in.isTTY) this.in.setRawMode(false);
  31. rl.close();
  32. this.emit(this.aborted ? 'abort' : 'submit', this.value);
  33. };
  34. this.close = close;
  35. this.in.on('keypress', keypress);
  36. }
  37. fire() {
  38. this.emit('state', {
  39. value: this.value,
  40. aborted: !!this.aborted
  41. });
  42. }
  43. bell() {
  44. this.out.write(beep);
  45. }
  46. }
  47. module.exports = Prompt;