Readline
[Стабильно: 2 - Стабильно]
Стабильно: 2 Стабильность: 2 - Стабильно
Исходный код: lib/readline.js
Модуль node:readline предоставляет интерфейс для чтения данных из Readable потока (такого как process.stdin) построчно.
Чтобы использовать API, основанные на промисах:
import * as readline from 'node:readline/promises';const readline = require('node:readline/promises');Чтобы использовать API с обратными вызовами и синхронные API:
import * as readline from 'node:readline';const readline = require('node:readline');Следующий простой пример иллюстрирует основное использование модуля node:readline.
import * as readline from 'node:readline/promises';
import { stdin as input, stdout as output } from 'node:process';
const rl = readline.createInterface({ input, output });
const answer = await rl.question('What do you think of Node.js? ');
console.log(`Thank you for your valuable feedback: ${answer}`);
rl.close();const readline = require('node:readline');
const { stdin: input, stdout: output } = require('node:process');
const rl = readline.createInterface({ input, output });
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();
});После вызова этого кода приложение Node.js не завершится, пока readline.Interface не будет закрыт, поскольку интерфейс ожидает получения данных из потока input.
Класс: InterfaceConstructor
Добавлено в версии: v0.1.104
- Расширяет: <EventEmitter>
Экземпляры класса InterfaceConstructor создаются с помощью метода readlinePromises.createInterface() или readline.createInterface(). Каждый экземпляр связан с одним потоком input Readable и одним потоком output Writable. Поток output используется для печати запросов ввода от пользователя, который поступает и считывается из потока input.
Событие: 'close'
Добавлено в версии: v0.1.98
Событие 'close' генерируется при наступлении одного из следующих случаев:
- Вызывается метод
rl.close()и экземплярInterfaceConstructorотказывается от контроля над потокамиinputиoutput; - Поток
inputполучает событие'end'; - Поток
inputполучает + для сигнализации конца передачи (EOT); - Поток
inputполучает + для сигнализацииSIGINTи на экземпляреInterfaceConstructorне зарегистрирован обработчик события'SIGINT'.
Функция-слушатель вызывается без передачи каких-либо аргументов.
Экземпляр InterfaceConstructor завершается после того, как сгенерировано событие 'close'.
Событие: 'line'
Добавлено в версии: v0.1.98
Событие 'line' генерируется всякий раз, когда поток input получает ввод с признаком конца строки (\n, \r или \r\n). Обычно это происходит, когда пользователь нажимает или .
Событие 'line' также генерируется, если из потока были прочитаны новые данные и этот поток завершается без конечного маркера конца строки.
Функция-слушатель вызывается со строкой, содержащей одну строку полученных входных данных.
rl.on('line', (input) => {
console.log(`Получено: ${input}`);
});Событие: 'history'
Добавлено в версии: v15.8.0, v14.18.0
Событие 'history' генерируется всякий раз, когда массив истории был изменен.
Функция-слушатель вызывается с массивом, содержащим массив истории. Он будет отражать все изменения, добавленные строки и удаленные строки из-за historySize и removeHistoryDuplicates.
Основная цель состоит в том, чтобы позволить слушателю сохранять историю. Слушатель также может изменить объект истории. Это может быть полезно для предотвращения добавления определенных строк в историю, например, пароля.
rl.on('history', (history) => {
console.log(`Получено: ${history}`);
});Событие: 'pause'
Добавлено в версии: v0.7.5
Событие 'pause' генерируется при наступлении одного из следующих случаев:
- Поток
inputприостановлен. - Поток
inputне приостановлен и получает событие'SIGCONT'. (См. события'SIGTSTP'и'SIGCONT'.)
Функция-слушатель вызывается без передачи каких-либо аргументов.
rl.on('pause', () => {
console.log('Readline приостановлен.');
});Событие: 'resume'
Добавлено в: v0.7.5
Событие 'resume' возникает всякий раз, когда поток input возобновляется.
Функция-слушатель вызывается без передачи каких-либо аргументов.
rl.on('resume', () => {
console.log('Readline возобновлен.');
});Событие: 'SIGCONT'
Добавлено в: v0.7.5
Событие 'SIGCONT' возникает, когда процесс Node.js, ранее перемещенный в фоновый режим с помощью + (т.е. SIGTSTP), затем возвращается на передний план с помощью fg(1p).
Если поток input был приостановлен до запроса SIGTSTP, это событие не будет сгенерировано.
Функция-слушатель вызывается без передачи каких-либо аргументов.
rl.on('SIGCONT', () => {
// `prompt` автоматически возобновит поток
rl.prompt();
});Событие 'SIGCONT' не поддерживается в Windows.
Событие: 'SIGINT'
Добавлено в: v0.3.0
Событие 'SIGINT' возникает всякий раз, когда поток input получает ввод, обычно известный как SIGINT. Если при получении потоком input сигнала SIGINT не зарегистрировано ни одного слушателя событий 'SIGINT', будет сгенерировано событие 'pause'.
Функция-слушатель вызывается без передачи каких-либо аргументов.
rl.on('SIGINT', () => {
rl.question('Вы уверены, что хотите выйти? ', (answer) => {
if (answer.match(/^y(es)?$/i)) rl.pause();
});
});Событие: 'SIGTSTP'
Добавлено в: v0.7.5
Событие 'SIGTSTP' возникает, когда поток input получает ввод +, обычно известный как SIGTSTP. Если при получении потоком input сигнала SIGTSTP не зарегистрировано ни одного слушателя событий 'SIGTSTP', процесс Node.js будет отправлен в фоновый режим.
Когда программа возобновляется с помощью fg(1p), будут сгенерированы события 'pause' и 'SIGCONT'. Их можно использовать для возобновления потока input.
События 'pause' и 'SIGCONT' не будут сгенерированы, если input был приостановлен до того, как процесс был отправлен в фоновый режим.
Функция-слушатель вызывается без передачи каких-либо аргументов.
rl.on('SIGTSTP', () => {
// Это переопределит SIGTSTP и предотвратит переход программы в
// фоновый режим.
console.log('Пойман SIGTSTP.');
});Событие 'SIGTSTP' не поддерживается в Windows.
rl.close()
Добавлено в: v0.1.98
Метод rl.close() закрывает экземпляр InterfaceConstructor и освобождает контроль над потоками input и output. При вызове будет сгенерировано событие 'close'.
Вызов rl.close() не немедленно останавливает генерацию других событий (включая 'line') экземпляром InterfaceConstructor.
rl.pause()
Добавлено в: v0.3.4
Метод rl.pause() приостанавливает поток input, позволяя возобновить его позже, если это необходимо.
Вызов rl.pause() не немедленно приостанавливает генерацию других событий (включая 'line') экземпляром InterfaceConstructor.
rl.prompt([preserveCursor])
Добавлено в: v0.1.98
preserveCursor<boolean> Еслиtrue, предотвращает сброс позиции курсора на0.
Метод rl.prompt() записывает настроенное свойство prompt экземпляра InterfaceConstructor на новую строку в output, чтобы предоставить пользователю новое место для ввода данных.
При вызове rl.prompt() возобновит поток input, если он был приостановлен.
Если InterfaceConstructor был создан с output, установленным в null или undefined, приглашение не записывается.
rl.resume()
Добавлено в: v0.3.4
Метод rl.resume() возобновляет поток input, если он был приостановлен.
rl.setPrompt(prompt)
Добавлено в: v0.1.98
prompt<string>
Метод rl.setPrompt() устанавливает приглашение, которое будет записано в output при каждом вызове rl.prompt().
rl.getPrompt()
Добавлено в: v15.3.0, v14.17.0
- Возвращает: <string> текущую строку приглашения
Метод rl.getPrompt() возвращает текущее приглашение, используемое rl.prompt().
rl.write(data[, key])
Добавлено в: v0.1.98
Метод rl.write() запишет либо data, либо последовательность клавиш, идентифицируемую по key, в output. Аргумент key поддерживается только в том случае, если output является текстовым терминалом TTY. См. Сочетания клавиш TTY для списка комбинаций клавиш.
Если указан key, то data игнорируется.
При вызове rl.write() возобновит поток input, если он был приостановлен.
Если InterfaceConstructor был создан с output, установленным в null или undefined, то data и key не записываются.
rl.write('Delete this!');
// Simulate Ctrl+U to delete the line written previously
rl.write(null, { ctrl: true, name: 'u' });Метод rl.write() запишет данные в input Interface readline так, как если бы они были предоставлены пользователем.
rl[Symbol.asyncIterator]()
[История]
| Версия | Изменения |
|---|---|
| v11.14.0, v10.17.0 | Поддержка Symbol.asyncIterator больше не является экспериментальной. |
| v11.4.0, v10.16.0 | Добавлено в: v11.4.0, v10.16.0 |
- Возвращает: <AsyncIterator>
Создает объект AsyncIterator, который перебирает каждую строку во входном потоке как строку. Этот метод позволяет асинхронно итерировать объекты InterfaceConstructor через циклы for await...of.
Ошибки во входном потоке не пересылаются.
Если цикл завершается с помощью break, throw или return, будет вызван rl.close(). Другими словами, итерация по InterfaceConstructor всегда будет полностью потреблять входной поток.
Производительность не соответствует традиционному API события 'line'. Используйте 'line' вместо этого для приложений, чувствительных к производительности.
async function processLineByLine() {
const rl = readline.createInterface({
// ...
});
for await (const line of rl) {
// Каждая строка во входных данных readline будет последовательно доступна здесь как
// `line`.
}
}readline.createInterface() начнет потреблять входной поток после вызова. Наличие асинхронных операций между созданием интерфейса и асинхронной итерацией может привести к пропущенным строкам.
rl.line
[История]
| Версия | Изменения |
|---|---|
| v15.8.0, v14.18.0 | Значение всегда будет строкой, никогда не будет неопределенным. |
| v0.1.98 | Добавлено в: v0.1.98 |
Текущие входные данные, обрабатываемые node.
Это можно использовать при сборе ввода из TTY-потока для получения текущего значения, которое было обработано до сих пор, до того, как будет сгенерировано событие line. После того, как событие line было сгенерировано, это свойство будет пустой строкой.
Имейте в виду, что изменение значения во время работы экземпляра может иметь непредвиденные последствия, если rl.cursor также не контролируется.
Если не используется TTY-поток для ввода, используйте 'line' событие.
Один из возможных вариантов использования может быть следующим:
const values = ['lorem ipsum', 'dolor sit amet'];
const rl = readline.createInterface(process.stdin);
const showResults = debounce(() => {
console.log(
'\n',
values.filter((val) => val.startsWith(rl.line)).join(' '),
);
}, 300);
process.stdin.on('keypress', (c, k) => {
showResults();
});rl.cursor
Добавлено в: v0.1.98
Позиция курсора относительно rl.line.
Отслеживает положение текущего курсора в строке ввода при чтении ввода из TTY-потока. Положение курсора определяет часть строки ввода, которая будет изменена при обработке ввода, а также столбец, в котором будет отображаться терминальный курсор.
rl.getCursorPos()
Добавлено в: v13.5.0, v12.16.0
- Возвращает: <Object>
Возвращает реальную позицию курсора относительно приглашения ввода + строки. Длинные строки ввода (с переносом), а также многострочные приглашения включены в расчеты.
Promises API
Добавлено в: v17.0.0
[Stable: 1 - Experimental]
Stable: 1 Stability: 1 - Экспериментальная функция
Класс: readlinePromises.Interface
Добавлено в: v17.0.0
- Расширяет: <readline.InterfaceConstructor>
Экземпляры класса readlinePromises.Interface конструируются с использованием метода readlinePromises.createInterface(). Каждый экземпляр связан с одним потоком input Readable и одним потоком output Writable. Поток output используется для печати приглашений для ввода пользователя, который поступает и считывается из потока input.
rl.question(query[, options])
Добавлено в версии: v17.0.0
query<string> Утверждение или запрос для записи вoutput, добавляемый перед приглашением.options<Object>signal<AbortSignal> При желании позволяет отменитьquestion()с помощьюAbortSignal.
Возвращает: <Promise> Promise, который выполняется с вводом пользователя в ответ на
query.
Метод rl.question() отображает query, записывая его в output, ожидает ввода пользователя в input, затем вызывает функцию callback, передавая предоставленный ввод в качестве первого аргумента.
При вызове rl.question() возобновит поток input, если он был приостановлен.
Если readlinePromises.Interface был создан с output, установленным в null или undefined, то query не записывается.
Если вопрос вызван после rl.close(), он возвращает отклоненный promise.
Пример использования:
const answer = await rl.question('What is your favorite food? ');
console.log(`Oh, so your favorite food is ${answer}`);Использование AbortSignal для отмены вопроса.
const signal = AbortSignal.timeout(10_000);
signal.addEventListener('abort', () => {
console.log('The food question timed out');
}, { once: true });
const answer = await rl.question('What is your favorite food? ', { signal });
console.log(`Oh, so your favorite food is ${answer}`);Класс: readlinePromises.Readline
Добавлено в версии: v17.0.0
new readlinePromises.Readline(stream[, options])
Добавлено в версии: v17.0.0
stream<stream.Writable> Поток TTY.options<Object>autoCommit<boolean> Еслиtrue, нет необходимости вызыватьrl.commit().
rl.clearLine(dir)
Добавлено в: v17.0.0
dir<integer>-1: слева от курсора1: справа от курсора0: вся строка
Возвращает: this
Метод rl.clearLine() добавляет во внутренний список ожидающих действий действие, которое очищает текущую строку связанного stream в указанном направлении, определяемом dir. Вызовите rl.commit(), чтобы увидеть эффект этого метода, если только autoCommit: true не был передан в конструктор.
rl.clearScreenDown()
Добавлено в: v17.0.0
- Возвращает: this
Метод rl.clearScreenDown() добавляет во внутренний список ожидающих действий действие, которое очищает связанный поток от текущей позиции курсора вниз. Вызовите rl.commit(), чтобы увидеть эффект этого метода, если только autoCommit: true не был передан в конструктор.
rl.commit()
Добавлено в: v17.0.0
- Возвращает: <Promise>
Метод rl.commit() отправляет все ожидающие действия связанному stream и очищает внутренний список ожидающих действий.
rl.cursorTo(x[, y])
Добавлено в: v17.0.0
Метод rl.cursorTo() добавляет во внутренний список ожидающих действий действие, которое перемещает курсор в указанную позицию в связанном stream. Вызовите rl.commit(), чтобы увидеть эффект этого метода, если только autoCommit: true не был передан в конструктор.
rl.moveCursor(dx, dy)
Добавлено в: v17.0.0
Метод rl.moveCursor() добавляет во внутренний список ожидающих действий действие, которое перемещает курсор относительно его текущей позиции в связанном stream. Вызовите rl.commit(), чтобы увидеть эффект этого метода, если только autoCommit: true не был передан в конструктор.
rl.rollback()
Добавлено в версии: v17.0.0
- Возвращает: this
Метод rl.rollback очищает внутренний список ожидающих действий, не отправляя его в связанный stream.
readlinePromises.createInterface(options)
Добавлено в версии: v17.0.0
options<Object>input<stream.Readable> Readable поток для прослушивания. Этот параметр обязателен.output<stream.Writable> Writable поток для записи данных readline.completer<Function> Необязательная функция, используемая для автозавершения Tab.terminal<boolean>true, если потокиinputиoutputдолжны рассматриваться как TTY и иметь записанные в них escape-коды ANSI/VT100. По умолчанию: проверкаisTTYв потокеoutputпри создании экземпляра.history<string[]> Начальный список строк истории. Этот параметр имеет смысл, только еслиterminalустановлен вtrueпользователем или внутренней проверкойoutput, в противном случае механизм кэширования истории вообще не инициализируется. По умолчанию:[].historySize<number> Максимальное количество сохраняемых строк истории. Чтобы отключить историю, установите для этого значения0. Этот параметр имеет смысл, только еслиterminalустановлен вtrueпользователем или внутренней проверкойoutput, в противном случае механизм кэширования истории вообще не инициализируется. По умолчанию:30.removeHistoryDuplicates<boolean> Еслиtrue, когда новая строка ввода, добавленная в список истории, дублирует более старую, это удаляет более старую строку из списка. По умолчанию:false.prompt<string> Строка приглашения для использования. По умолчанию:'\> '.crlfDelay<number> Если задержка между\rи\nпревышаетcrlfDelayмиллисекунд, то и\r, и\nбудут рассматриваться как отдельные входные данные конца строки.crlfDelayбудет приведён к числу не менее100. Его можно установить вInfinity, и в этом случае\r, за которым следует\n, всегда будет считаться одним символом новой строки (что может быть разумным для чтения файлов с разделителем строк\r\n). По умолчанию:100.escapeCodeTimeout<number> Продолжительность, в течение которойreadlinePromisesбудет ожидать символ (при чтении неоднозначной последовательности клавиш в миллисекундах, которая может как сформировать полную последовательность клавиш, используя введенные до сих пор данные, так и принять дополнительные входные данные для завершения более длинной последовательности клавиш). По умолчанию:500.tabSize<integer> Количество пробелов, которому равна табуляция (минимум 1). По умолчанию:8.
Возвращает: <readlinePromises.Interface>
Метод readlinePromises.createInterface() создает новый экземпляр readlinePromises.Interface.
import { createInterface } from 'node:readline/promises';
import { stdin, stdout } from 'node:process';
const rl = createInterface({
input: stdin,
output: stdout,
});const { createInterface } = require('node:readline/promises');
const rl = createInterface({
input: process.stdin,
output: process.stdout,
});После создания экземпляра readlinePromises.Interface наиболее распространенным случаем является прослушивание события 'line':
rl.on('line', (line) => {
console.log(`Received: ${line}`);
});Если terminal имеет значение true для этого экземпляра, то поток output получит наилучшую совместимость, если он определяет свойство output.columns и выдает событие 'resize' для output, если или когда столбцы когда-либо изменятся (process.stdout делает это автоматически, когда это TTY).
Использование функции completer
Функция completer принимает текущую строку, введенную пользователем, в качестве аргумента и возвращает Array с 2 элементами:
Arrayс соответствующими записями для завершения.- Подстрока, которая использовалась для сопоставления.
Например: [[substr1, substr2, ...], originalsubstring].
function completer(line) {
const completions = '.help .error .exit .quit .q'.split(' ');
const hits = completions.filter((c) => c.startsWith(line));
// Show all completions if none found
return [hits.length ? hits : completions, line];
}Функция completer также может возвращать <Promise> или быть асинхронной:
async function completer(linePartial) {
await someAsyncWork();
return [['123'], linePartial];
}Callback API
Добавлено в версии: v0.1.104
Класс: readline.Interface
[История]
| Версия | Изменения |
|---|---|
| v17.0.0 | Класс readline.Interface теперь наследуется от Interface. |
| v0.1.104 | Добавлено в версии: v0.1.104 |
- Расширяет: <readline.InterfaceConstructor>
Экземпляры класса readline.Interface конструируются с использованием метода readline.createInterface(). Каждый экземпляр связан с одним input Readable потоком и одним output Writable потоком. output поток используется для печати подсказок для ввода пользователя, который поступает в input поток и считывается из него.
rl.question(query[, options], callback)
Добавлено в версии: v0.3.3
query<string> Утверждение или запрос для записи вoutput, добавляется перед приглашением.options<Object>signal<AbortSignal> При необходимости позволяет отменитьquestion()с помощьюAbortController.
callback<Function> Функция обратного вызова, которая вызывается с пользовательским вводом в ответ наquery.
Метод rl.question() отображает query, записывая его в output, ожидает ввода пользователя в input, а затем вызывает функцию callback, передавая предоставленный ввод в качестве первого аргумента.
При вызове rl.question() возобновит input поток, если он был приостановлен.
Если readline.Interface был создан с output, установленным в null или undefined, query не записывается.
Функция callback, переданная в rl.question(), не соответствует типичной схеме принятия объекта Error или null в качестве первого аргумента. callback вызывается с предоставленным ответом в качестве единственного аргумента.
Будет выброшена ошибка при вызове rl.question() после rl.close().
Пример использования:
rl.question('What is your favorite food? ', (answer) => {
console.log(`Oh, so your favorite food is ${answer}`);
});Использование AbortController для отмены вопроса.
const ac = new AbortController();
const signal = ac.signal;
rl.question('What is your favorite food? ', { signal }, (answer) => {
console.log(`Oh, so your favorite food is ${answer}`);
});
signal.addEventListener('abort', () => {
console.log('The food question timed out');
}, { once: true });
setTimeout(() => ac.abort(), 10000);readline.clearLine(stream, dir[, callback])
[История]
| Версия | Изменения |
|---|---|
| v18.0.0 | Передача недопустимой функции обратного вызова в аргументе callback теперь вызывает ERR_INVALID_ARG_TYPE вместо ERR_INVALID_CALLBACK. |
| v12.7.0 | Функция обратного вызова write() потока и возвращаемое значение предоставляются. |
| v0.7.7 | Добавлено в: v0.7.7 |
stream<stream.Writable>dir<number>-1: слева от курсора1: справа от курсора0: вся строка
callback<Function> Вызывается после завершения операции.Возвращает: <boolean>
false, еслиstreamхочет, чтобы вызывающий код ждал, пока не будет сгенерировано событие'drain', прежде чем продолжить запись дополнительных данных; в противном случаеtrue.
Метод readline.clearLine() очищает текущую строку заданного TTY потока в указанном направлении, определяемом dir.
readline.clearScreenDown(stream[, callback])
[История]
| Версия | Изменения |
|---|---|
| v18.0.0 | Передача недопустимой функции обратного вызова в аргументе callback теперь вызывает ERR_INVALID_ARG_TYPE вместо ERR_INVALID_CALLBACK. |
| v12.7.0 | Функция обратного вызова write() потока и возвращаемое значение предоставляются. |
| v0.7.7 | Добавлено в: v0.7.7 |
stream<stream.Writable>callback<Function> Вызывается после завершения операции.- Возвращает: <boolean>
false, еслиstreamхочет, чтобы вызывающий код ждал, пока не будет сгенерировано событие'drain', прежде чем продолжить запись дополнительных данных; в противном случаеtrue.
Метод readline.clearScreenDown() очищает заданный TTY поток от текущей позиции курсора вниз.
readline.createInterface(options)
[История]
| Версия | Изменения |
|---|---|
| v15.14.0, v14.18.0 | Теперь поддерживается опция signal. |
| v15.8.0, v14.18.0 | Теперь поддерживается опция history. |
| v13.9.0 | Теперь поддерживается опция tabSize. |
| v8.3.0, v6.11.4 | Убрано максимальное ограничение опции crlfDelay. |
| v6.6.0 | Теперь поддерживается опция crlfDelay. |
| v6.3.0 | Теперь поддерживается опция prompt. |
| v6.0.0 | Теперь historySize может быть 0. |
| v0.1.98 | Добавлено в: v0.1.98 |
options<Object>input<stream.Readable> Читаемый поток для прослушивания. Эта опция обязательна.output<stream.Writable> Записываемый поток, в который записываются данные readline.completer<Function> Необязательная функция, используемая для автозаполнения с помощью Tab.terminal<boolean>true, если потокиinputиoutputдолжны рассматриваться как TTY и иметь записанные в них escape-коды ANSI/VT100. По умолчанию: проверкаisTTYв потокеoutputпри создании экземпляра.history<string[]> Начальный список строк истории. Эта опция имеет смысл только в том случае, еслиterminalустановлен вtrueпользователем или внутренней проверкойoutput, в противном случае механизм кэширования истории вообще не инициализируется. По умолчанию:[].historySize<number> Максимальное количество сохраняемых строк истории. Чтобы отключить историю, установите это значение в0. Эта опция имеет смысл только в том случае, еслиterminalустановлен вtrueпользователем или внутренней проверкойoutput, в противном случае механизм кэширования истории вообще не инициализируется. По умолчанию:30.removeHistoryDuplicates<boolean> Еслиtrue, когда новая входная строка, добавленная в список истории, дублирует более старую, она удаляет старую строку из списка. По умолчанию:false.prompt<string> Строка приглашения для использования. По умолчанию:'\> '.crlfDelay<number> Если задержка между\rи\nпревышаетcrlfDelayмиллисекунд, то и\r, и\nбудут рассматриваться как отдельные входные данные конца строки.crlfDelayбудет приведён к числу не менее100. Его можно установить вInfinity, и в этом случае\r, за которым следует\n, всегда будет считаться одним символом новой строки (что может быть разумно для чтения файлов с разделителем строк\r\n). По умолчанию:100.escapeCodeTimeout<number> Продолжительность ожиданияreadlineсимвола (при чтении неоднозначной последовательности клавиш в миллисекундах, которая может как сформировать полную последовательность клавиш, используя прочитанный ввод до сих пор, так и может принимать дополнительный ввод для завершения более длинной последовательности клавиш). По умолчанию:500.tabSize<integer> Количество пробелов, которому равна табуляция (минимум 1). По умолчанию:8.signal<AbortSignal> Позволяет закрыть интерфейс с помощью AbortSignal. Прерывание сигнала внутренне вызоветcloseдля интерфейса.
Возвращает: <readline.Interface>
Метод readline.createInterface() создаёт новый экземпляр readline.Interface.
import { createInterface } from 'node:readline';
import { stdin, stdout } from 'node:process';
const rl = createInterface({
input: stdin,
output: stdout,
});const { createInterface } = require('node:readline');
const rl = createInterface({
input: process.stdin,
output: process.stdout,
});После создания экземпляра readline.Interface наиболее распространенным случаем является прослушивание события 'line':
rl.on('line', (line) => {
console.log(`Получено: ${line}`);
});Если для этого экземпляра terminal имеет значение true, то поток output получит наилучшую совместимость, если он определяет свойство output.columns и генерирует событие 'resize' в output, если или когда столбцы когда-либо изменятся (process.stdout делает это автоматически, когда это TTY).
При создании readline.Interface с использованием stdin в качестве ввода программа не завершится, пока не получит символ EOF. Чтобы выйти, не дожидаясь ввода пользователя, вызовите process.stdin.unref().
Использование функции completer
Функция completer принимает текущую строку, введенную пользователем, в качестве аргумента и возвращает Array с 2 элементами:
Arrayс совпадающими элементами для автозавершения.- Подстроку, которая использовалась для сопоставления.
Например: [[substr1, substr2, ...], originalsubstring].
function completer(line) {
const completions = '.help .error .exit .quit .q'.split(' ');
const hits = completions.filter((c) => c.startsWith(line));
// Show all completions if none found
return [hits.length ? hits : completions, line];
}Функция completer может быть вызвана асинхронно, если она принимает два аргумента:
function completer(linePartial, callback) {
callback(null, [['123'], linePartial]);
}readline.cursorTo(stream, x[, y][, callback])
[История]
| Версия | Изменения |
|---|---|
| v18.0.0 | Передача недействительного обратного вызова в аргумент callback теперь вызывает ERR_INVALID_ARG_TYPE вместо ERR_INVALID_CALLBACK. |
| v12.7.0 | Предоставляется обратный вызов и возвращаемое значение stream.write(). |
| v0.7.7 | Добавлено в: v0.7.7 |
stream<stream.Writable>x<number>y<number>callback<Function> Вызывается после завершения операции.- Возвращает: <boolean>
false, еслиstreamжелает, чтобы вызывающий код подождал, пока не будет сгенерировано событие'drain', прежде чем продолжить запись дополнительных данных; в противном случаеtrue.
Метод readline.cursorTo() перемещает курсор в указанную позицию в данном TTY stream.
readline.moveCursor(stream, dx, dy[, callback])
[История]
| Версия | Изменения |
|---|---|
| v18.0.0 | Передача недействительного обратного вызова в аргумент callback теперь вызывает ERR_INVALID_ARG_TYPE вместо ERR_INVALID_CALLBACK. |
| v12.7.0 | Предоставляется обратный вызов и возвращаемое значение stream.write(). |
| v0.7.7 | Добавлено в: v0.7.7 |
stream<stream.Writable>dx<number>dy<number>callback<Function> Вызывается после завершения операции.- Возвращает: <boolean>
false, еслиstreamжелает, чтобы вызывающий код подождал, пока не будет сгенерировано событие'drain', прежде чем продолжить запись дополнительных данных; в противном случаеtrue.
Метод readline.moveCursor() перемещает курсор относительно его текущей позиции в данном TTY stream.
readline.emitKeypressEvents(stream[, interface])
Добавлено в: v0.7.7
stream<stream.Readable>interface<readline.InterfaceConstructor>
Метод readline.emitKeypressEvents() заставляет заданный Readable поток начать испускать события 'keypress', соответствующие полученным входным данным.
Необязательно, interface указывает экземпляр readline.Interface, для которого автозаполнение отключено при обнаружении скопированных и вставленных входных данных.
Если stream является TTY, то он должен быть в raw режиме.
Это автоматически вызывается любым экземпляром readline для его input, если input является терминалом. Закрытие экземпляра readline не останавливает испускание input событий 'keypress'.
readline.emitKeypressEvents(process.stdin);
if (process.stdin.isTTY)
process.stdin.setRawMode(true);Пример: Tiny CLI
Следующий пример иллюстрирует использование класса readline.Interface для реализации небольшого интерфейса командной строки:
import { createInterface } from 'node:readline';
import { exit, stdin, stdout } from 'node:process';
const rl = createInterface({
input: stdin,
output: stdout,
prompt: '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!');
exit(0);
});const { createInterface } = require('node:readline');
const rl = createInterface({
input: process.stdin,
output: process.stdout,
prompt: '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 - обработка входного файла построчно. Проще всего это сделать, используя API fs.ReadStream, а также цикл for await...of:
import { createReadStream } from 'node:fs';
import { createInterface } from 'node:readline';
async function processLineByLine() {
const fileStream = createReadStream('input.txt');
const rl = createInterface({
input: fileStream,
crlfDelay: Infinity,
});
// Note: we use the crlfDelay option to recognize all instances of CR LF
// ('\r\n') in input.txt as a single line break.
for await (const line of rl) {
// Each line in input.txt will be successively available here as `line`.
console.log(`Line from file: ${line}`);
}
}
processLineByLine();const { createReadStream } = require('node:fs');
const { createInterface } = require('node:readline');
async function processLineByLine() {
const fileStream = createReadStream('input.txt');
const rl = createInterface({
input: fileStream,
crlfDelay: Infinity,
});
// Note: we use the crlfDelay option to recognize all instances of CR LF
// ('\r\n') in input.txt as a single line break.
for await (const line of rl) {
// Each line in input.txt will be successively available here as `line`.
console.log(`Line from file: ${line}`);
}
}
processLineByLine();Альтернативно, можно использовать событие 'line':
import { createReadStream } from 'node:fs';
import { createInterface } from 'node:readline';
const rl = createInterface({
input: createReadStream('sample.txt'),
crlfDelay: Infinity,
});
rl.on('line', (line) => {
console.log(`Line from file: ${line}`);
});const { createReadStream } = require('node:fs');
const { createInterface } = require('node:readline');
const rl = createInterface({
input: createReadStream('sample.txt'),
crlfDelay: Infinity,
});
rl.on('line', (line) => {
console.log(`Line from file: ${line}`);
});В настоящее время цикл for await...of может быть немного медленнее. Если важны как async / await поток, так и скорость, можно применить смешанный подход:
import { once } from 'node:events';
import { createReadStream } from 'node:fs';
import { createInterface } from 'node:readline';
(async function processLineByLine() {
try {
const rl = createInterface({
input: createReadStream('big-file.txt'),
crlfDelay: Infinity,
});
rl.on('line', (line) => {
// Process the line.
});
await once(rl, 'close');
console.log('File processed.');
} catch (err) {
console.error(err);
}
})();const { once } = require('node:events');
const { createReadStream } = require('node:fs');
const { createInterface } = require('node:readline');
(async function processLineByLine() {
try {
const rl = createInterface({
input: createReadStream('big-file.txt'),
crlfDelay: Infinity,
});
rl.on('line', (line) => {
// Process the line.
});
await once(rl, 'close');
console.log('File processed.');
} catch (err) {
console.error(err);
}
})();TTY keybindings
| Keybindings | Description | Notes |
|---|---|---|
| + + | Удалить строку слева | Не работает в Linux, Mac и Windows |
| + + | Удалить строку справа | Не работает в Mac |
| + | Отправить SIGINT или закрыть экземпляр readline | |
| + | Удалить слева | |
| + | Удалить справа или закрыть экземпляр readline, если текущая строка пуста / EOF | Не работает в Windows |
| + | Удалить от текущей позиции до начала строки | |
| + | Удалить от текущей позиции до конца строки | |
| + | Вставить (восстановить) ранее удаленный текст | Работает только с текстом, удаленным с помощью + или + |
| + | Циклически переключаться между ранее удаленными текстами | Доступно только тогда, когда последнее нажатие клавиши было + или + |
| + | Перейти к началу строки | |
| + | Перейти к концу строки | |
| + | Назад на один символ | |
| + | Вперед на один символ | |
| + | Очистить экран | |
| + | Следующий элемент истории | |
| + | Предыдущий элемент истории | |
| + | Отменить предыдущее изменение | Любое нажатие клавиши, которое выдает код клавиши 0x1F, выполнит это действие. Во многих терминалах, например xterm , это привязано к + . |
| + | Повторить предыдущее изменение | Многие терминалы не имеют сочетания клавиш для повтора по умолчанию. Мы выбрали код клавиши 0x1E для выполнения повтора. В xterm , это привязано к + по умолчанию. |
| + | Перемещает запущенный процесс в фоновый режим. Введите fg и нажмите , чтобы вернуться. | Не работает в Windows |
| + или + | Удалить назад до границы слова | + Не работает в Linux, Mac и Windows |
| + | Удалить вперед до границы слова | Не работает в Mac |
| + или + | Слово слева | + Не работает в Mac |
| + или + | Слово справа | + Не работает в Mac |
| + или + | Удалить слово справа | + Не работает в windows |
| + | Удалить слово слева | Не работает в Mac |