clitutor
Version:
Interactive CLI learning tool for beginners
86 lines (72 loc) • 2.14 kB
JavaScript
const chalk = require('chalk');
const readline = require('readline');
function clearScreen() {
process.stdout.write('\x1Bc');
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function printWithTypingEffect(text, delay = 30) {
return new Promise((resolve) => {
let i = 0;
let skipAnimation = false;
// Set up stdin for raw mode to capture single keypresses
if (process.stdin.isTTY) {
process.stdin.setRawMode(true);
process.stdin.resume();
}
// Listen for Enter key
const keypressHandler = (chunk) => {
// Enter key is '\r' or '\n' in raw mode
if (chunk && (chunk.toString() === '\r' || chunk.toString() === '\n')) {
skipAnimation = true;
}
};
process.stdin.on('data', keypressHandler);
const cleanup = () => {
// Remove the keypress listener
process.stdin.removeListener('data', keypressHandler);
// Restore stdin to normal mode
if (process.stdin.isTTY) {
process.stdin.setRawMode(false);
process.stdin.pause();
}
};
const interval = setInterval(() => {
if (skipAnimation && i < text.length) {
// Print remaining text immediately
process.stdout.write(text.substring(i));
clearInterval(interval);
process.stdout.write('\n');
cleanup();
resolve();
} else if (i < text.length) {
process.stdout.write(text[i]);
i++;
} else {
clearInterval(interval);
process.stdout.write('\n');
cleanup();
resolve();
}
}, delay);
});
}
function validateCommand(input, expected, fuzzy = false) {
const normalized = input.trim().toLowerCase();
const expectedNorm = expected.toLowerCase();
if (fuzzy) {
return normalized.includes(expectedNorm) || expectedNorm.includes(normalized);
}
return normalized === expectedNorm;
}
function showHint(hint) {
console.log(chalk.yellow('\n💡 Hint: ') + chalk.dim(hint));
}
module.exports = {
clearScreen,
sleep,
printWithTypingEffect,
validateCommand,
showHint
};