« get me outta code hell

tui-lib - Pure Node.js library for making visual command-line programs (ala vim, ncdu)
about summary refs log tree commit diff
path: root/util/tui-app.js
diff options
context:
space:
mode:
Diffstat (limited to 'util/tui-app.js')
-rw-r--r--util/tui-app.js60
1 files changed, 60 insertions, 0 deletions
diff --git a/util/tui-app.js b/util/tui-app.js
new file mode 100644
index 0000000..7ee0480
--- /dev/null
+++ b/util/tui-app.js
@@ -0,0 +1,60 @@
+// General-purpose wrapper code that can be used as the base of a tui-lib
+// program. Contained to reduce boilerplate and improve consistency between
+// programs.
+
+const ansi = require('./ansi');
+
+const CommandLineInterfacer = require('./CommandLineInterfacer');
+const Flushable = require('./Flushable');
+const Root = require('../ui/Root');
+
+module.exports = async function tuiApp(callback) {
+    // TODO: Support other interfacers.
+    const interfacer = new CommandLineInterfacer();
+
+    const flushable = new Flushable(process.stdout, true);
+
+    const root = new Root(interfacer);
+
+    const size = await interfacer.getScreenSize();
+    root.w = size.width;
+    root.h = size.height;
+    flushable.resizeScreen(size);
+
+    interfacer.on('resize', newSize => {
+        root.w = newSize.width;
+        root.h = newSize.height;
+        flushable.resizeScreen(newSize);
+        root.fixAllLayout();
+    });
+
+    const clean = function() {
+        process.stdout.write(ansi.cleanCursor());
+        process.stdout.write(ansi.disableAlternateScreen());
+    };
+
+    const quitProgram = function(status = 0) {
+        clean();
+        process.exit(status);
+    };
+
+    const startRenderLoop = function() {
+        process.stdout.write(ansi.enableAlternateScreen());
+        setInterval(() => {
+            root.renderTo(flushable);
+            flushable.flush();
+        });
+    };
+
+    try {
+        return await callback({
+            root,
+            startRenderLoop,
+            quitProgram
+        });
+    } catch (error) {
+        clean();
+        console.error(error);
+        process.exit(1);
+    };
+};