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 :
import * as readline from 'node:readline/promises'
const readline = require('node:readline/promises')
Pour utiliser les API de rappel et synchrones :
import * as readline from 'node:readline'
const readline = require('node:readline')
L’exemple simple suivant illustre l’utilisation de base du module node:readline
.
import * as readline from 'node:readline/promises'
import { stdin as input, stdout as output } from 'node:process'
const rl = readline.createInterface({ input, output })
const answer = await rl.question('Que pensez-vous de Node.js ? ')
console.log(`Merci pour votre précieux avis : ${answer}`)
rl.close()
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
- Hérite : <EventEmitter>
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'instanceInterfaceConstructor
a renoncé au contrôle des fluxinput
etoutput
; - 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 signalerSIGINT
et aucun écouteur d'événement'SIGINT'
n'est enregistré sur l'instanceInterfaceConstructor
.
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.
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.
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.
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.
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.
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.
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.
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> Sitrue
, 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
prompt
<string>
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.
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]
Version | Modifications |
---|---|
v11.14.0, v10.17.0 | La prise en charge de Symbol.asyncIterator n'est plus expérimentale. |
v11.4.0, v10.16.0 | Ajoutée dans : v11.4.0, v10.16.0 |
- Retourne : <AsyncIterator>
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.
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]
Version | Modifications |
---|---|
v15.8.0, v14.18.0 | La valeur sera toujours une chaîne de caractères, jamais indéfinie. |
v0.1.98 | Ajouté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 :
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>
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
- Étend : <readline.InterfaceConstructor>
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 dansoutput
, ajoutée avant l’invite.options
<Object>signal
<AbortSignal> Permet éventuellement d’annulerquestion()
en utilisant unAbortSignal
.
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 :
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.
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
stream
<stream.Writable> Un flux TTY.options
<Object>autoCommit
<boolean> Si la valeur esttrue
, il n’est pas nécessaire d’appelerrl.commit()
.
rl.clearLine(dir)
Ajouté dans : v17.0.0
dir
<integer>-1
: à gauche du curseur1
: à droite du curseur0
: 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
- Retourne : <Promise>
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 fluxinput
etoutput
doivent être traités comme un TTY et que des codes d’échappement ANSI/VT100 doivent y être écrits. Par défaut : vérification deisTTY
sur le fluxoutput
lors de l’instanciation.history
<string[]> Liste initiale des lignes d’historique. Cette option n’a de sens que siterminal
est défini surtrue
par l’utilisateur ou par une vérification interne deoutput
, 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 sur0
. Cette option n’a de sens que siterminal
est défini surtrue
par l’utilisateur ou par une vérification interne deoutput
, sinon le mécanisme de mise en cache de l’historique n’est pas initialisé du tout. Par défaut :30
.removeHistoryDuplicates
<boolean> Sitrue
, 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épassecrlfDelay
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 surInfinity
, 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 laquellereadlinePromises
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
.
import { createInterface } from 'node:readline/promises'
import { stdin, stdout } from 'node:process'
const rl = createInterface({
input: stdin,
output: stdout,
})
const { createInterface } = require('node:readline/promises')
const rl = createInterface({
input: process.stdin,
output: process.stdout,
})
Une fois l’instance de readlinePromises.Interface
créée, le cas le plus courant est d’écouter l’événement 'line'
:
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]
.
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 :
async function completer(linePartial) {
await someAsyncWork()
return [['123'], linePartial]
}
API de rappel (Callback)
Ajouté dans : v0.1.104
Classe : readline.Interface
[Historique]
Version | Changements |
---|---|
v17.0.0 | La classe readline.Interface hérite maintenant de Interface . |
v0.1.104 | Ajouté dans : v0.1.104 |
- Hérite de : <readline.InterfaceConstructor>
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 dansoutput
, ajoutée avant l'invite.options
<Object>signal
<AbortSignal> Permet éventuellement d'annuler la fonctionquestion()
à l'aide d'unAbortController
.
callback
<Function> Une fonction de rappel qui est invoquée avec la saisie de l'utilisateur en réponse à laquery
.
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 :
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.
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]
Version | Modifications |
---|---|
v18.0.0 | Le passage d'un rappel invalide à l'argument callback lève désormais ERR_INVALID_ARG_TYPE au lieu de ERR_INVALID_CALLBACK . |
v12.7.0 | Le rappel et la valeur de retour de la fonction write() du flux sont exposés. |
v0.7.7 | Ajouté dans la version : v0.7.7 |
stream
<stream.Writable>dir
<number>-1
: à gauche du curseur1
: à droite du curseur0
: la ligne entière
callback
<Function> Invoqué une fois l'opération terminée.- Renvoie : <boolean>
false
si lestream
souhaite que le code appelant attende l'événement'drain'
à être émis avant de continuer à écrire des données supplémentaires ; sinontrue
.
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]
Version | Modifications |
---|---|
v18.0.0 | Le passage d'un rappel invalide à l'argument callback lève désormais ERR_INVALID_ARG_TYPE au lieu de ERR_INVALID_CALLBACK . |
v12.7.0 | Le rappel et la valeur de retour de la fonction write() du flux sont exposés. |
v0.7.7 | Ajouté dans la version : v0.7.7 |
stream
<stream.Writable>callback
<Function> Invoqué une fois l'opération terminée.- Renvoie : <boolean>
false
si lestream
souhaite que le code appelant attende l'événement'drain'
à être émis avant de continuer à écrire des données supplémentaires ; sinontrue
.
La méthode readline.clearScreenDown()
efface le flux TTY donné à partir de la position actuelle du curseur vers le bas.
readline.createInterface(options)
[Historique]
Version | Changements |
---|---|
v15.14.0, v14.18.0 | L'option signal est désormais prise en charge. |
v15.8.0, v14.18.0 | L'option history est désormais prise en charge. |
v13.9.0 | L'option tabSize est désormais prise en charge. |
v8.3.0, v6.11.4 | Suppression de la limite maximale de l'option crlfDelay . |
v6.6.0 | L'option crlfDelay est désormais prise en charge. |
v6.3.0 | L'option prompt est désormais prise en charge. |
v6.0.0 | L'option historySize peut désormais être 0 . |
v0.1.98 | Ajouté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 fluxinput
etoutput
doivent être traités comme un TTY et que des codes d'échappement ANSI/VT100 doivent y être écrits. Par défaut : vérification deisTTY
sur le fluxoutput
lors de l'instanciation.history
<string[]> Liste initiale des lignes d'historique. Cette option n'a de sens que siterminal
est défini surtrue
par l'utilisateur ou par une vérification interne deoutput
, 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 sur0
. Cette option n'a de sens que siterminal
est défini surtrue
par l'utilisateur ou par une vérification interne deoutput
, sinon le mécanisme de mise en cache de l'historique n'est pas du tout initialisé. Par défaut :30
.removeHistoryDuplicates
<boolean> Sitrue
, 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épassecrlfDelay
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 surInfinity
, 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 laquellereadline
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 interneclose
sur l'interface.
Retourne : <readline.Interface>
La méthode readline.createInterface()
crée une nouvelle instance de readline.Interface
.
import { createInterface } from 'node:readline'
import { stdin, stdout } from 'node:process'
const rl = createInterface({
input: stdin,
output: stdout,
})
const { createInterface } = require('node:readline')
const rl = createInterface({
input: process.stdin,
output: process.stdout,
})
Une fois l'instance readline.Interface
créée, le cas le plus courant est d'écouter l'événement 'line'
:
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]
.
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 :
function completer(linePartial, callback) {
callback(null, [['123'], linePartial])
}
readline.cursorTo(stream, x[, y][, callback])
[Historique]
Version | Modifications |
---|---|
v18.0.0 | Le passage d’un rappel non valide à l’argument callback lève maintenant ERR_INVALID_ARG_TYPE au lieu de ERR_INVALID_CALLBACK . |
v12.7.0 | Le rappel et la valeur de retour de stream's write() sont exposés. |
v0.7.7 | Ajouté dans : v0.7.7 |
stream
<stream.Writable>x
<number>y
<number>callback
<Function> Invoqué une fois l'opération terminée.- Retourne : <boolean>
false
sistream
souhaite que le code appelant attende que l'événement'drain'
soit émis avant de continuer à écrire des données supplémentaires ; sinontrue
.
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]
Version | Modifications |
---|---|
v18.0.0 | Le passage d’un rappel non valide à l’argument callback lève maintenant ERR_INVALID_ARG_TYPE au lieu de ERR_INVALID_CALLBACK . |
v12.7.0 | Le rappel et la valeur de retour de stream's write() sont exposés. |
v0.7.7 | Ajouté dans : v0.7.7 |
stream
<stream.Writable>dx
<number>dy
<number>callback
<Function> Invoqué une fois l'opération terminée.- Retourne : <boolean>
false
sistream
souhaite que le code appelant attende que l'événement'drain'
soit émis avant de continuer à écrire des données supplémentaires ; sinontrue
.
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
stream
<stream.Readable>interface
<readline.InterfaceConstructor>
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'
.
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 :
import { createInterface } from 'node:readline'
import { exit, stdin, stdout } from 'node:process'
const rl = createInterface({
input: stdin,
output: stdout,
prompt: 'OHAI> ',
})
rl.prompt()
rl.on('line', line => {
switch (line.trim()) {
case 'hello':
console.log('world!')
break
default:
console.log(`Say what? I might have heard '${line.trim()}'`)
break
}
rl.prompt()
}).on('close', () => {
console.log('Have a great day!')
exit(0)
})
const { createInterface } = require('node:readline')
const rl = createInterface({
input: process.stdin,
output: process.stdout,
prompt: 'OHAI> ',
})
rl.prompt()
rl.on('line', line => {
switch (line.trim()) {
case 'hello':
console.log('world!')
break
default:
console.log(`Say what? I might have heard '${line.trim()}'`)
break
}
rl.prompt()
}).on('close', () => {
console.log('Have a great day!')
process.exit(0)
})
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
:
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()
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'
:
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}`)
})
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 :
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)
}
})()
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 clavier | Description | Notes |
---|---|---|
+ + | Supprimer la ligne à gauche | Ne fonctionne pas sous Linux, Mac et Windows |
+ + | Supprimer la ligne à droite | Ne 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 / EOF | Ne 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és | Uniquement 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édente | Toute 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édente | De 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 mot | Ne 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 à gauche | Ne fonctionne pas sous Mac |