Skip to content

Instantly share code, notes, and snippets.

@thomasballinger
Last active May 30, 2020 21:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomasballinger/e677db598d337c50327444e9a59cb1e5 to your computer and use it in GitHub Desktop.
Save thomasballinger/e677db598d337c50327444e9a59cb1e5 to your computer and use it in GitHub Desktop.
import tty from 'tty'
import { emitKeypressEvents } from 'readline';
let drain;
process.stdout.on('drain', () => { drain() });
const waitForDrain = () => new Promise(r => {drain = r});
function waitForDrainify(func) {
return async (...args) => {
if (!func(...args)) {
await waitForDrain();
}
}
};
const write = waitForDrainify((s) => process.stdout.write(s));
const moveCursor = waitForDrainify((x, y) => process.stdout.moveCursor(x, y));
(async function simpleRepl() {
emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true)
let currentInput = '';
const processInp = async (str, key) => {
await moveCursor(0, 1);
const info = `pressed ${key.name}`
await write(info)
await moveCursor(-info.length, -1)
if (key.name === 'return') {
await write(`\n${currentInput.toUpperCase()}\n> `)
currentInput = ''
} else if (key.name === 'backspace') {
if (currentInput.length) await write('\b \b')
currentInput = currentInput.slice(0, currentInput.length-1);
} else {
currentInput += key.sequence
await write(key.sequence);
}
};
let lastKeyPromise = Promise.resolve();
process.stdin.on('keypress', async (str, key) => {
if(key.sequence === '\u0003') { // this is ctrl-c
process.exit();
}
const prevKeyFinished = lastKeyPromise;
let inputDoneBeingProcessed;
lastKeyPromise = new Promise(r => {inputDoneBeingProcessed = r});
await prevKeyFinished;
await processInp(str, key)
inputDoneBeingProcessed();
});
await write('> ')
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment