node.jsreadlinectrl

What signal is emitted when pressing CTRL+D in node:readline?


I've been trying to intercept CTRL+D so I can use it to represent 'document' for a CLI I am building. I have been unsuccessful identifying how to intercept it when using readline with keypress.

Is there a specific signal event I can listen for and override the default readline behavior to exit the application when CTRL+D is pressed?

It's also notable that CTRL+D does not exit the application if other keys have been pressed. But this is untenable as a solution.

Any help would be appreciated!

import readline from'node:readline'

const stdin = process.stdin
stdin.setEncoding('utf8')
const stdout = process.stdout
stdout.setEncoding('utf8')

const rl = readline.createInterface( stdin, stdout )

readline.emitKeypressEvents(stdin)
stdin.setRawMode(true)

rl.on('line', line => {
  console.log(line)
})

stdin.on('keypress', async (str, key) => {  
  if(key.name === 'd' && key.ctrl === true){
    console.log('CTRL-D')
  }
})

process.on('SIGINT', ()=>{
  console.log('CTRL+D??')
})

Solution

  • Control + D is not a regular operating system signal like SIGINT.

    It is used on stdin as "end-of-transmission" information by readline and many others to close stdin. Here is a snippet of the node readline source1 handling it:

            case 'd': // delete right or EOF
              if (this.cursor === 0 && this.line.length === 0) {
                // This readline instance is finished
                this.close();
              } else if (this.cursor < this.line.length) {
                this[kDeleteRight]();
              }
              break;
    

    I can't see a way of changing this behaviour in readline without overiding readlines _ttyWrite function or some type of interception before readline handles stdin.

    1 - MIT Licensed. Copyright Node.js contributors