« get me outta code hell

App boilerplate code - tui-lib - Pure Node.js library for making visual command-line programs (ala vim, ncdu)
about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorrie <towerofnix@gmail.com>2019-02-05 20:13:53 -0400
committerFlorrie <towerofnix@gmail.com>2019-02-05 20:13:53 -0400
commitaa38d1beb78635e5273b89b76c6a2b91428dd62c (patch)
treec851c489757fd0a5992573d46b0d2c3b69f13df2
parent6ca4f2e08d323b26940704eca89bdc71b4ed0160 (diff)
App boilerplate code
-rw-r--r--index.js1
-rw-r--r--util/tui-app.js60
2 files changed, 61 insertions, 0 deletions
diff --git a/index.js b/index.js
index cbfc562..de4c680 100644
--- a/index.js
+++ b/index.js
@@ -20,6 +20,7 @@ module.exports = {
     }
   },
   util: {
+    tuiApp: require('./util/tui-app'),
     ansi: require('./util/ansi'),
     CommandLineInterfacer: require('./util/CommandLineInterfacer'),
     count: require('./util/count'),
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);
+    };
+};