Readline
Для использования этого модуля, сделайте require('readline'). Readline позволяет читать поток (например, process.stdin) построчно.
Обратите внимание, что после вызова этого модуля ваша программа Node.js не завершится, пока вы не закроете интерфейс. Вот как можно обеспечить плавное завершение вашей программы:
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('What do you think of Node.js? ', (answer) => {
// TODO: Log the answer in a database
console.log('Thank you for your valuable feedback:', answer);
rl.close();
});
Класс: Интерфейс
Класс, представляющий интерфейс readline с потоком ввода и вывода.
rl.close()
Закрывает экземпляр Interface, освобождая управление потоками input и output. Также будет выброшено событие 'close'.
rl.pause()
Приостанавливает поток readline input, позволяя его возобновить позже, если это необходимо.
Обратите внимание, что это не сразу приостанавливает поток событий. После вызова pause могут быть выброшены несколько событий, включая line.
rl.prompt([preserveCursor])
Подготавливает readline для ввода от пользователя, помещая текущие setPrompt опции на новую строку, предоставляя пользователю новое место для ввода. Установите preserveCursor в true, чтобы предотвратить сброс позиции курсора до 0.
Это также возобновит поток input, используемый с createInterface, если он был приостановлен.
Если output установлено в null или undefined при вызове createInterface, приглашение не выводится.
rl.question(query, callback)
Предваряет запрос query и вызывает callback с ответом пользователя. Отображает запрос пользователю, а затем вызывает callback с ответом пользователя после его ввода.
Это также возобновит поток input используемый с createInterface если он был приостановлен.
Если output установлено в null или undefined при вызове createInterface, ничего не отображается.
Пример использования:
rl.question('What is your favorite food?', (answer) => {
console.log(`Oh, so your favorite food is ${answer}`);
});
rl.resume()
Возобновляет поток readline input.
rl.setPrompt(prompt)
Устанавливает приглашение, например, когда вы запускаете node в командной строке, вы видите >, что является приглашением Node.js.
rl.write(data[, key])
Записывает data в поток output, если output не установлено в null или undefined при вызове createInterface. key — это объект литерал для представления последовательности клавиш; доступен, если терминал является TTY.
Это также возобновит поток input если он был приостановлен.
Пример:
rl.write('Delete me!');
// Simulate ctrl+u to delete the line written previously
rl.write(null, {ctrl: true, name: 'u'});
События
Событие: 'close'
function () {}
Выбрасывается при вызове close().
Также выбрасывается, когда поток input получает событие 'end'. Экземпляр Interface следует считать завершенным после выброса этого события. Например, когда поток input получает ^D, соответственно известное как EOT.
Это событие также вызывается, если обработчик события SIGINT отсутствует, когда поток input получает событие ^C, соответственно известное как SIGINT.
Событие: 'line'
function (line) {}
Выбрасывается всякий раз, когда поток input получает конец строки (\n, \r, или \r\n), обычно получаемое при нажатии пользователем клавиши Enter или Return. Это хорошая точка для прослушивания ввода пользователя.
Пример прослушивания события 'line':
rl.on('line', (cmd) => {
console.log(`You just typed: ${cmd}`);
});
Событие: 'pause'
function () {}
Выбрасывается всякий раз, когда поток input приостанавливается.
Также выбрасывается, когда поток input не приостановлен и получает событие SIGCONT (см. события SIGTSTP и SIGCONT).
Пример прослушивания события 'pause':
rl.on('pause', () => {
console.log('Readline paused.');
});
Событие: 'resume'
function () {}
Выбрасывается всякий раз, когда поток input возобновляется.
Пример прослушивания события 'resume':
rl.on('resume', () => {
console.log('Readline resumed.');
});
Событие: 'SIGCONT'
function () {}
Это не работает в Windows.
Выбрасывается всякий раз, когда поток input отправляется в фоновый режим с ^Z, соответственно известное как SIGTSTP, и затем продолжается с помощью fg(1). Это событие выбрасывается только в том случае, если поток не был приостановлен перед отправкой программы в фоновый режим.
Пример прослушивания события SIGCONT:
rl.on('SIGCONT', () => {
// `prompt` will automatically resume the stream
rl.prompt();
});
Событие: 'SIGINT'
function () {}
Выбрасывается всякий раз, когда поток input получает ^C, соответственно известное как SIGINT. Если обработчик события SIGINT отсутствует, когда поток input получает SIGINT, будет срабатывать pause.
Пример прослушивания события SIGINT:
rl.on('SIGINT', () => {
rl.question('Are you sure you want to exit?', (answer) => {
if (answer.match(/^y(es)?$/i)) rl.pause();
});
});
Событие: 'SIGTSTP'
function () {}
Это не работает в Windows.
Выбрасывается всякий раз, когда поток input получает ^Z, соответственно известное как SIGTSTP. Если обработчик события SIGTSTP отсутствует, когда поток input получает SIGTSTP, программа будет отправлена в фоновый режим.
Когда программа возобновляется с помощью fg, будут выброшены события 'pause' и SIGCONT.
События 'pause' и SIGCONT не будут выброшены, если поток был приостановлен до отправки программы в фоновый режим.
Пример прослушивания события SIGTSTP:
rl.on('SIGTSTP', () => {
// This will override SIGTSTP and prevent the program from going to the
// background.
console.log('Caught SIGTSTP.');
});
Пример: Минимальный CLI
Вот пример того, как использовать все это вместе для создания минимального интерфейса командной строки:
const readline = require('readline');
const rl = readline.createInterface(process.stdin, process.stdout);
rl.setPrompt('OHAI> ');
rl.prompt();
rl.on('line', (line) => {
switch(line.trim()) {
case 'hello':
console.log('world!');
break;
default:
console.log('Say what? I might have heard `' + line.trim() + '`');
break;
}
rl.prompt();
}).on('close', () => {
console.log('Have a great day!');
process.exit(0);
});
Пример: Чтение файла построчно
Распространенный случай использования опции readline input — это передача потока чтения файла. Вот как можно реализовать построчную обработку файла:
const readline = require('readline');
const fs = require('fs');
const rl = readline.createInterface({
input: fs.createReadStream('sample.txt')
});
rl.on('line', (line) => {
console.log('Line from file:', line);
});
Примечание: Метод rl.write() запишет данные в интерфейс readline потока input будто они были введены пользователем.
readline.clearLine(stream, dir)
Очищает текущую строку заданного потока TTY в указанном направлении. dir должно принимать одно из следующих значений:
-
-1— влево от курсора -
1— вправо от курсора -
0— вся строка
readline.clearScreenDown(stream)
Очищает экран от текущей позиции курсора вниз.
readline.createInterface(options)
Создает экземпляр readline Interface. Принимает объект options, который принимает следующие значения:
-
input— читаемый поток для прослушивания (обязательно). -
output— поток для записи данных readline (необязательно). -
completer— необязательная функция, используемая для автозавершения Tab. См. пример ниже. -
terminal— передайтеtrue, если потокиinputиoutputдолжны обрабатываться как TTY и к ним должны записываться коды ANSI/VT100. По умолчанию проверяетсяisTTYв потокеoutputпри инициализации. -
historySize— максимальное количество сохраняемых строк истории. По умолчанию30.
Функция completer получает текущую введенную пользователем строку и должна возвращать массив из 2 элементов:
-
Массив совпадающих элементов для завершения.
-
Подстрока, которая использовалась для сопоставления.
Что в итоге выглядит примерно так: [[substr1, substr2, ...], originalsubstring].
Пример:
function completer(line) {
var completions = '.help .error .exit .quit .q'.split(' ')
var hits = completions.filter((c) => { return c.indexOf(line) == 0 })
// show all completions if none found
return [hits.length ? hits : completions, line]
}
Также completer может быть запущен в асинхронном режиме, если он принимает два аргумента:
function completer(linePartial, callback) {
callback(null, [['123'], linePartial]);
}
createInterface обычно используется с process.stdin и process.stdout для приема ввода пользователя:
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
После получения экземпляра readline вы обычно прослушиваете событие 'line'.
Если terminal равно true для данного экземпляра, то поток output получит наилучшую совместимость, если он определит свойство output.columns, и сгенерирует событие 'resize' в потоке output, если и когда столбцы изменятся (process.stdout делает это автоматически, когда это TTY).
readline.cursorTo(stream, x, y)
Переместить курсор в указанную позицию в заданном потоке TTY.
readline.emitKeypressEvents(stream[, interface])
Заставляет stream начать генерировать события 'keypress' соответствующие его вводу. Опционально, interface указывает экземпляр readline.Interface, для которого автодополнение отключено при обнаружении ввода, скопированного и вставленного.
readline.moveCursor(stream, dx, dy)
Переместить курсор относительно его текущей позиции в заданном потоке TTY.
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v4.x/docs/api/readline.html