Чтение строк
Исходный код: lib/readline.js
Модуль node:readline предоставляет интерфейс для чтения данных из потока Readable (такого как process.stdin) по одной строке за раз.
Для использования API на основе обещаний:
Модули MJS
import * as readline from 'node:readline/promises';
Модули CJS
const readline = require('node:readline/promises'); Для использования API на основе обратных вызовов и синхронного API:
Модули MJS
import * as readline from 'node:readline';
Модули CJS
const readline = require('node:readline'); Следующий простой пример демонстрирует основное использование модуля node:readline.
Модули MJS
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();
Модули CJS
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
- Расширяет: <EventEmitter>
Экземпляры класса InterfaceConstructor создаются с помощью метода readlinePromises.createInterface() или readline.createInterface(). Каждый экземпляр связан с одним потоком input Readable и одним потоком output Writable. Поток output используется для вывода запросов на ввод данных пользователя, которые поступают и считываются из потока input.
Событие: 'close'
Событие 'close' генерируется, когда происходит одно из следующих событий:
- Вызван метод
rl.close(), и экземплярInterfaceConstructorпередал контроль над потокамиinputиoutput; - Поток
inputполучает событие'end'; - Поток
inputполучает Ctrl+D для сигнализации об окончании передачи (EOT); - Поток
inputполучает Ctrl+C для сигнализации обSIGINTи нет обработчика события'SIGINT'зарегистрированного на экземпляреInterfaceConstructor.
Функция-обработчик вызывается без передачи аргументов.
Экземпляр InterfaceConstructor завершается, как только генерируется событие 'close'.
Событие: 'line'
Событие 'line' генерируется всякий раз, когда поток input получает ввод на новой строке (\n, \r, или \r\n). Обычно это происходит, когда пользователь нажимает Enter или Return.
Событие 'line' также генерируется, если из потока были считываемы новые данные, и этот поток завершается без финального маркера новой строки.
Функция-обработчик вызывается со строкой, содержащей единственную строку полученного ввода.
rl.on('line', (input) => {
console.log(`Received: ${input}`);
}); copy Событие: 'history'
Событие 'history' генерируется всякий раз, когда массив истории изменяется.
Функция-обработчик вызывается с массивом, содержащим массив истории. Он будет отражать все изменения, добавленные строки и удаленные строки из-за historySize и removeHistoryDuplicates.
Основная цель — позволить обработчику сохранить историю. Также обработчик может изменить объект истории. Это может быть полезно для предотвращения добавления определенных строк в историю, например, паролей.
rl.on('history', (history) => {
console.log(`Received: ${history}`);
}); copy Событие: 'pause'
Событие 'pause' генерируется, когда происходит одно из следующих событий:
- Поток
inputприостановлен. - Поток
inputне приостановлен и получает событие'SIGCONT'. (См. события'SIGTSTP'и'SIGCONT'.)
Функция-обработчик вызывается без передачи аргументов.
rl.on('pause', () => {
console.log('Readline paused.');
}); copy Событие: 'resume'
Событие 'resume' генерируется всякий раз, когда поток input возобновлен.
Функция-обработчик вызывается без передачи аргументов.
rl.on('resume', () => {
console.log('Readline resumed.');
}); copy Событие: 'SIGCONT'
Событие 'SIGCONT' генерируется, когда процесс Node.js, ранее переведенный в фоновый режим с помощью Ctrl+Z (т.е. SIGTSTP), затем возвращен в фоновый режим с помощью fg(1p).
Если поток input был приостановлен до запроса SIGTSTP, это событие не будет сгенерировано.
Функция-обработчик вызывается без передачи аргументов.
rl.on('SIGCONT', () => {
// `prompt` will automatically resume the stream
rl.prompt();
}); copy Событие 'SIGCONT' не поддерживается в Windows.
Событие: 'SIGINT'
Событие 'SIGINT' генерируется всякий раз, когда поток input получает ввод Ctrl+C, обычно называемый SIGINT. Если нет обработчиков события 'SIGINT' зарегистрированы, когда поток input получает SIGINT, будет сгенерировано событие 'pause'.
Функция-обработчик вызывается без передачи аргументов.
rl.on('SIGINT', () => {
rl.question('Are you sure you want to exit? ', (answer) => {
if (answer.match(/^y(es)?$/i)) rl.pause();
});
}); copy Событие: 'SIGTSTP'
Событие 'SIGTSTP' генерируется, когда поток input получает ввод Ctrl+Z, обычно известный как SIGTSTP. Если нет обработчиков события 'SIGTSTP' зарегистрированы, когда поток input получает SIGTSTP, процесс Node.js будет переведен в фоновый режим.
При возобновлении программы с помощью fg(1p), будут сгенерированы события 'pause' и 'SIGCONT'. Эти события можно использовать для возобновления потока input.
События 'pause' и 'SIGCONT' не будут сгенерированы, если поток input был приостановлен до перевода процесса в фоновый режим.
Функция-обработчик вызывается без передачи аргументов.
rl.on('SIGTSTP', () => {
// This will override SIGTSTP and prevent the program from going to the
// background.
console.log('Caught SIGTSTP.');
}); copy Событие 'SIGTSTP' не поддерживается в Windows.
rl.close()
Метод rl.close() закрывает экземпляр InterfaceConstructor и освобождает контроль над потоками input и output. При вызове генерируется событие 'close'.
Вызов rl.close() не останавливает немедленно другие события (включая 'line'), которые могут генерироваться экземпляром InterfaceConstructor.
rl.pause()
Метод rl.pause() приостанавливает поток input, позволяя его возобновить позже, если необходимо.
Вызов rl.pause() не останавливает немедленно другие события (включая 'line'), которые могут генерироваться экземпляром InterfaceConstructor.
rl.prompt([preserveCursor])
-
preserveCursor<boolean> Еслиtrue, предотвращает сброс позиции курсора до0.
Метод rl.prompt() записывает заданный InterfaceConstructor экземпляром, настроенным на prompt, в новую строку в output, чтобы предоставить пользователю новое место для ввода.
При вызове rl.prompt() возобновит поток input , если он был приостановлен.
Если InterfaceConstructor был создан с output установленным в null или undefined, запрос не выводится.
rl.question(query[, options], callback)
-
query<string> Текст заявления или запроса для вывода вoutput, предваряющий запрос. -
options<Object>-
signal<AbortSignal> Допускает отменуquestion()с помощьюAbortController.
-
-
callback<Function> Функция-обработчик, которая вызывается с вводом пользователя в ответ на запросquery.
Метод rl.question() отображает query, записав его в output, ожидает ввода пользователя в input, затем вызывает функцию callback, передавая полученный ввод в качестве первого аргумента.
При вызове rl.question() возобновит поток input , если он был приостановлен.
Если InterfaceConstructor был создан с 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}`);
}); copy Использование 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); copy
rl.resume()
Метод rl.resume() возобновляет поток input , если он был приостановлен.
rl.setPrompt(prompt)
-
prompt<string>
Метод rl.setPrompt() задаёт запрос, который будет выводиться в output при вызове rl.prompt().
rl.getPrompt()
- Возвращает: <string> текущую строку запроса
Метод rl.getPrompt() возвращает текущий запрос, используемый rl.prompt().
rl.write(data[, key])
-
data<строка> -
key<Объект>-
ctrl<логическое значение>trueдля обозначения клавиши Ctrl. -
meta<логическое значение>trueдля обозначения клавиши Meta. -
shift<логическое значение>trueдля обозначения клавиши Shift. -
name<строка> Имя клавиши.
-
Метод 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' }); copy Метод rl.write() запишет данные в readline Interface input как если бы они были введены пользователем.
rl[Symbol.asyncIterator]()
- Возвращает: <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) {
// Each line in the readline input will be successively available here as
// `line`.
}
} copy readline.createInterface() начнёт потреблять поток ввода сразу после вызова. Наличие асинхронных операций между созданием интерфейса и асинхронной итерацией может привести к пропускам строк.
rl.line
Текущие данные ввода, обрабатываемые узлом.
Это может быть использовано при сборе ввода из потока 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();
}); copy
rl.cursor
Позиция курсора относительно rl.line.
Это отслеживает, куда попадает текущий курсор в строке ввода при чтении ввода из потока TTY. Позиция курсора определяет часть строки ввода, которая будет изменена при обработке ввода, а также столбец, в котором будет отображен курсор терминала.
rl.getCursorPos()
- Возвращает: <Объект>
Возвращает реальную позицию курсора относительно приглашения ввода + строки. В расчёты включаются длинные строки ввода (перенос строк) и приглашения, состоящие из нескольких строк.
API обещаний
Класс: readlinePromises.Interface
- Расширяет: <readline.InterfaceConstructor>
Экземпляры класса readlinePromises.Interface создаются с помощью метода readlinePromises.createInterface(). Каждый экземпляр связан с одним потоком input Readable и одним потоком output Writable. Поток output используется для вывода запросов к пользователю, которые поступают и считываются из потока input.
rl.question(query[, options])
-
query<строка> Заявление или запрос для записи вoutput, добавленный перед запросом. -
options<Объект>-
signal<AbortSignal> Допускает отменуquestion()с помощьюAbortSignal.
-
- Возвращает: <Promise> Обещание, которое выполняется с вводом пользователя в ответ на
query.
Метод rl.question() отображает query, записывая его в output, ожидает ввода пользователя в input, затем вызывает функцию callback, передавая полученный ввод в качестве первого аргумента.
При вызове rl.question() возобновляет поток input если он был приостановлен.
Если readlinePromises.Interface был создан с output установленным в null или undefined, то query не выводится.
Если к вопросу обратиться после rl.close(), то возвращается отклоненное обещание.
Пример использования:
const answer = await rl.question('What is your favorite food? ');
console.log(`Oh, so your favorite food is ${answer}`); copy Использование 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}`); copy Класс: readlinePromises.Readline
new readlinePromises.Readline(stream[, options])
-
stream<stream.Writable> Поток TTY. -
options<Объект>-
autoCommit<логическое> Еслиtrue, нет необходимости вызыватьrl.commit().
-
rl.clearLine(dir)
-
dir<целое>-
-1: влево от курсора -
1: вправо от курсора -
0: вся строка
-
- Возвращает: this
Метод rl.clearLine() добавляет в внутренний список ожидаемых действий действие, которое очищает текущую строку связанного stream в указанном направлении, определённом dir. Вызовите rl.commit() для отображения эффекта этого метода, если autoCommit: true не был передан конструктору.
rl.clearScreenDown()
- Возвращает: this
Метод rl.clearScreenDown() добавляет в внутренний список ожидаемых действий действие, которое очищает связанный поток от текущей позиции курсора вниз. Вызовите rl.commit() для отображения эффекта этого метода, если autoCommit: true не был передан конструктору.
rl.commit()
- Возвращает: <Promise>
Метод rl.commit() отправляет все ожидаемые действия связанному stream и очищает внутренний список ожидаемых действий.
rl.cursorTo(x[, y])
Метод rl.cursorTo() добавляет в внутренний список ожидаемых действий действие, которое перемещает курсор в указанную позицию в связанном stream. Вызовите rl.commit() для отображения эффекта этого метода, если autoCommit: true не был передан конструктору.
rl.moveCursor(dx, dy)
Метод rl.moveCursor() добавляет в внутренний список ожидаемых действий действие, которое перемещает курсор *относительно* его текущей позиции в связанном stream. Вызовите rl.commit() для отображения эффекта этого метода, если autoCommit: true не был передан конструктору.
rl.rollback()
- Возвращает: this
Метод rl.rollback очищает внутренний список ожидаемых действий, не отправляя его связанному stream.
readlinePromises.createInterface(options)
-
options<Объект>-
input<stream.Readable> Поток Readable для прослушивания. Этот параметр обязателен. -
output<stream.Writable> Поток Writable для записи данных readline. -
completer<Функция> Необязательная функция для автодополнения Tab. -
terminal<boolean>trueдолжны лиinputиoutputпотоки обрабатываться как TTY и получать ANSI/VT100 escape-коды. По умолчанию: проверкаisTTYна потокеoutputпри создании. -
history<строковый массив> Начальный список строк истории. Этот параметр имеет смысл только еслиterminalустановлено вtrueпользователем или внутреннимoutputпроверкой, в противном случае механизм кеширования истории не инициализируется. По умолчанию:[]. -
historySize<число> Максимальное количество строк истории, которые сохраняются. Для отключения истории установите это значение в0. Этот параметр имеет смысл только еслиterminalустановлено вtrueпользователем или внутреннимoutputпроверкой, в противном случае механизм кеширования истории не инициализируется. По умолчанию:30. -
removeHistoryDuplicates<boolean> Еслиtrue, когда новая строка ввода добавляется в список истории и дублирует более старую, то старая строка удаляется из списка. По умолчанию:false. -
prompt<строка> Строка приглашения для использования. По умолчанию:'> '. -
crlfDelay<число> Если задержка между\rи\nпревышаетcrlfDelayмиллисекунд,\rи\nбудут обрабатываться как отдельный ввод конца строки.crlfDelayбудет приведено к числу не меньше100. Может быть установлено вInfinity, в этом случае\rи\nвсегда будут считаться одной новой строкой (что может быть целесообразно для чтения файлов с\r\nразделителем строк). По умолчанию:100. -
escapeCodeTimeout<число> ДлительностьreadlinePromisesожидания символа (при чтении неоднозначной последовательности символов в миллисекундах, которая может как сформировать полную последовательность символов, используя прочитанный ввод, так и принять дополнительный ввод для завершения более длинной последовательности символов). По умолчанию:500. -
tabSize<целое число> Количество пробелов, которым равен Tab (минимум 1). По умолчанию:8.
-
- Возвращает: <readlinePromises.Interface>
Метод readlinePromises.createInterface() создает новый экземпляр readlinePromises.Interface.
const readlinePromises = require('node:readline/promises');
const rl = readlinePromises.createInterface({
input: process.stdin,
output: process.stdout,
}); copy После создания экземпляра readlinePromises.Interface наиболее распространенным случаем является прослушивание события 'line':
rl.on('line', (line) => {
console.log(`Received: ${line}`);
}); copy Если 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];
} copy Функция completer также может возвращать <Promise> или быть асинхронной:
async function completer(linePartial) {
await someAsyncWork();
return [['123'], linePartial];
} copy API обратного вызова
Класс: readline.Interface
- Расширяет: <readline.InterfaceConstructor>
Экземпляры класса readline.Interface создаются с помощью метода readline.createInterface(). Каждый экземпляр связан с одним потоком input Readable и одним потоком output Writable. Поток output используется для вывода подсказок для ввода пользователя, которые поступают и считываются из потока input.
rl.question(query[, options], callback)
-
query<строка> Оператор или запрос для записи вoutput, предваряемый подсказкой. -
options<Объект>-
signal<AbortSignal> Позволяет отменитьquestion()с помощьюAbortController.
-
-
callback<Функция> Функция обратного вызова, которая вызывается с вводом пользователя в ответ на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}`);
}); copy Использование 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); copy
readline.clearLine(stream, dir[, callback])
-
stream<stream.Writable> -
dir<число>-
-1: влево от курсора -
1: вправо от курсора -
0: вся строка
-
-
callback<Функция> Вызывается после завершения операции. - Возвращает: <логическое>
falseеслиstreamхочет, чтобы вызывающий код ждал события'drain'перед продолжением записи дополнительных данных; в противном случаеtrue.
Метод readline.clearLine() очищает текущую строку заданного потока TTY в указанном направлении, определенном dir.
readline.clearScreenDown(stream[, callback])
-
stream<stream.Writable> -
callback<Функция> Вызывается после завершения операции. - Возвращает: <логическое>
falseеслиstreamхочет, чтобы вызывающий код ждал события'drain'перед продолжением записи дополнительных данных; в противном случаеtrue.
Метод readline.clearScreenDown() очищает заданный поток TTY снизу от текущей позиции курсора.
readline.createInterface(options)
-
options<Object>-
input<stream.Readable> Поток Readable для прослушивания. Этот параметр обязателен. -
output<stream.Writable> Поток Writable для записи данных readline. -
completer<Function> Необязательная функция для автодополнения. -
terminal<boolean>trueЕсли потокиinputиoutputдолжны обрабатываться как TTY и к ним должны передаваться коды 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() создаёт новый экземпляр
const readline = require('node:readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
}); copy. После создания экземпляра readline.Interface, наиболее распространённый случай – это прослушивание события 'line':
rl.on('line', (line) => {
console.log(`Received: ${line}`);
}); copy Если terminal установлено в true для данного экземпляра, то поток output получит наилучшую совместимость, если он определит свойство output.columns и испустит событие 'resize' в потоке output при изменении количества столбцов (process.stdout автоматически делает это, когда он является TTY).
При создании readline.Interface с stdin в качестве входных данных программа не завершит работу, пока не получит символ конца файла. Чтобы выйти без ожидания пользовательского ввода, вызовите process.stdin.unref().
Использование функции completer
Функция completer принимает текущую введённую пользователем строку в качестве аргумента и возвращает объект Array с двумя элементами:
- Массив
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];
} copy Функция completer может вызываться асинхронно, если она принимает два аргумента:
function completer(linePartial, callback) {
callback(null, [['123'], linePartial]);
} copy
readline.cursorTo(stream, x[, y][, callback])
-
stream<stream.Writable> -
x<number> -
y<number> -
callback<Function> Вызывается по завершении операции. - Возвращает: <boolean>
falseеслиstreamхочет, чтобы вызывающий код ожидал испускания события'drain'перед продолжением записи дополнительных данных; в противном случаеtrue.
Метод readline.cursorTo() перемещает курсор в указанную позицию в заданном TTY stream.
readline.moveCursor(stream, dx, dy[, callback])
-
stream<stream.Writable> -
dx<number> -
dy<number> -
callback<Function> Вызывается по завершении операции. - Возвращает: <boolean>
falseеслиstreamхочет, чтобы вызывающий код ожидал испускания события'drain'перед продолжением записи дополнительных данных; в противном случаеtrue.
Метод readline.moveCursor() перемещает курсор относительно его текущей позиции в заданном TTY stream.
readline.emitKeypressEvents(stream[, interface])
-
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); copy
Пример: Маленький CLI
Следующий пример демонстрирует использование класса readline.Interface для реализации небольшого интерфейса командной строки:
const readline = require('node:readline');
const rl = readline.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);
}); copy Пример: Чтение потока файла построчно
Распространённый случай использования readline — это потребление входного файла по одной строке за раз. Самый простой способ сделать это — использовать API fs.ReadStream и цикл for await...of.
const fs = require('node:fs');
const readline = require('node:readline');
async function processLineByLine() {
const fileStream = fs.createReadStream('input.txt');
const rl = readline.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(); copy В качестве альтернативы можно использовать событие 'line':
const fs = require('node:fs');
const readline = require('node:readline');
const rl = readline.createInterface({
input: fs.createReadStream('sample.txt'),
crlfDelay: Infinity,
});
rl.on('line', (line) => {
console.log(`Line from file: ${line}`);
}); copy В настоящее время цикл for await...of может быть немного медленнее. Если async / await поток и скорость имеют первостепенное значение, можно применить смешанный подход:
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);
}
})(); copy Настройки горячих клавиш для терминала
| Горячие клавиши | Описание | Примечания |
|---|---|---|
| Ctrl+Shift+Backspace | Удалить строку влево | Не работает в Linux, macOS и Windows |
| Ctrl+Shift+Delete | Удалить строку вправо | Не работает в macOS |
| Ctrl+C | Выдать SIGINT или закрыть экземпляр readline | |
| Ctrl+H | Удалить символ влево | |
| Ctrl+D | Удалить символ вправо или закрыть экземпляр readline, если текущая строка пуста/EOF | Не работает в Windows |
| Ctrl+U | Удалить символы от текущей позиции до начала строки | |
| Ctrl+K | Удалить символы от текущей позиции до конца строки | |
| Ctrl+Y | Восстановить (Yank) ранее удалённый текст | Работает только с текстом, удалённым с помощью Ctrl+U или Ctrl+K |
| Meta+Y | Переключаться между ранее удалёнными строками | Доступно только после нажатия Ctrl+Y |
| Ctrl+A | Перейти к началу строки | |
| Ctrl+E | Перейти к концу строки | |
| Ctrl+B | Переместиться на один символ назад | |
| Ctrl+F | Переместиться на один символ вперёд | |
| Ctrl+L | Очистить экран | |
| Ctrl+N | Следующий элемент истории | |
| Ctrl+P | Предыдущий элемент истории | |
| Ctrl+- | Отменить предыдущее изменение | Любая клавиша, которая генерирует код 0x1F, выполнит это действие. В многих терминалах, например, xterm, это привязано к Ctrl+-. |
| Ctrl+6 | Повторить предыдущее изменение | Во многих терминалах нет стандартной клавиши повтора. Мы используем код клавиши 0x1E для повтора. В xterm, по умолчанию он привязан к Ctrl+6. |
| Ctrl+Z | Переводит работающий процесс в фоновый режим. Введите fg и нажмите Enter для возврата. | Не работает в Windows |
| Ctrl+W или Ctrl +Backspace | Удалить слово влево | Ctrl+Backspace Не работает в Linux, macOS и Windows |
| Ctrl+Delete | Удалить слово вправо | Не работает в macOS |
| Ctrl+Left arrow или Meta+B | Слово влево | Ctrl+Left arrow Не работает в macOS |
| Ctrl+Right arrow или Meta+F | Слово вправо | Ctrl+Right arrow Не работает в macOS |
| Meta+D или Meta +Delete | Удалить слово вправо | Meta+Delete Не работает в Windows |
| Meta+Backspace | Удалить слово влево | Не работает в macOS |
© 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-v18.x/docs/api/readline.html