tui-app.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // General-purpose wrapper code that can be used as the base of a tui-lib
  2. // program. Contained to reduce boilerplate and improve consistency between
  3. // programs.
  4. import {Root} from 'tui-lib/ui/primitives'
  5. import {CommandLineInterface, Flushable} from './interfaces/index.js'
  6. import * as ansi from './ansi.js'
  7. export default async function tuiApp(callback) {
  8. // TODO: Support other screen interfaces.
  9. const screenInterface = new CommandLineInterface();
  10. const flushable = new Flushable(process.stdout, true);
  11. const root = new Root(screenInterface, flushable);
  12. const size = await screenInterface.getScreenSize();
  13. root.w = size.width;
  14. root.h = size.height;
  15. flushable.resizeScreen(size);
  16. root.on('rendered', () => flushable.flush());
  17. screenInterface.on('resize', newSize => {
  18. root.w = newSize.width;
  19. root.h = newSize.height;
  20. flushable.resizeScreen(newSize);
  21. root.fixAllLayout();
  22. });
  23. const cleanTerminal = function () {
  24. process.stdout.write(ansi.cleanCursor());
  25. process.stdout.write(ansi.disableAlternateScreen());
  26. };
  27. const dirtyTerminal = function () {
  28. process.stdout.write(ansi.enableAlternateScreen());
  29. process.stdout.write(ansi.startTrackingMouse());
  30. };
  31. const quitProgram = function (status = 0) {
  32. cleanTerminal();
  33. process.exit(status);
  34. };
  35. const suspendProgram = function () {
  36. cleanTerminal();
  37. process.kill(process.pid, 'SIGTSTP');
  38. };
  39. process.on('SIGCONT', () => {
  40. flushable.clearLastFrame();
  41. process.stdin.setRawMode(false);
  42. process.stdin.setRawMode(true);
  43. dirtyTerminal();
  44. });
  45. dirtyTerminal();
  46. try {
  47. return await callback({
  48. root,
  49. suspendProgram,
  50. quitProgram
  51. });
  52. } catch (error) {
  53. cleanTerminal();
  54. console.error(error);
  55. process.exit(1);
  56. };
  57. };