• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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