summaryrefslogtreecommitdiff
path: root/keyboard.js
diff options
context:
space:
mode:
Diffstat (limited to 'keyboard.js')
-rw-r--r--keyboard.js70
1 files changed, 70 insertions, 0 deletions
diff --git a/keyboard.js b/keyboard.js
new file mode 100644
index 0000000..e1101d8
--- /dev/null
+++ b/keyboard.js
@@ -0,0 +1,70 @@
+module.exports = {};
+
+let inputBuffer = "";
+let initialised = false, haveEOF = false;
+let waitQueue = [];
+
+function stdinDataListener(data) {
+ data = data.toString();
+ inputBuffer += data;
+
+ if (waitQueue.length == 0) return;
+
+ const idx = inputBuffer.indexOf("\n");
+ if (idx == -1) return;
+
+ waitQueue.shift()[0](inputBuffer.slice(0, idx));
+ inputBuffer = inputBuffer.slice(idx + 1);
+}
+
+function stdinEndListener() {
+ haveEOF = true;
+ for (const [resolve, reject] of waitQueue) {
+ reject("End-of-file reached");
+ }
+ waitQueue = [];
+}
+
+function init() {
+ process.stdin.on("data", stdinDataListener);
+ process.stdin.on("end", stdinEndListener);
+ initialised = true;
+}
+module.exports.init = init;
+
+function end() {
+ process.stdin.removeListener("data", stdinDataListener);
+ process.stdin.removeListener("end", stdinEndListener);
+ process.stdin.end();
+}
+module.exports.end = end;
+
+function getline() {
+ return new Promise((resolve, reject) => {
+ if (haveEOF) {
+ reject("End-of-file reached");
+ return;
+ }
+
+ const idx = inputBuffer.indexOf("\n");
+ if (idx != -1) {
+ const line = inputBuffer.slice(0, idx);
+ inputBuffer = inputBuffer.slice(idx + 1);
+ resolve(line);
+ } else {
+ waitQueue.push([resolve, reject]);
+ }
+ });
+}
+module.exports.getline = getline;
+
+async function prompt(str) {
+ process.stdout.write(str);
+ return await getline();
+}
+module.exports.prompt = prompt;
+
+function eof() {
+ return haveEOF;
+}
+module.exports.eof = eof;