1# Readline 2 3<!--introduced_in=v0.10.0--> 4 5> Stability: 2 - Stable 6 7<!-- source_link=lib/readline.js --> 8 9The `readline` module provides an interface for reading data from a [Readable][] 10stream (such as [`process.stdin`][]) one line at a time. It can be accessed 11using: 12 13```js 14const readline = require('readline'); 15``` 16 17The following simple example illustrates the basic use of the `readline` module. 18 19```js 20const readline = require('readline'); 21 22const rl = readline.createInterface({ 23 input: process.stdin, 24 output: process.stdout 25}); 26 27rl.question('What do you think of Node.js? ', (answer) => { 28 // TODO: Log the answer in a database 29 console.log(`Thank you for your valuable feedback: ${answer}`); 30 31 rl.close(); 32}); 33``` 34 35Once this code is invoked, the Node.js application will not terminate until the 36`readline.Interface` is closed because the interface waits for data to be 37received on the `input` stream. 38 39## Class: `Interface` 40<!-- YAML 41added: v0.1.104 42--> 43 44* Extends: {EventEmitter} 45 46Instances of the `readline.Interface` class are constructed using the 47`readline.createInterface()` method. Every instance is associated with a 48single `input` [Readable][] stream and a single `output` [Writable][] stream. 49The `output` stream is used to print prompts for user input that arrives on, 50and is read from, the `input` stream. 51 52### Event: `'close'` 53<!-- YAML 54added: v0.1.98 55--> 56 57The `'close'` event is emitted when one of the following occur: 58 59* The `rl.close()` method is called and the `readline.Interface` instance has 60 relinquished control over the `input` and `output` streams; 61* The `input` stream receives its `'end'` event; 62* The `input` stream receives <kbd>Ctrl</kbd>+<kbd>D</kbd> to signal 63 end-of-transmission (EOT); 64* The `input` stream receives <kbd>Ctrl</kbd>+<kbd>C</kbd> to signal `SIGINT` 65 and there is no `'SIGINT'` event listener registered on the 66 `readline.Interface` instance. 67 68The listener function is called without passing any arguments. 69 70The `readline.Interface` instance is finished once the `'close'` event is 71emitted. 72 73### Event: `'line'` 74<!-- YAML 75added: v0.1.98 76--> 77 78The `'line'` event is emitted whenever the `input` stream receives an 79end-of-line input (`\n`, `\r`, or `\r\n`). This usually occurs when the user 80presses <kbd>Enter</kbd> or <kbd>Return</kbd>. 81 82The listener function is called with a string containing the single line of 83received input. 84 85```js 86rl.on('line', (input) => { 87 console.log(`Received: ${input}`); 88}); 89``` 90 91### Event: `'history'` 92<!-- YAML 93added: v14.18.0 94--> 95 96The `'history'` event is emitted whenever the history array has changed. 97 98The listener function is called with an array containing the history array. 99It will reflect all changes, added lines and removed lines due to 100`historySize` and `removeHistoryDuplicates`. 101 102The primary purpose is to allow a listener to persist the history. 103It is also possible for the listener to change the history object. This 104could be useful to prevent certain lines to be added to the history, like 105a password. 106 107```js 108rl.on('history', (history) => { 109 console.log(`Received: ${history}`); 110}); 111``` 112 113### Event: `'pause'` 114<!-- YAML 115added: v0.7.5 116--> 117 118The `'pause'` event is emitted when one of the following occur: 119 120* The `input` stream is paused. 121* The `input` stream is not paused and receives the `'SIGCONT'` event. (See 122 events [`'SIGTSTP'`][] and [`'SIGCONT'`][].) 123 124The listener function is called without passing any arguments. 125 126```js 127rl.on('pause', () => { 128 console.log('Readline paused.'); 129}); 130``` 131 132### Event: `'resume'` 133<!-- YAML 134added: v0.7.5 135--> 136 137The `'resume'` event is emitted whenever the `input` stream is resumed. 138 139The listener function is called without passing any arguments. 140 141```js 142rl.on('resume', () => { 143 console.log('Readline resumed.'); 144}); 145``` 146 147### Event: `'SIGCONT'` 148<!-- YAML 149added: v0.7.5 150--> 151 152The `'SIGCONT'` event is emitted when a Node.js process previously moved into 153the background using <kbd>Ctrl</kbd>+<kbd>Z</kbd> (i.e. `SIGTSTP`) is then 154brought back to the foreground using fg(1p). 155 156If the `input` stream was paused *before* the `SIGTSTP` request, this event will 157not be emitted. 158 159The listener function is invoked without passing any arguments. 160 161```js 162rl.on('SIGCONT', () => { 163 // `prompt` will automatically resume the stream 164 rl.prompt(); 165}); 166``` 167 168The `'SIGCONT'` event is _not_ supported on Windows. 169 170### Event: `'SIGINT'` 171<!-- YAML 172added: v0.3.0 173--> 174 175The `'SIGINT'` event is emitted whenever the `input` stream receives a 176<kbd>Ctrl+C</kbd> input, known typically as `SIGINT`. If there are no `'SIGINT'` 177event listeners registered when the `input` stream receives a `SIGINT`, the 178`'pause'` event will be emitted. 179 180The listener function is invoked without passing any arguments. 181 182```js 183rl.on('SIGINT', () => { 184 rl.question('Are you sure you want to exit? ', (answer) => { 185 if (answer.match(/^y(es)?$/i)) rl.pause(); 186 }); 187}); 188``` 189 190### Event: `'SIGTSTP'` 191<!-- YAML 192added: v0.7.5 193--> 194 195The `'SIGTSTP'` event is emitted when the `input` stream receives a 196<kbd>Ctrl</kbd>+<kbd>Z</kbd> input, typically known as `SIGTSTP`. If there are 197no `'SIGTSTP'` event listeners registered when the `input` stream receives a 198`SIGTSTP`, the Node.js process will be sent to the background. 199 200When the program is resumed using fg(1p), the `'pause'` and `'SIGCONT'` events 201will be emitted. These can be used to resume the `input` stream. 202 203The `'pause'` and `'SIGCONT'` events will not be emitted if the `input` was 204paused before the process was sent to the background. 205 206The listener function is invoked without passing any arguments. 207 208```js 209rl.on('SIGTSTP', () => { 210 // This will override SIGTSTP and prevent the program from going to the 211 // background. 212 console.log('Caught SIGTSTP.'); 213}); 214``` 215 216The `'SIGTSTP'` event is _not_ supported on Windows. 217 218### `rl.close()` 219<!-- YAML 220added: v0.1.98 221--> 222 223The `rl.close()` method closes the `readline.Interface` instance and 224relinquishes control over the `input` and `output` streams. When called, 225the `'close'` event will be emitted. 226 227Calling `rl.close()` does not immediately stop other events (including `'line'`) 228from being emitted by the `readline.Interface` instance. 229 230### `rl.pause()` 231<!-- YAML 232added: v0.3.4 233--> 234 235The `rl.pause()` method pauses the `input` stream, allowing it to be resumed 236later if necessary. 237 238Calling `rl.pause()` does not immediately pause other events (including 239`'line'`) from being emitted by the `readline.Interface` instance. 240 241### `rl.prompt([preserveCursor])` 242<!-- YAML 243added: v0.1.98 244--> 245 246* `preserveCursor` {boolean} If `true`, prevents the cursor placement from 247 being reset to `0`. 248 249The `rl.prompt()` method writes the `readline.Interface` instances configured 250`prompt` to a new line in `output` in order to provide a user with a new 251location at which to provide input. 252 253When called, `rl.prompt()` will resume the `input` stream if it has been 254paused. 255 256If the `readline.Interface` was created with `output` set to `null` or 257`undefined` the prompt is not written. 258 259### `rl.question(query[, options], callback)` 260<!-- YAML 261added: v0.3.3 262--> 263 264* `query` {string} A statement or query to write to `output`, prepended to the 265 prompt. 266* `options` {Object} 267 * `signal` {AbortSignal} Optionally allows the `question()` to be canceled 268 using an `AbortController`. 269* `callback` {Function} A callback function that is invoked with the user's 270 input in response to the `query`. 271 272The `rl.question()` method displays the `query` by writing it to the `output`, 273waits for user input to be provided on `input`, then invokes the `callback` 274function passing the provided input as the first argument. 275 276When called, `rl.question()` will resume the `input` stream if it has been 277paused. 278 279If the `readline.Interface` was created with `output` set to `null` or 280`undefined` the `query` is not written. 281 282The `callback` function passed to `rl.question()` does not follow the typical 283pattern of accepting an `Error` object or `null` as the first argument. 284The `callback` is called with the provided answer as the only argument. 285 286Example usage: 287 288```js 289rl.question('What is your favorite food? ', (answer) => { 290 console.log(`Oh, so your favorite food is ${answer}`); 291}); 292``` 293 294Using an `AbortController` to cancel a question. 295 296```js 297const ac = new AbortController(); 298const signal = ac.signal; 299 300rl.question('What is your favorite food? ', { signal }, (answer) => { 301 console.log(`Oh, so your favorite food is ${answer}`); 302}); 303 304signal.addEventListener('abort', () => { 305 console.log('The food question timed out'); 306}, { once: true }); 307 308setTimeout(() => ac.abort(), 10000); 309``` 310 311If this method is invoked as it's util.promisify()ed version, it returns a 312Promise that fulfills with the answer. If the question is canceled using 313an `AbortController` it will reject with an `AbortError`. 314 315```js 316const util = require('util'); 317const question = util.promisify(rl.question).bind(rl); 318 319async function questionExample() { 320 try { 321 const answer = await question('What is you favorite food? '); 322 console.log(`Oh, so your favorite food is ${answer}`); 323 } catch (err) { 324 console.error('Question rejected', err); 325 } 326} 327questionExample(); 328``` 329 330### `rl.resume()` 331<!-- YAML 332added: v0.3.4 333--> 334 335The `rl.resume()` method resumes the `input` stream if it has been paused. 336 337### `rl.setPrompt(prompt)` 338<!-- YAML 339added: v0.1.98 340--> 341 342* `prompt` {string} 343 344The `rl.setPrompt()` method sets the prompt that will be written to `output` 345whenever `rl.prompt()` is called. 346 347### `rl.getPrompt()` 348<!-- YAML 349added: v14.17.0 350--> 351 352* Returns: {string} the current prompt string 353 354The `rl.getPrompt()` method returns the current prompt used by `rl.prompt()`. 355 356### `rl.write(data[, key])` 357<!-- YAML 358added: v0.1.98 359--> 360 361* `data` {string} 362* `key` {Object} 363 * `ctrl` {boolean} `true` to indicate the <kbd>Ctrl</kbd> key. 364 * `meta` {boolean} `true` to indicate the <kbd>Meta</kbd> key. 365 * `shift` {boolean} `true` to indicate the <kbd>Shift</kbd> key. 366 * `name` {string} The name of the a key. 367 368The `rl.write()` method will write either `data` or a key sequence identified 369by `key` to the `output`. The `key` argument is supported only if `output` is 370a [TTY][] text terminal. See [TTY keybindings][] for a list of key 371combinations. 372 373If `key` is specified, `data` is ignored. 374 375When called, `rl.write()` will resume the `input` stream if it has been 376paused. 377 378If the `readline.Interface` was created with `output` set to `null` or 379`undefined` the `data` and `key` are not written. 380 381```js 382rl.write('Delete this!'); 383// Simulate Ctrl+U to delete the line written previously 384rl.write(null, { ctrl: true, name: 'u' }); 385``` 386 387The `rl.write()` method will write the data to the `readline` `Interface`'s 388`input` *as if it were provided by the user*. 389 390### `rl[Symbol.asyncIterator]()` 391<!-- YAML 392added: 393 - v11.4.0 394 - v10.16.0 395changes: 396 - version: 397 - v11.14.0 398 - v10.17.0 399 pr-url: https://github.com/nodejs/node/pull/26989 400 description: Symbol.asyncIterator support is no longer experimental. 401--> 402 403* Returns: {AsyncIterator} 404 405Create an `AsyncIterator` object that iterates through each line in the input 406stream as a string. This method allows asynchronous iteration of 407`readline.Interface` objects through `for await...of` loops. 408 409Errors in the input stream are not forwarded. 410 411If the loop is terminated with `break`, `throw`, or `return`, 412[`rl.close()`][] will be called. In other words, iterating over a 413`readline.Interface` will always consume the input stream fully. 414 415Performance is not on par with the traditional `'line'` event API. Use `'line'` 416instead for performance-sensitive applications. 417 418```js 419async function processLineByLine() { 420 const rl = readline.createInterface({ 421 // ... 422 }); 423 424 for await (const line of rl) { 425 // Each line in the readline input will be successively available here as 426 // `line`. 427 } 428} 429``` 430 431`readline.createInterface()` will start to consume the input stream once 432invoked. Having asynchronous operations between interface creation and 433asynchronous iteration may result in missed lines. 434 435### `rl.line` 436<!-- YAML 437added: v0.1.98 438changes: 439 - version: v14.18.0 440 pr-url: https://github.com/nodejs/node/pull/33676 441 description: Value will always be a string, never undefined. 442--> 443 444* {string} 445 446The current input data being processed by node. 447 448This can be used when collecting input from a TTY stream to retrieve the 449current value that has been processed thus far, prior to the `line` event 450being emitted. Once the `line` event has been emitted, this property will 451be an empty string. 452 453Be aware that modifying the value during the instance runtime may have 454unintended consequences if `rl.cursor` is not also controlled. 455 456**If not using a TTY stream for input, use the [`'line'`][] event.** 457 458One possible use case would be as follows: 459 460```js 461const values = ['lorem ipsum', 'dolor sit amet']; 462const rl = readline.createInterface(process.stdin); 463const showResults = debounce(() => { 464 console.log( 465 '\n', 466 values.filter((val) => val.startsWith(rl.line)).join(' ') 467 ); 468}, 300); 469process.stdin.on('keypress', (c, k) => { 470 showResults(); 471}); 472``` 473 474### `rl.cursor` 475<!-- YAML 476added: v0.1.98 477--> 478 479* {number|undefined} 480 481The cursor position relative to `rl.line`. 482 483This will track where the current cursor lands in the input string, when 484reading input from a TTY stream. The position of cursor determines the 485portion of the input string that will be modified as input is processed, 486as well as the column where the terminal caret will be rendered. 487 488### `rl.getCursorPos()` 489<!-- YAML 490added: 491 - v13.5.0 492 - v12.16.0 493--> 494 495* Returns: {Object} 496 * `rows` {number} the row of the prompt the cursor currently lands on 497 * `cols` {number} the screen column the cursor currently lands on 498 499Returns the real position of the cursor in relation to the input 500prompt + string. Long input (wrapping) strings, as well as multiple 501line prompts are included in the calculations. 502 503## `readline.clearLine(stream, dir[, callback])` 504<!-- YAML 505added: v0.7.7 506changes: 507 - version: v12.7.0 508 pr-url: https://github.com/nodejs/node/pull/28674 509 description: The stream's write() callback and return value are exposed. 510--> 511 512* `stream` {stream.Writable} 513* `dir` {number} 514 * `-1`: to the left from cursor 515 * `1`: to the right from cursor 516 * `0`: the entire line 517* `callback` {Function} Invoked once the operation completes. 518* Returns: {boolean} `false` if `stream` wishes for the calling code to wait for 519 the `'drain'` event to be emitted before continuing to write additional data; 520 otherwise `true`. 521 522The `readline.clearLine()` method clears current line of given [TTY][] stream 523in a specified direction identified by `dir`. 524 525## `readline.clearScreenDown(stream[, callback])` 526<!-- YAML 527added: v0.7.7 528changes: 529 - version: v12.7.0 530 pr-url: https://github.com/nodejs/node/pull/28641 531 description: The stream's write() callback and return value are exposed. 532--> 533 534* `stream` {stream.Writable} 535* `callback` {Function} Invoked once the operation completes. 536* Returns: {boolean} `false` if `stream` wishes for the calling code to wait for 537 the `'drain'` event to be emitted before continuing to write additional data; 538 otherwise `true`. 539 540The `readline.clearScreenDown()` method clears the given [TTY][] stream from 541the current position of the cursor down. 542 543## `readline.createInterface(options)` 544<!-- YAML 545added: v0.1.98 546changes: 547 - version: v14.18.0 548 pr-url: https://github.com/nodejs/node/pull/37932 549 description: The `signal` option is supported now. 550 - version: v14.18.0 551 pr-url: https://github.com/nodejs/node/pull/33662 552 description: The `history` option is supported now. 553 - version: v13.9.0 554 pr-url: https://github.com/nodejs/node/pull/31318 555 description: The `tabSize` option is supported now. 556 - version: 557 - v8.3.0 558 - v6.11.4 559 pr-url: https://github.com/nodejs/node/pull/13497 560 description: Remove max limit of `crlfDelay` option. 561 - version: v6.6.0 562 pr-url: https://github.com/nodejs/node/pull/8109 563 description: The `crlfDelay` option is supported now. 564 - version: v6.3.0 565 pr-url: https://github.com/nodejs/node/pull/7125 566 description: The `prompt` option is supported now. 567 - version: v6.0.0 568 pr-url: https://github.com/nodejs/node/pull/6352 569 description: The `historySize` option can be `0` now. 570--> 571 572* `options` {Object} 573 * `input` {stream.Readable} The [Readable][] stream to listen to. This option 574 is *required*. 575 * `output` {stream.Writable} The [Writable][] stream to write readline data 576 to. 577 * `completer` {Function} An optional function used for Tab autocompletion. 578 * `terminal` {boolean} `true` if the `input` and `output` streams should be 579 treated like a TTY, and have ANSI/VT100 escape codes written to it. 580 **Default:** checking `isTTY` on the `output` stream upon instantiation. 581 * `history` {string[]} Initial list of history lines. This option makes sense 582 only if `terminal` is set to `true` by the user or by an internal `output` 583 check, otherwise the history caching mechanism is not initialized at all. 584 **Default:** `[]`. 585 * `historySize` {number} Maximum number of history lines retained. To disable 586 the history set this value to `0`. This option makes sense only if 587 `terminal` is set to `true` by the user or by an internal `output` check, 588 otherwise the history caching mechanism is not initialized at all. 589 **Default:** `30`. 590 * `removeHistoryDuplicates` {boolean} If `true`, when a new input line added 591 to the history list duplicates an older one, this removes the older line 592 from the list. **Default:** `false`. 593 * `prompt` {string} The prompt string to use. **Default:** `'> '`. 594 * `crlfDelay` {number} If the delay between `\r` and `\n` exceeds 595 `crlfDelay` milliseconds, both `\r` and `\n` will be treated as separate 596 end-of-line input. `crlfDelay` will be coerced to a number no less than 597 `100`. It can be set to `Infinity`, in which case `\r` followed by `\n` 598 will always be considered a single newline (which may be reasonable for 599 [reading files][] with `\r\n` line delimiter). **Default:** `100`. 600 * `escapeCodeTimeout` {number} The duration `readline` will wait for a 601 character (when reading an ambiguous key sequence in milliseconds one that 602 can both form a complete key sequence using the input read so far and can 603 take additional input to complete a longer key sequence). 604 **Default:** `500`. 605 * `tabSize` {integer} The number of spaces a tab is equal to (minimum 1). 606 **Default:** `8`. 607 * `signal` {AbortSignal} Allows closing the interface using an AbortSignal. 608 Aborting the signal will internally call `close` on the interface. 609* Returns: {readline.Interface} 610 611The `readline.createInterface()` method creates a new `readline.Interface` 612instance. 613 614```js 615const readline = require('readline'); 616const rl = readline.createInterface({ 617 input: process.stdin, 618 output: process.stdout 619}); 620``` 621 622Once the `readline.Interface` instance is created, the most common case is to 623listen for the `'line'` event: 624 625```js 626rl.on('line', (line) => { 627 console.log(`Received: ${line}`); 628}); 629``` 630 631If `terminal` is `true` for this instance then the `output` stream will get 632the best compatibility if it defines an `output.columns` property and emits 633a `'resize'` event on the `output` if or when the columns ever change 634([`process.stdout`][] does this automatically when it is a TTY). 635 636When creating a `readline.Interface` using `stdin` as input, the program 637will not terminate until it receives `EOF` (<kbd>Ctrl</kbd>+<kbd>D</kbd> on 638Linux/macOS, <kbd>Ctrl</kbd>+<kbd>Z</kbd> followed by <kbd>Return</kbd> on 639Windows). 640If you want your application to exit without waiting for user input, you can 641[`unref()`][] the standard input stream: 642 643```js 644process.stdin.unref(); 645``` 646 647### Use of the `completer` function 648 649The `completer` function takes the current line entered by the user 650as an argument, and returns an `Array` with 2 entries: 651 652* An `Array` with matching entries for the completion. 653* The substring that was used for the matching. 654 655For instance: `[[substr1, substr2, ...], originalsubstring]`. 656 657```js 658function completer(line) { 659 const completions = '.help .error .exit .quit .q'.split(' '); 660 const hits = completions.filter((c) => c.startsWith(line)); 661 // Show all completions if none found 662 return [hits.length ? hits : completions, line]; 663} 664``` 665 666The `completer` function can be called asynchronously if it accepts two 667arguments: 668 669```js 670function completer(linePartial, callback) { 671 callback(null, [['123'], linePartial]); 672} 673``` 674 675## `readline.cursorTo(stream, x[, y][, callback])` 676<!-- YAML 677added: v0.7.7 678changes: 679 - version: v12.7.0 680 pr-url: https://github.com/nodejs/node/pull/28674 681 description: The stream's write() callback and return value are exposed. 682--> 683 684* `stream` {stream.Writable} 685* `x` {number} 686* `y` {number} 687* `callback` {Function} Invoked once the operation completes. 688* Returns: {boolean} `false` if `stream` wishes for the calling code to wait for 689 the `'drain'` event to be emitted before continuing to write additional data; 690 otherwise `true`. 691 692The `readline.cursorTo()` method moves cursor to the specified position in a 693given [TTY][] `stream`. 694 695## `readline.emitKeypressEvents(stream[, interface])` 696<!-- YAML 697added: v0.7.7 698--> 699 700* `stream` {stream.Readable} 701* `interface` {readline.Interface} 702 703The `readline.emitKeypressEvents()` method causes the given [Readable][] 704stream to begin emitting `'keypress'` events corresponding to received input. 705 706Optionally, `interface` specifies a `readline.Interface` instance for which 707autocompletion is disabled when copy-pasted input is detected. 708 709If the `stream` is a [TTY][], then it must be in raw mode. 710 711This is automatically called by any readline instance on its `input` if the 712`input` is a terminal. Closing the `readline` instance does not stop 713the `input` from emitting `'keypress'` events. 714 715```js 716readline.emitKeypressEvents(process.stdin); 717if (process.stdin.isTTY) 718 process.stdin.setRawMode(true); 719``` 720 721## `readline.moveCursor(stream, dx, dy[, callback])` 722<!-- YAML 723added: v0.7.7 724changes: 725 - version: v12.7.0 726 pr-url: https://github.com/nodejs/node/pull/28674 727 description: The stream's write() callback and return value are exposed. 728--> 729 730* `stream` {stream.Writable} 731* `dx` {number} 732* `dy` {number} 733* `callback` {Function} Invoked once the operation completes. 734* Returns: {boolean} `false` if `stream` wishes for the calling code to wait for 735 the `'drain'` event to be emitted before continuing to write additional data; 736 otherwise `true`. 737 738The `readline.moveCursor()` method moves the cursor *relative* to its current 739position in a given [TTY][] `stream`. 740 741## Example: Tiny CLI 742 743The following example illustrates the use of `readline.Interface` class to 744implement a small command-line interface: 745 746```js 747const readline = require('readline'); 748const rl = readline.createInterface({ 749 input: process.stdin, 750 output: process.stdout, 751 prompt: 'OHAI> ' 752}); 753 754rl.prompt(); 755 756rl.on('line', (line) => { 757 switch (line.trim()) { 758 case 'hello': 759 console.log('world!'); 760 break; 761 default: 762 console.log(`Say what? I might have heard '${line.trim()}'`); 763 break; 764 } 765 rl.prompt(); 766}).on('close', () => { 767 console.log('Have a great day!'); 768 process.exit(0); 769}); 770``` 771 772## Example: Read file stream line-by-Line 773 774A common use case for `readline` is to consume an input file one line at a 775time. The easiest way to do so is leveraging the [`fs.ReadStream`][] API as 776well as a `for await...of` loop: 777 778```js 779const fs = require('fs'); 780const readline = require('readline'); 781 782async function processLineByLine() { 783 const fileStream = fs.createReadStream('input.txt'); 784 785 const rl = readline.createInterface({ 786 input: fileStream, 787 crlfDelay: Infinity 788 }); 789 // Note: we use the crlfDelay option to recognize all instances of CR LF 790 // ('\r\n') in input.txt as a single line break. 791 792 for await (const line of rl) { 793 // Each line in input.txt will be successively available here as `line`. 794 console.log(`Line from file: ${line}`); 795 } 796} 797 798processLineByLine(); 799``` 800 801Alternatively, one could use the [`'line'`][] event: 802 803```js 804const fs = require('fs'); 805const readline = require('readline'); 806 807const rl = readline.createInterface({ 808 input: fs.createReadStream('sample.txt'), 809 crlfDelay: Infinity 810}); 811 812rl.on('line', (line) => { 813 console.log(`Line from file: ${line}`); 814}); 815``` 816 817Currently, `for await...of` loop can be a bit slower. If `async` / `await` 818flow and speed are both essential, a mixed approach can be applied: 819 820```js 821const { once } = require('events'); 822const { createReadStream } = require('fs'); 823const { createInterface } = require('readline'); 824 825(async function processLineByLine() { 826 try { 827 const rl = createInterface({ 828 input: createReadStream('big-file.txt'), 829 crlfDelay: Infinity 830 }); 831 832 rl.on('line', (line) => { 833 // Process the line. 834 }); 835 836 await once(rl, 'close'); 837 838 console.log('File processed.'); 839 } catch (err) { 840 console.error(err); 841 } 842})(); 843``` 844 845## TTY keybindings 846 847<table> 848 <tr> 849 <th>Keybindings</th> 850 <th>Description</th> 851 <th>Notes</th> 852 </tr> 853 <tr> 854 <td><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Backspace</kbd></td> 855 <td>Delete line left</td> 856 <td>Doesn't work on Linux, Mac and Windows</td> 857 </tr> 858 <tr> 859 <td><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Delete</kbd></td> 860 <td>Delete line right</td> 861 <td>Doesn't work on Mac</td> 862 </tr> 863 <tr> 864 <td><kbd>Ctrl</kbd>+<kbd>C</kbd></td> 865 <td>Emit <code>SIGINT</code> or close the readline instance</td> 866 <td></td> 867 </tr> 868 <tr> 869 <td><kbd>Ctrl</kbd>+<kbd>H</kbd></td> 870 <td>Delete left</td> 871 <td></td> 872 </tr> 873 <tr> 874 <td><kbd>Ctrl</kbd>+<kbd>D</kbd></td> 875 <td>Delete right or close the readline instance in case the current line is empty / EOF</td> 876 <td>Doesn't work on Windows</td> 877 </tr> 878 <tr> 879 <td><kbd>Ctrl</kbd>+<kbd>U</kbd></td> 880 <td>Delete from the current position to the line start</td> 881 <td></td> 882 </tr> 883 <tr> 884 <td><kbd>Ctrl</kbd>+<kbd>K</kbd></td> 885 <td>Delete from the current position to the end of line</td> 886 <td></td> 887 </tr> 888 <tr> 889 <td><kbd>Ctrl</kbd>+<kbd>A</kbd></td> 890 <td>Go to start of line</td> 891 <td></td> 892 </tr> 893 <tr> 894 <td><kbd>Ctrl</kbd>+<kbd>E</kbd></td> 895 <td>Go to to end of line</td> 896 <td></td> 897 </tr> 898 <tr> 899 <td><kbd>Ctrl</kbd>+<kbd>B</kbd></td> 900 <td>Back one character</td> 901 <td></td> 902 </tr> 903 <tr> 904 <td><kbd>Ctrl</kbd>+<kbd>F</kbd></td> 905 <td>Forward one character</td> 906 <td></td> 907 </tr> 908 <tr> 909 <td><kbd>Ctrl</kbd>+<kbd>L</kbd></td> 910 <td>Clear screen</td> 911 <td></td> 912 </tr> 913 <tr> 914 <td><kbd>Ctrl</kbd>+<kbd>N</kbd></td> 915 <td>Next history item</td> 916 <td></td> 917 </tr> 918 <tr> 919 <td><kbd>Ctrl</kbd>+<kbd>P</kbd></td> 920 <td>Previous history item</td> 921 <td></td> 922 </tr> 923 <tr> 924 <td><kbd>Ctrl</kbd>+<kbd>Z</kbd></td> 925 <td>Moves running process into background. Type 926 <code>fg</code> and press <kbd>Enter</kbd> 927 to return.</td> 928 <td>Doesn't work on Windows</td> 929 </tr> 930 <tr> 931 <td><kbd>Ctrl</kbd>+<kbd>W</kbd> or <kbd>Ctrl</kbd> 932 +<kbd>Backspace</kbd></td> 933 <td>Delete backward to a word boundary</td> 934 <td><kbd>Ctrl</kbd>+<kbd>Backspace</kbd> Doesn't 935 work on Linux, Mac and Windows</td> 936 </tr> 937 <tr> 938 <td><kbd>Ctrl</kbd>+<kbd>Delete</kbd></td> 939 <td>Delete forward to a word boundary</td> 940 <td>Doesn't work on Mac</td> 941 </tr> 942 <tr> 943 <td><kbd>Ctrl</kbd>+<kbd>Left arrow</kbd> or 944 <kbd>Meta</kbd>+<kbd>B</kbd></td> 945 <td>Word left</td> 946 <td><kbd>Ctrl</kbd>+<kbd>Left arrow</kbd> Doesn't work 947 on Mac</td> 948 </tr> 949 <tr> 950 <td><kbd>Ctrl</kbd>+<kbd>Right arrow</kbd> or 951 <kbd>Meta</kbd>+<kbd>F</kbd></td> 952 <td>Word right</td> 953 <td><kbd>Ctrl</kbd>+<kbd>Right arrow</kbd> Doesn't work 954 on Mac</td> 955 </tr> 956 <tr> 957 <td><kbd>Meta</kbd>+<kbd>D</kbd> or <kbd>Meta</kbd> 958 +<kbd>Delete</kbd></td> 959 <td>Delete word right</td> 960 <td><kbd>Meta</kbd>+<kbd>Delete</kbd> Doesn't work 961 on windows</td> 962 </tr> 963 <tr> 964 <td><kbd>Meta</kbd>+<kbd>Backspace</kbd></td> 965 <td>Delete word left</td> 966 <td>Doesn't work on Mac</td> 967 </tr> 968</table> 969 970[Readable]: stream.md#stream_readable_streams 971[TTY]: tty.md 972[TTY keybindings]: #readline_tty_keybindings 973[Writable]: stream.md#stream_writable_streams 974[`'SIGCONT'`]: #readline_event_sigcont 975[`'SIGTSTP'`]: #readline_event_sigtstp 976[`'line'`]: #readline_event_line 977[`fs.ReadStream`]: fs.md#fs_class_fs_readstream 978[`process.stdin`]: process.md#process_process_stdin 979[`process.stdout`]: process.md#process_process_stdout 980[`rl.close()`]: #readline_rl_close 981[`unref()`]: net.md#net_socket_unref 982[reading files]: #readline_example_read_file_stream_line_by_line 983