Skip to content

Readline

[Stable: 2 - Stable]

Stable: 2 Stability: 2 - Stable

Code source : lib/readline.js

Le module node:readline fournit une interface pour lire les données d'un flux Readable (tel que process.stdin) une ligne à la fois.

Pour utiliser les API basées sur les promesses :

js
import * as readline from 'node:readline/promises'
js
const readline = require('node:readline/promises')

Pour utiliser les API de rappel et synchrones :

js
import * as readline from 'node:readline'
js
const readline = require('node:readline')

L’exemple simple suivant illustre l’utilisation de base du module node:readline.

js
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('Que pensez-vous de Node.js ? ')

console.log(`Merci pour votre précieux avis : ${answer}`)

rl.close()
js
const readline = require('node:readline')
const { stdin: input, stdout: output } = require('node:process')

const rl = readline.createInterface({ input, output })

rl.question('Que pensez-vous de Node.js ? ', answer => {
  // TODO : Enregistrer la réponse dans une base de données
  console.log(`Merci pour votre précieux avis : ${answer}`)

  rl.close()
})

Une fois ce code invoqué, l’application Node.js ne se terminera pas tant que readline.Interface n’est pas fermée, car l’interface attend que des données soient reçues sur le flux input.

Classe : InterfaceConstructor

Ajouté dans : v0.1.104

Les instances de la classe InterfaceConstructor sont construites à l’aide de la méthode readlinePromises.createInterface() ou readline.createInterface(). Chaque instance est associée à un seul flux input Readable et à un seul flux output Writable. Le flux output est utilisé pour afficher les invites pour la saisie utilisateur qui arrive sur le flux input et est lue à partir de celui-ci.

Événement : 'close'

Ajouté dans : v0.1.98

L'événement 'close' est émis lorsqu'une des situations suivantes se produit :

  • La méthode rl.close() est appelée et l'instance InterfaceConstructor a renoncé au contrôle des flux input et output ;
  • Le flux input reçoit son événement 'end' ;
  • Le flux input reçoit Ctrl+D pour signaler la fin de transmission (EOT) ;
  • Le flux input reçoit Ctrl+C pour signaler SIGINT et aucun écouteur d'événement 'SIGINT' n'est enregistré sur l'instance InterfaceConstructor.

La fonction d'écoute est appelée sans transmettre d'arguments.

L'instance InterfaceConstructor est terminée une fois l'événement 'close' émis.

Événement : 'line'

Ajouté dans : v0.1.98

L'événement 'line' est émis chaque fois que le flux input reçoit une entrée de fin de ligne (\n, \r ou \r\n). Cela se produit généralement lorsque l'utilisateur appuie sur Entrée ou Retour.

L'événement 'line' est également émis si de nouvelles données ont été lues à partir d'un flux et que ce flux se termine sans marqueur de fin de ligne final.

La fonction d'écoute est appelée avec une chaîne contenant la seule ligne d'entrée reçue.

js
rl.on('line', input => {
  console.log(`Reçu : ${input}`)
})

Événement : 'history'

Ajouté dans : v15.8.0, v14.18.0

L'événement 'history' est émis chaque fois que le tableau d'historique a changé.

La fonction d'écoute est appelée avec un tableau contenant le tableau d'historique. Il reflétera tous les changements, les lignes ajoutées et les lignes supprimées en raison de historySize et removeHistoryDuplicates.

L'objectif principal est de permettre à un écouteur de conserver l'historique. Il est également possible pour l'écouteur de modifier l'objet d'historique. Cela pourrait être utile pour empêcher l'ajout de certaines lignes à l'historique, comme un mot de passe.

js
rl.on('history', history => {
  console.log(`Reçu : ${history}`)
})

Événement : 'pause'

Ajouté dans : v0.7.5

L'événement 'pause' est émis lorsqu'une des situations suivantes se produit :

  • Le flux input est mis en pause.
  • Le flux input n'est pas mis en pause et reçoit l'événement 'SIGCONT'. (Voir les événements 'SIGTSTP' et 'SIGCONT'.)

La fonction d'écoute est appelée sans transmettre d'arguments.

js
rl.on('pause', () => {
  console.log('Readline en pause.')
})

Événement : 'resume'

Ajouté dans : v0.7.5

L’événement 'resume' est émis chaque fois que le flux input est relancé.

La fonction d’écoute est appelée sans transmettre d’arguments.

js
rl.on('resume', () => {
  console.log('Readline relancé.')
})

Événement : 'SIGCONT'

Ajouté dans : v0.7.5

L’événement 'SIGCONT' est émis lorsqu’un processus Node.js précédemment déplacé en arrière-plan à l’aide de + (c’est-à-dire SIGTSTP) est ensuite ramené au premier plan à l’aide de fg(1p).

Si le flux input était en pause avant la requête SIGTSTP, cet événement ne sera pas émis.

La fonction d’écoute est invoquée sans transmettre d’arguments.

js
rl.on('SIGCONT', () => {
  // `prompt` relancera automatiquement le flux
  rl.prompt()
})

L’événement 'SIGCONT' n’est pas pris en charge sur Windows.

Événement : 'SIGINT'

Ajouté dans : v0.3.0

L’événement 'SIGINT' est émis chaque fois que le flux input reçoit une entrée , généralement appelée SIGINT. S’il n’y a pas d’écouteurs d’événement 'SIGINT' enregistrés lorsque le flux input reçoit un SIGINT, l’événement 'pause' est émis.

La fonction d’écoute est invoquée sans transmettre d’arguments.

js
rl.on('SIGINT', () => {
  rl.question('Êtes-vous sûr de vouloir quitter ? ', answer => {
    if (answer.match(/^y(es)?$/i)) rl.pause()
  })
})

Événement : 'SIGTSTP'

Ajouté dans : v0.7.5

L’événement 'SIGTSTP' est émis lorsque le flux input reçoit une entrée + , généralement appelée SIGTSTP. S’il n’y a pas d’écouteurs d’événement 'SIGTSTP' enregistrés lorsque le flux input reçoit un SIGTSTP, le processus Node.js est envoyé en arrière-plan.

Lorsque le programme est relancé à l’aide de fg(1p), les événements 'pause' et 'SIGCONT' sont émis. Ceux-ci peuvent être utilisés pour relancer le flux input.

Les événements 'pause' et 'SIGCONT' ne seront pas émis si le flux input était en pause avant que le processus ne soit envoyé en arrière-plan.

La fonction d’écoute est invoquée sans transmettre d’arguments.

js
rl.on('SIGTSTP', () => {
  // Cela remplacera SIGTSTP et empêchera le programme de passer à l’arrière-plan.
  console.log('SIGTSTP capturé.')
})

L’événement 'SIGTSTP' n’est pas pris en charge sur Windows.

rl.close()

Ajouté dans la version : v0.1.98

La méthode rl.close() ferme l'instance InterfaceConstructor et renonce au contrôle des flux input et output. Lorsqu'elle est appelée, l'événement 'close' sera émis.

L'appel de rl.close() n'arrête pas immédiatement les autres événements (y compris 'line') d'être émis par l'instance InterfaceConstructor.

rl.pause()

Ajouté dans la version : v0.3.4

La méthode rl.pause() met en pause le flux input, ce qui permet de le reprendre ultérieurement si nécessaire.

L'appel de rl.pause() ne met pas immédiatement en pause les autres événements (y compris 'line') d'être émis par l'instance InterfaceConstructor.

rl.prompt([preserveCursor])

Ajouté dans la version : v0.1.98

  • preserveCursor <boolean> Si true, empêche le positionnement du curseur d'être réinitialisé à 0.

La méthode rl.prompt() écrit l'invite prompt configurée des instances InterfaceConstructor sur une nouvelle ligne dans output afin de fournir à un utilisateur un nouvel emplacement où fournir des saisies.

Lorsqu'elle est appelée, rl.prompt() reprendra le flux input s'il a été mis en pause.

Si l'instance InterfaceConstructor a été créée avec output défini sur null ou undefined, l'invite n'est pas écrite.

rl.resume()

Ajouté dans la version : v0.3.4

La méthode rl.resume() reprend le flux input s'il a été mis en pause.

rl.setPrompt(prompt)

Ajouté dans la version : v0.1.98

La méthode rl.setPrompt() définit l'invite qui sera écrite dans output chaque fois que rl.prompt() est appelée.

rl.getPrompt()

Ajouté dans la version : v15.3.0, v14.17.0

  • Retourne : <string> la chaîne d'invite actuelle

La méthode rl.getPrompt() retourne l'invite actuelle utilisée par rl.prompt().

rl.write(data[, key])

Ajouté dans la version : v0.1.98

La méthode rl.write() écrira soit data, soit une séquence de touches identifiée par key dans output. L'argument key n'est pris en charge que si output est un terminal texte TTY. Consultez Raccourcis clavier TTY pour une liste des combinaisons de touches.

Si key est spécifié, data est ignoré.

Lorsqu'elle est appelée, rl.write() reprendra le flux input s'il a été mis en pause.

Si l'instance InterfaceConstructor a été créée avec output défini sur null ou undefined, les data et key ne sont pas écrits.

js
rl.write('Supprimez ceci !')
// Simuler Ctrl+U pour supprimer la ligne écrite précédemment
rl.write(null, { ctrl: true, name: 'u' })

La méthode rl.write() écrira les données dans l'objet Interface readline input comme si elles étaient fournies par l'utilisateur.

rl[Symbol.asyncIterator]()

[Historique]

VersionModifications
v11.14.0, v10.17.0La prise en charge de Symbol.asyncIterator n'est plus expérimentale.
v11.4.0, v10.16.0Ajoutée dans : v11.4.0, v10.16.0

Crée un objet AsyncIterator qui itère sur chaque ligne du flux d’entrée sous forme de chaîne de caractères. Cette méthode permet l’itération asynchrone d’objets InterfaceConstructor par le biais de boucles for await...of.

Les erreurs dans le flux d’entrée ne sont pas transmises.

Si la boucle est arrêtée par break, throw ou return, rl.close() est appelé. En d’autres termes, l’itération sur un InterfaceConstructor consomme toujours entièrement le flux d’entrée.

Les performances ne sont pas équivalentes à celles de l’API d’événement 'line' traditionnelle. Utilisez plutôt 'line' pour les applications sensibles aux performances.

js
async function processLineByLine() {
  const rl = readline.createInterface({
    // ...
  })

  for await (const line of rl) {
    // Chaque ligne de l’entrée readline sera successivement disponible ici comme
    // `line`.
  }
}

readline.createInterface() commence à consommer le flux d’entrée une fois invoquée. Avoir des opérations asynchrones entre la création de l’interface et l’itération asynchrone peut entraîner des lignes manquées.

rl.line

[Historique]

VersionModifications
v15.8.0, v14.18.0La valeur sera toujours une chaîne de caractères, jamais indéfinie.
v0.1.98Ajoutée dans : v0.1.98

Les données d’entrée actuelles traitées par node.

Ceci peut être utilisé lors de la collecte d’entrées d’un flux TTY afin de récupérer la valeur actuelle qui a été traitée jusqu’à présent, avant que l’événement line ne soit émis. Une fois que l’événement line a été émis, cette propriété sera une chaîne vide.

Sachez que la modification de la valeur pendant l’exécution de l’instance peut avoir des conséquences inattendues si rl.cursor n’est pas également contrôlé.

Si vous n’utilisez pas de flux TTY pour l’entrée, utilisez l’événement 'line'.

Un cas d’utilisation possible serait le suivant :

js
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

Ajouté dans : v0.1.98

Position du curseur par rapport à rl.line.

Cela permettra de suivre où le curseur se trouve dans la chaîne d’entrée lors de la lecture de l’entrée à partir d’un flux TTY. La position du curseur détermine la portion de la chaîne d’entrée qui sera modifiée lors du traitement de l’entrée, ainsi que la colonne où le curseur du terminal sera rendu.

rl.getCursorPos()

Ajouté dans : v13.5.0, v12.16.0

  • Retourne : <Objet>
    • rows <nombre> la ligne de l’invite sur laquelle le curseur se trouve actuellement
    • cols <nombre> la colonne de l’écran sur laquelle le curseur se trouve actuellement

Retourne la position réelle du curseur par rapport à l’invite d’entrée + chaîne. Les longues chaînes d’entrée (enroulement), ainsi que les invites multilignes sont incluses dans les calculs.

API Promises

Ajouté dans : v17.0.0

[Stable : 1 - Expérimental]

Stable : 1 Stabilité : 1 - Expérimental

Classe : readlinePromises.Interface

Ajouté dans : v17.0.0

Les instances de la classe readlinePromises.Interface sont construites à l’aide de la méthode readlinePromises.createInterface(). Chaque instance est associée à un unique flux input Readable et à un unique flux output Writable. Le flux output est utilisé pour imprimer les invites d’entrée utilisateur qui arrivent sur le flux input et qui en sont lues.

rl.question(query[, options])

Ajouté dans : v17.0.0

  • query <string> Une instruction ou une requête à écrire dans output, ajoutée avant l’invite.

  • options <Object>

    • signal <AbortSignal> Permet éventuellement d’annuler question() en utilisant un AbortSignal.
  • Retourne : <Promise> Une promesse qui est remplie avec la saisie de l’utilisateur en réponse à la query.

La méthode rl.question() affiche la query en l’écrivant dans output, attend que la saisie de l’utilisateur soit fournie sur input, puis invoque la fonction callback en passant la saisie fournie comme premier argument.

Lorsqu’elle est appelée, rl.question() reprendra le flux input s’il a été mis en pause.

Si l’readlinePromises.Interface a été créé avec output défini sur null ou undefined, la query n’est pas écrite.

Si la question est appelée après rl.close(), elle retourne une promesse rejetée.

Exemple d’utilisation :

js
const answer = await rl.question('Quelle est votre nourriture préférée ? ')
console.log(`Oh, donc votre nourriture préférée est ${answer}`)

Utilisation d’un AbortSignal pour annuler une question.

js
const signal = AbortSignal.timeout(10_000)

signal.addEventListener(
  'abort',
  () => {
    console.log('La question sur la nourriture a expiré')
  },
  { once: true }
)

const answer = await rl.question('Quelle est votre nourriture préférée ? ', { signal })
console.log(`Oh, donc votre nourriture préférée est ${answer}`)

Class : readlinePromises.Readline

Ajouté dans : v17.0.0

new readlinePromises.Readline(stream[, options])

Ajouté dans : v17.0.0

rl.clearLine(dir)

Ajouté dans : v17.0.0

  • dir <integer>

    • -1 : à gauche du curseur
    • 1 : à droite du curseur
    • 0 : toute la ligne
  • Retourne : this

La méthode rl.clearLine() ajoute à la liste interne des actions en attente une action qui efface la ligne actuelle du stream associé dans une direction spécifiée identifiée par dir. Appelez rl.commit() pour voir l’effet de cette méthode, sauf si autoCommit : true a été transmis au constructeur.

rl.clearScreenDown()

Ajouté dans : v17.0.0

  • Retourne : this

La méthode rl.clearScreenDown() ajoute à la liste interne des actions en attente une action qui efface le stream associé depuis la position actuelle du curseur vers le bas. Appelez rl.commit() pour voir l’effet de cette méthode, sauf si autoCommit : true a été transmis au constructeur.

rl.commit()

Ajouté dans : v17.0.0

La méthode rl.commit() envoie toutes les actions en attente au stream associé et efface la liste interne des actions en attente.

rl.cursorTo(x[, y])

Ajouté dans : v17.0.0

La méthode rl.cursorTo() ajoute à la liste interne des actions en attente une action qui déplace le curseur vers la position spécifiée dans le stream associé. Appelez rl.commit() pour voir l’effet de cette méthode, sauf si autoCommit : true a été transmis au constructeur.

rl.moveCursor(dx, dy)

Ajouté dans : v17.0.0

La méthode rl.moveCursor() ajoute à la liste interne des actions en attente une action qui déplace le curseur par rapport à sa position actuelle dans le stream associé. Appelez rl.commit() pour voir l’effet de cette méthode, sauf si autoCommit : true a été transmis au constructeur.

rl.rollback()

Ajouté dans : v17.0.0

  • Retourne : this

La méthode rl.rollback efface la liste interne des actions en attente sans l’envoyer au stream associé.

readlinePromises.createInterface(options)

Ajouté dans : v17.0.0

  • options <Object>

    • input <stream.Readable> Le flux Readable à écouter. Cette option est obligatoire.
    • output <stream.Writable> Le flux Writable dans lequel écrire les données de lecture de ligne.
    • completer <Function> Une fonction optionnelle utilisée pour l’autocomplétion par tabulation.
    • terminal <boolean> true si les flux input et output doivent être traités comme un TTY et que des codes d’échappement ANSI/VT100 doivent y être écrits. Par défaut : vérification de isTTY sur le flux output lors de l’instanciation.
    • history <string[]> Liste initiale des lignes d’historique. Cette option n’a de sens que si terminal est défini sur true par l’utilisateur ou par une vérification interne de output, sinon le mécanisme de mise en cache de l’historique n’est pas initialisé du tout. Par défaut : [].
    • historySize <number> Nombre maximal de lignes d’historique conservées. Pour désactiver l’historique, définissez cette valeur sur 0. Cette option n’a de sens que si terminal est défini sur true par l’utilisateur ou par une vérification interne de output, sinon le mécanisme de mise en cache de l’historique n’est pas initialisé du tout. Par défaut : 30.
    • removeHistoryDuplicates <boolean> Si true, lorsqu’une nouvelle ligne d’entrée ajoutée à la liste de l’historique duplique une ligne plus ancienne, cela supprime la ligne la plus ancienne de la liste. Par défaut : false.
    • prompt <string> La chaîne d’invite à utiliser. Par défaut : '\> '.
    • crlfDelay <number> Si le délai entre \r et \n dépasse crlfDelay millisecondes, \r et \n seront traités comme des entrées de fin de ligne distinctes. crlfDelay sera contraint à un nombre non inférieur à 100. Il peut être défini sur Infinity, auquel cas \r suivi de \n sera toujours considéré comme un seul saut de ligne (ce qui peut être raisonnable pour la lecture de fichiers avec le délimiteur de ligne \r\n). Par défaut : 100.
    • escapeCodeTimeout <number> La durée pendant laquelle readlinePromises attendra un caractère (lors de la lecture d’une séquence de touches ambiguë en millisecondes, une qui peut à la fois former une séquence de touches complète en utilisant l’entrée lue jusqu’à présent et peut prendre une entrée supplémentaire pour compléter une séquence de touches plus longue). Par défaut : 500.
    • tabSize <integer> Le nombre d’espaces équivalent à une tabulation (minimum 1). Par défaut : 8.
  • Retourne : <readlinePromises.Interface>

La méthode readlinePromises.createInterface() crée une nouvelle instance de readlinePromises.Interface.

js
import { createInterface } from 'node:readline/promises'
import { stdin, stdout } from 'node:process'
const rl = createInterface({
  input: stdin,
  output: stdout,
})
js
const { createInterface } = require('node:readline/promises')
const rl = createInterface({
  input: process.stdin,
  output: process.stdout,
})

Une fois l’instance de readlinePromises.Interface créée, le cas le plus courant est d’écouter l’événement 'line' :

js
rl.on('line', line => {
  console.log(`Reçu : ${line}`)
})

Si terminal est true pour cette instance, alors le flux output obtiendra la meilleure compatibilité s’il définit une propriété output.columns et émet un événement 'resize' sur output si ou quand les colonnes changent ( process.stdout le fait automatiquement lorsqu’il s’agit d’un TTY).

Utilisation de la fonction completer

La fonction completer prend en argument la ligne courante saisie par l'utilisateur et renvoie un Array avec 2 entrées :

  • Un Array avec les entrées correspondantes pour la complétion.
  • La sous-chaîne qui a été utilisée pour la correspondance.

Par exemple : [[substr1, substr2, ...], originalsubstring].

js
function completer(line) {
  const completions = '.help .error .exit .quit .q'.split(' ')
  const hits = completions.filter(c => c.startsWith(line))
  // Afficher toutes les complétions si aucune n'est trouvée
  return [hits.length ? hits : completions, line]
}

La fonction completer peut également renvoyer un <Promise>, ou être asynchrone :

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

API de rappel (Callback)

Ajouté dans : v0.1.104

Classe : readline.Interface

[Historique]

VersionChangements
v17.0.0La classe readline.Interface hérite maintenant de Interface.
v0.1.104Ajouté dans : v0.1.104

Les instances de la classe readline.Interface sont construites à l'aide de la méthode readline.createInterface(). Chaque instance est associée à un seul flux input Readable et à un seul flux output Writable. Le flux output est utilisé pour afficher les invites pour la saisie utilisateur qui arrive sur le flux input et est lue à partir de ce dernier.

rl.question(query[, options], callback)

Ajouté dans : v0.3.3

  • query <string> Une instruction ou une requête à écrire dans output, ajoutée avant l'invite.

  • options <Object>

    • signal <AbortSignal> Permet éventuellement d'annuler la fonction question() à l'aide d'un AbortController.
  • callback <Function> Une fonction de rappel qui est invoquée avec la saisie de l'utilisateur en réponse à la query.

La méthode rl.question() affiche la query en l'écrivant dans output, attend que la saisie utilisateur soit fournie dans input, puis invoque la fonction callback en passant la saisie fournie comme premier argument.

Lorsqu'elle est appelée, rl.question() reprend le flux input s'il a été mis en pause.

Si readline.Interface a été créé avec output défini sur null ou undefined, la query n'est pas écrite.

La fonction callback passée à rl.question() ne suit pas le schéma habituel d'acceptation d'un objet Error ou null comme premier argument. La fonction callback est appelée avec la réponse fournie comme seul argument.

Une erreur sera levée si rl.question() est appelée après rl.close().

Exemple d'utilisation :

js
rl.question('Quel est votre plat préféré ? ', answer => {
  console.log(`Ah, votre plat préféré est donc ${answer}`)
})

Utilisation d'un AbortController pour annuler une question.

js
const ac = new AbortController()
const signal = ac.signal

rl.question('Quel est votre plat préféré ? ', { signal }, answer => {
  console.log(`Ah, votre plat préféré est donc ${answer}`)
})

signal.addEventListener(
  'abort',
  () => {
    console.log('La question du plat a expiré')
  },
  { once: true }
)

setTimeout(() => ac.abort(), 10000)

readline.clearLine(stream, dir[, callback])

[Historique]

VersionModifications
v18.0.0Le passage d'un rappel invalide à l'argument callback lève désormais ERR_INVALID_ARG_TYPE au lieu de ERR_INVALID_CALLBACK.
v12.7.0Le rappel et la valeur de retour de la fonction write() du flux sont exposés.
v0.7.7Ajouté dans la version : v0.7.7
  • stream <stream.Writable>
  • dir <number>
    • -1 : à gauche du curseur
    • 1 : à droite du curseur
    • 0 : la ligne entière
  • callback <Function> Invoqué une fois l'opération terminée.
  • Renvoie : <boolean> false si le stream souhaite que le code appelant attende l'événement 'drain' à être émis avant de continuer à écrire des données supplémentaires ; sinon true.

La méthode readline.clearLine() efface la ligne actuelle du flux TTY donné dans une direction spécifiée identifiée par dir.

readline.clearScreenDown(stream[, callback])

[Historique]

VersionModifications
v18.0.0Le passage d'un rappel invalide à l'argument callback lève désormais ERR_INVALID_ARG_TYPE au lieu de ERR_INVALID_CALLBACK.
v12.7.0Le rappel et la valeur de retour de la fonction write() du flux sont exposés.
v0.7.7Ajouté dans la version : v0.7.7
  • stream <stream.Writable>
  • callback <Function> Invoqué une fois l'opération terminée.
  • Renvoie : <boolean> false si le stream souhaite que le code appelant attende l'événement 'drain' à être émis avant de continuer à écrire des données supplémentaires ; sinon true.

La méthode readline.clearScreenDown() efface le flux TTY donné à partir de la position actuelle du curseur vers le bas.

readline.createInterface(options)

[Historique]

VersionChangements
v15.14.0, v14.18.0L'option signal est désormais prise en charge.
v15.8.0, v14.18.0L'option history est désormais prise en charge.
v13.9.0L'option tabSize est désormais prise en charge.
v8.3.0, v6.11.4Suppression de la limite maximale de l'option crlfDelay.
v6.6.0L'option crlfDelay est désormais prise en charge.
v6.3.0L'option prompt est désormais prise en charge.
v6.0.0L'option historySize peut désormais être 0.
v0.1.98Ajoutée dans : v0.1.98
  • options <Object>

    • input <stream.Readable> Le flux Readable à écouter. Cette option est obligatoire.
    • output <stream.Writable> Le flux Writable vers lequel écrire les données readline.
    • completer <Function> Une fonction optionnelle utilisée pour l'autocomplétion par tabulation.
    • terminal <boolean> true si les flux input et output doivent être traités comme un TTY et que des codes d'échappement ANSI/VT100 doivent y être écrits. Par défaut : vérification de isTTY sur le flux output lors de l'instanciation.
    • history <string[]> Liste initiale des lignes d'historique. Cette option n'a de sens que si terminal est défini sur true par l'utilisateur ou par une vérification interne de output, sinon le mécanisme de mise en cache de l'historique n'est pas du tout initialisé. Par défaut : [].
    • historySize <number> Nombre maximal de lignes d'historique conservées. Pour désactiver l'historique, définissez cette valeur sur 0. Cette option n'a de sens que si terminal est défini sur true par l'utilisateur ou par une vérification interne de output, sinon le mécanisme de mise en cache de l'historique n'est pas du tout initialisé. Par défaut : 30.
    • removeHistoryDuplicates <boolean> Si true, lorsqu'une nouvelle ligne d'entrée ajoutée à la liste d'historique en duplique une plus ancienne, cette ligne plus ancienne est supprimée de la liste. Par défaut : false.
    • prompt <string> La chaîne d'invite à utiliser. Par défaut : '\> '.
    • crlfDelay <number> Si le délai entre \r et \n dépasse crlfDelay millisecondes, \r et \n seront tous deux traités comme une entrée de fin de ligne distincte. crlfDelay sera forcé à un nombre non inférieur à 100. Il peut être défini sur Infinity, auquel cas \r suivi de \n sera toujours considéré comme un seul caractère de nouvelle ligne (ce qui peut être raisonnable pour lire des fichiers avec le délimiteur de ligne \r\n). Par défaut : 100.
    • escapeCodeTimeout <number> La durée pendant laquelle readline attendra un caractère (lors de la lecture d'une séquence de touches ambiguë en millisecondes, une séquence qui peut à la fois former une séquence de touches complète en utilisant l'entrée lue jusqu'à présent et qui peut prendre une entrée supplémentaire pour compléter une séquence de touches plus longue). Par défaut : 500.
    • tabSize <integer> Le nombre d'espaces auquel une tabulation est égale (minimum 1). Par défaut : 8.
    • signal <AbortSignal> Permet de fermer l'interface à l'aide d'un AbortSignal. L'abandon du signal appellera en interne close sur l'interface.
  • Retourne : <readline.Interface>

La méthode readline.createInterface() crée une nouvelle instance de readline.Interface.

js
import { createInterface } from 'node:readline'
import { stdin, stdout } from 'node:process'
const rl = createInterface({
  input: stdin,
  output: stdout,
})
js
const { createInterface } = require('node:readline')
const rl = createInterface({
  input: process.stdin,
  output: process.stdout,
})

Une fois l'instance readline.Interface créée, le cas le plus courant est d'écouter l'événement 'line' :

js
rl.on('line', line => {
  console.log(`Reçu : ${line}`)
})

Si terminal est true pour cette instance, le flux output obtiendra la meilleure compatibilité s'il définit une propriété output.columns et émet un événement 'resize' sur output si ou lorsque les colonnes changent (process.stdout le fait automatiquement lorsqu'il s'agit d'un TTY).

Lors de la création d'un readline.Interface utilisant stdin comme entrée, le programme ne se terminera pas tant qu'il n'aura pas reçu un caractère EOF. Pour quitter sans attendre l'entrée de l'utilisateur, appelez process.stdin.unref().

Utilisation de la fonction completer

La fonction completer prend la ligne actuelle saisie par l'utilisateur comme argument, et retourne un Array avec 2 entrées :

  • Un Array avec les entrées correspondantes pour l'autocomplétion.
  • La sous-chaîne qui a été utilisée pour la correspondance.

Par exemple : [[sous_chaine1, sous_chaine2, ...], sous_chaine_originale].

js
function completer(line) {
  const completions = '.help .error .exit .quit .q'.split(' ')
  const hits = completions.filter(c => c.startsWith(line))
  // Afficher toutes les complétions si aucune n'est trouvée
  return [hits.length ? hits : completions, line]
}

La fonction completer peut être appelée de manière asynchrone si elle accepte deux arguments :

js
function completer(linePartial, callback) {
  callback(null, [['123'], linePartial])
}

readline.cursorTo(stream, x[, y][, callback])

[Historique]

VersionModifications
v18.0.0Le passage d’un rappel non valide à l’argument callback lève maintenant ERR_INVALID_ARG_TYPE au lieu de ERR_INVALID_CALLBACK.
v12.7.0Le rappel et la valeur de retour de stream's write() sont exposés.
v0.7.7Ajouté dans : v0.7.7
  • stream <stream.Writable>
  • x <number>
  • y <number>
  • callback <Function> Invoqué une fois l'opération terminée.
  • Retourne : <boolean> false si stream souhaite que le code appelant attende que l'événement 'drain' soit émis avant de continuer à écrire des données supplémentaires ; sinon true.

La méthode readline.cursorTo() déplace le curseur à la position spécifiée dans un stream TTY donné.

readline.moveCursor(stream, dx, dy[, callback])

[Historique]

VersionModifications
v18.0.0Le passage d’un rappel non valide à l’argument callback lève maintenant ERR_INVALID_ARG_TYPE au lieu de ERR_INVALID_CALLBACK.
v12.7.0Le rappel et la valeur de retour de stream's write() sont exposés.
v0.7.7Ajouté dans : v0.7.7
  • stream <stream.Writable>
  • dx <number>
  • dy <number>
  • callback <Function> Invoqué une fois l'opération terminée.
  • Retourne : <boolean> false si stream souhaite que le code appelant attende que l'événement 'drain' soit émis avant de continuer à écrire des données supplémentaires ; sinon true.

La méthode readline.moveCursor() déplace le curseur relativement à sa position actuelle dans un stream TTY donné.

readline.emitKeypressEvents(stream[, interface])

Ajouté dans : v0.7.7

La méthode readline.emitKeypressEvents() amène le flux Readable donné à commencer à émettre des événements 'keypress' correspondant à l'entrée reçue.

Optionnellement, interface spécifie une instance readline.Interface pour laquelle l'autocomplétion est désactivée quand une entrée copiée-collée est détectée.

Si le stream est un TTY, alors il doit être en mode raw.

Ceci est automatiquement appelé par n'importe quelle instance readline sur son input si le input est un terminal. La fermeture de l'instance readline n'empêche pas le input d'émettre des événements 'keypress'.

js
readline.emitKeypressEvents(process.stdin)
if (process.stdin.isTTY) process.stdin.setRawMode(true)

Exemple : Petite interface en ligne de commande

L'exemple suivant illustre l'utilisation de la classe readline.Interface pour implémenter une petite interface en ligne de commande :

js
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)
})
js
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)
})

Exemple : Lire un flux de fichiers ligne par ligne

Un cas d’utilisation courant pour readline est de consommer un fichier d’entrée une ligne à la fois. La façon la plus simple de procéder consiste à utiliser l’API fs.ReadStream ainsi qu’une boucle for await...of :

js
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,
  })
  // Remarque : nous utilisons l’option crlfDelay pour reconnaître toutes les instances de CR LF
  // ('\r\n') dans input.txt comme un seul saut de ligne.

  for await (const line of rl) {
    // Chaque ligne de input.txt sera successivement disponible ici en tant que `line`.
    console.log(`Ligne du fichier : ${line}`)
  }
}

processLineByLine()
js
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,
  })
  // Remarque : nous utilisons l’option crlfDelay pour reconnaître toutes les instances de CR LF
  // ('\r\n') dans input.txt comme un seul saut de ligne.

  for await (const line of rl) {
    // Chaque ligne de input.txt sera successivement disponible ici en tant que `line`.
    console.log(`Ligne du fichier : ${line}`)
  }
}

processLineByLine()

Une autre solution consiste à utiliser l’événement 'line' :

js
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(`Ligne du fichier : ${line}`)
})
js
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(`Ligne du fichier : ${line}`)
})

Actuellement, la boucle for await...of peut être un peu plus lente. Si le flux async/await et la vitesse sont tous deux essentiels, une approche mixte peut être appliquée :

js
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 => {
      // Traiter la ligne.
    })

    await once(rl, 'close')

    console.log('Fichier traité.')
  } catch (err) {
    console.error(err)
  }
})()
js
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 => {
      // Traiter la ligne.
    })

    await once(rl, 'close')

    console.log('Fichier traité.')
  } catch (err) {
    console.error(err)
  }
})()

Raccourcis clavier TTY

Raccourcis clavierDescriptionNotes
+ +Supprimer la ligne à gaucheNe fonctionne pas sous Linux, Mac et Windows
+ +Supprimer la ligne à droiteNe fonctionne pas sous Mac
+Émettre SIGINT ou fermer l'instance readline
+Supprimer à gauche
+Supprimer à droite ou fermer l'instance readline si la ligne actuelle est vide / EOFNe fonctionne pas sous Windows
+Supprimer de la position actuelle au début de la ligne
+Supprimer de la position actuelle à la fin de la ligne
+Coller (rappeler) le texte précédemment suppriméNe fonctionne qu'avec le texte supprimé par + ou +
+Parcourir les textes précédemment supprimésUniquement disponible lorsque la dernière frappe est + ou +
+Aller au début de la ligne
+Aller à la fin de la ligne
+Reculer d'un caractère
+Avancer d'un caractère
+Effacer l'écran
+Élément suivant de l'historique
+Élément précédent de l'historique
+Annuler la modification précédenteToute frappe qui émet le code de touche 0x1F effectuera cette action. Dans de nombreux terminaux, par exemple xterm , ceci est lié à + .
+Rétablir la modification précédenteDe nombreux terminaux n'ont pas de raccourci clavier par défaut pour rétablir. Nous choisissons le code de touche 0x1E pour effectuer la restauration. Dans xterm , il est lié à + par défaut.
+Déplace le processus en cours d'exécution en arrière-plan. Tapez fg et appuyez sur pour revenir.Ne fonctionne pas sous Windows
+ ou +Supprimer en arrière jusqu'à une limite de mot+ Ne fonctionne pas sous Linux, Mac et Windows
+Supprimer vers l'avant jusqu'à une limite de motNe fonctionne pas sous Mac
+ ou +Mot à gauche+ Ne fonctionne pas sous Mac
+ ou +Mot à droite+ Ne fonctionne pas sous Mac
+ ou +Supprimer le mot à droite+ Ne fonctionne pas sous Windows
+Supprimer le mot à gaucheNe fonctionne pas sous Mac