Spec-Zone.ru › Node.js 24 LTS

Readline

Стабильность: 2 — Стабильный

Исходный код: lib/readline.js

Модуль node:readline предоставляет интерфейс для чтения данных из потока Readable (например, process.stdin) построчно.

Для использования API на основе промисов:

Модули JavaScript
import * as readline from 'node:readline/promises';
CommonJS
const readline = require('node:readline/promises');

Для использования API с обратными вызовами и синхронных API:

Модули JavaScript
import * as readline from 'node:readline';
CommonJS
const readline = require('node:readline');

Следующий простой пример демонстрирует базовое использование модуля node:readline.

Модули JavaScript
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();
CommonJS
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 получает Ctrl+D, сигнализируя о конце передачи данных (EOT);
  • Поток input получает Ctrl+C, сигнализируя о SIGINT, и в экземпляре InterfaceConstructor не зарегистрирован обработчик события 'SIGINT'.

Функция-обработчик вызывается без аргументов.

Работа экземпляра InterfaceConstructor завершается после генерации события 'close'.

Событие: 'error'

Добавлено в: v16.0.0

Событие 'error' генерируется при возникновении ошибки в потоке input, связанном с node:readline Interface.

Функция-обработчик вызывается с объектом Error в качестве единственного аргумента.

Событие: 'line'

Добавлено в: v0.1.98

Событие 'line' генерируется каждый раз, когда поток input получает символ конца строки (\n, \r или \r\n). Обычно это происходит, когда пользователь нажимает Enter или Return.

Событие 'line' также генерируется, если из потока были прочитаны новые данные, а затем поток завершается без конечного символа конца строки.

Функция-обработчик вызывается со строкой, содержащей единственную строку полученных данных.

rl.on('line', (input) => {
  console.log(`Received: ${input}`);
}); copy

Событие: 'history'

Добавлено в: v15.8.0, v14.18.0

Событие 'history' генерируется каждый раз при изменении массива истории.

Функция-обработчик вызывается с массивом, содержащим массив истории. В нем отражаются все изменения: добавленные и удаленные строки, связанные с historySize и removeHistoryDuplicates.

Основное назначение этого события — позволить обработчику сохранять историю. Обработчик также может изменять объект истории. Это может быть полезно, чтобы предотвратить добавление в историю определенных строк, например пароля.

rl.on('history', (history) => {
  console.log(`Received: ${history}`);
}); copy

Событие: 'pause'

Добавлено в: v0.7.5

Событие 'pause' генерируется при наступлении одного из следующих условий:

  • Поток input приостановлен.
  • Поток input не приостановлен и получает событие 'SIGCONT'. (См. события 'SIGTSTP' и 'SIGCONT'.)

Функция-обработчик вызывается без аргументов.

rl.on('pause', () => {
  console.log('Readline paused.');
}); copy

Событие: 'resume'

Добавлено в: v0.7.5

Событие 'resume' генерируется каждый раз при возобновлении потока input.

Функция-обработчик вызывается без аргументов.

rl.on('resume', () => {
  console.log('Readline resumed.');
}); copy

Событие: 'SIGCONT'

Добавлено в: v0.7.5

Событие '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'

Добавлено в: v0.3.0

Событие 'SIGINT' генерируется каждый раз, когда поток input получает сигнал Ctrl+C, обычно называемый SIGINT. Если в момент получения потоком input сигнала SIGINT не зарегистрированы обработчики события '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'

Добавлено в: v0.7.5

Событие 'SIGTSTP' генерируется, когда поток input получает сигнал Ctrl+Z, обычно называемый SIGTSTP. Если в момент получения потоком input сигнала SIGTSTP не зарегистрированы обработчики события '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()

Добавлено в: v0.1.98

Метод rl.close() закрывает экземпляр InterfaceConstructor и освобождает управление потоками input и output. При вызове будет сгенерировано событие 'close'.

Вызов rl.close() немедленно не прекращает генерацию других событий (включая 'line') экземпляром InterfaceConstructor.

rl[Symbol.dispose]()

Добавлено в: v23.10.0, v22.15.0

Псевдоним для rl.close().

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
  • data <string>
  • key <Object>
    • ctrl <boolean> true для обозначения клавиши Ctrl.
    • meta <boolean> true для обозначения клавиши Meta.
    • shift <boolean> true для обозначения клавиши Shift.
    • name <string> Название клавиши.

Метод rl.write() выводит в output либо data, либо последовательность клавиш, определяемую параметром key. Аргумент 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's input, как если бы они были введены пользователем.

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) {
    // Each line in the readline input will be successively available here as
    // `line`.
  }
} copy

readline.createInterface() начнет считывать входной поток после вызова. Асинхронные операции между созданием интерфейса и асинхронным перебором могут привести к пропуску строк.

rl.line

История
Версия Изменения
v15.8.0, v14.18.0

Значение всегда будет строкой, никогда не будет undefined.

v0.1.98

Добавлено в: v0.1.98

  • Тип: <string>

Текущие входные данные, обрабатываемые Node.js.

Это свойство можно использовать при сборе входных данных из потока 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

Добавлено в: v0.1.98
  • Тип: <number> | <undefined>

Положение курсора относительно rl.line.

При чтении входных данных из потока TTY это свойство отслеживает положение текущего курсора во входной строке. Положение курсора определяет часть входной строки, которая будет изменяться по мере обработки входных данных, а также столбец, в котором будет отображаться курсор терминала.

rl.getCursorPos()

Добавлено в: v13.5.0, v12.16.0
  • Возвращает: <Object>
    • rows <number> строка приглашения, на которой сейчас находится курсор
    • cols <number> столбец экрана, на котором сейчас находится курсор

Возвращает фактическое положение курсора относительно строки приглашения и введенной строки. При вычислениях учитываются длинные строки ввода (с переносами), а также многострочные приглашения.

API Promises

История
Версия Изменения
v24.0.0

API объявлен стабильным.

v17.0.0

Добавлено в: v17.0.0

Класс: 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> Промис, который будет выполнен с вводом пользователя в ответ на 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

Добавлено в: 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
  • x <integer>
  • y <integer>
  • Возвращает: this

Метод rl.cursorTo() добавляет во внутренний список ожидающих действий действие, перемещающее курсор в указанную позицию в связанном stream. Вызовите rl.commit(), чтобы увидеть результат работы этого метода, если только при создании объекта не был передан параметр autoCommit: true.

rl.moveCursor(dx, dy)
Добавлено в: v17.0.0
  • dx <integer>
  • dy <integer>
  • Возвращает: this

Метод 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.
    • signal <AbortSignal> Позволяет закрыть интерфейс с помощью AbortSignal.
  • Возвращает: <readlinePromises.Interface>

Метод readlinePromises.createInterface() создаёт новый экземпляр readlinePromises.Interface.

Модули JavaScript
import { createInterface } from 'node:readline/promises';
import { stdin, stdout } from 'node:process';
const rl = createInterface({
  input: stdin,
  output: stdout,
});
CommonJS
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}`);
}); copy

Если для этого экземпляра terminal равно true, поток output будет наиболее совместимым, если в нём определено свойство output.columns и генерируется событие 'resize' в output при изменении количества столбцов (это происходит автоматически с process.stdout, когда он является TTY).

Использование функции 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 также может возвращать <Promise> или быть асинхронной:

async function completer(linePartial) {
  await someAsyncWork();
  return [['123'], linePartial];
} copy

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}`);
}); 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])

История
Версия Изменения
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> Поток Readable, за которым нужно следить. Этот параметр обязателен.
    • output <stream.Writable> Поток Writable, в который записываются данные readline.
    • completer <Function> Необязательная функция для автодополнения по клавише Tab.
    • terminal <boolean> true, если потоки input и output должны обрабатываться как TTY, а в них должны записываться управляющие последовательности ANSI/VT100. По умолчанию: проверка isTTY в потоке output при создании экземпляра.
    • history <string[]> Начальный список строк истории. Этот параметр имеет смысл только в том случае, если пользователь или внутренняя проверка output установили terminal в true; в противном случае механизм кэширования истории вообще не инициализируется. По умолчанию: [].
    • historySize <number> Максимальное число сохраняемых строк истории. Чтобы отключить историю, установите это значение в 0. Этот параметр имеет смысл только в том случае, если пользователь или внутренняя проверка output установили terminal в true; в противном случае механизм кэширования истории вообще не инициализируется. По умолчанию: 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.

Модули JavaScript
import { createInterface } from 'node:readline';
import { stdin, stdout } from 'node:process';
const rl = createInterface({
  input: stdin,
  output: stdout,
});
CommonJS
const { createInterface } = require('node:readline');
const rl = createInterface({
  input: process.stdin,
  output: process.stdout,
});

После создания экземпляра readline.Interface в большинстве случаев нужно прослушивать событие 'line':

rl.on('line', (line) => {
  console.log(`Received: ${line}`);
}); copy

Если для этого экземпляра terminal имеет значение true, то поток output будет наиболее совместимым, если в нём определено свойство output.columns и при изменении числа столбцов для output будет генерироваться событие 'resize' (ссылка process.stdout делает это автоматически, если она является TTY).

При создании readline.Interface с использованием stdin в качестве входных данных программа не завершится, пока не получит символ EOF. Чтобы выйти, не дожидаясь ввода пользователя, вызовите 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])

История
Версия Изменения
v18.0.0

Передача недопустимой функции обратного вызова в аргумент callback теперь вызывает ошибку ERR_INVALID_ARG_TYPE вместо ERR_INVALID_CALLBACK.

v12.7.0

Стали доступны функция обратного вызова 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

Стали доступны функция обратного вызова 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, он должен работать в необработанном режиме.

Этот метод автоматически вызывается любым экземпляром readline для его input, если input является терминалом. Закрытие экземпляра readline не прекращает генерацию событий 'keypress' потоком input.

readline.emitKeypressEvents(process.stdin);
if (process.stdin.isTTY)
  process.stdin.setRawMode(true); copy

Пример: небольшая CLI

В следующем примере показано использование класса readline.Interface для реализации небольшого интерфейса командной строки:

Модули JavaScript
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);
});
CommonJS
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:

Модули JavaScript
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();
CommonJS
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':

Модули JavaScript
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}`);
});
CommonJS
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, и скорость, можно применить смешанный подход:

Модули JavaScript
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);
  }
})();
CommonJS
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

Сочетания клавиш Описание Примечания
Ctrl+Shift+Backspace Удалить строку слева Не работает в Linux, Mac и Windows
Ctrl+Shift+Delete Удалить строку справа Не работает в Mac
Ctrl+C Сгенерировать SIGINT или закрыть экземпляр readline
Ctrl+H Удалить символ слева
Ctrl+D Удалить символ справа или закрыть экземпляр readline, если текущая строка пуста или достигнут EOF Не работает в Windows
Ctrl+U Удалить текст от текущего положения до начала строки
Ctrl+K Удалить текст от текущего положения до конца строки
Ctrl+Y Вставить (восстановить) ранее удалённый текст Работает только с текстом, удалённым с помощью Ctrl+U или Ctrl+K
Meta+Y Перебирать ранее удалённые фрагменты текста Доступно, только если последнее нажатие клавиши — Ctrl+Y или Meta+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, Mac и Windows
Ctrl+Delete Удалить текст вперёд до границы слова Не работает в Mac
Ctrl+Left arrow или Meta+B Перейти на слово влево Ctrl+Left arrow Не работает в Mac
Ctrl+Right arrow или Meta+F Перейти на слово вправо Ctrl+Right arrow Не работает в Mac
Meta+D или Meta +Delete Удалить слово справа Meta+Delete Не работает в Windows
Meta+Backspace Удалить слово слева Не работает в Mac

© 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-v24.x/docs/api/readline.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API