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