René Beneš
René Beneš

Reputation: 468

Mute console text input

My process.stdin is set to RAW mode, so I can catch user keypress event with:

process.stdin.on('keypress', (str, key) => {
     // process keypress      
});

Events are successfully fired, keystrokes registered, but I haven't been able to find a way to prevent input to console. Using this approach, is it possible to prevent a key to be written to console? If not, is there any other way to intercept keypress event without sending keystrokes to console?

Upvotes: 2

Views: 583

Answers (1)

Darkosphere
Darkosphere

Reputation: 171

The code you provided miss some more details. As it is it should not output anything to the console.

But let's say you did something like this :

process.stdin.on('keypress', (str, key) => {
    console.log(key);
});

process.stdin.setRawMode(true);
process.stdin.resume();

This will output :

  • the key object if the key pressed has no displayable char. i.e :
 {
  sequence: ' ',
  name: 'space',
  ctrl: false,
  meta: false,
  shift: false
}
  • otherwise it will output the key pressed char followed by the key object:
a{ sequence: 'a', name: 'a', ctrl: false, meta: false, shift: false }

If what you want to do is to avoid the keypressed char from being displayed you can try this :

var readline = require('readline');
var Writable = require('stream').Writable;

var mutableStdout = new Writable({
  write: function(chunk, encoding, callback) {
    if (!this.muted)
      process.stdout.write(chunk, encoding);
    callback();
  }
});

var rl = readline.createInterface({
  input: process.stdin,
  output: mutableStdout,
  terminal: true
});

What we do here basically is to define a readline interface with a mutable output stream so now we can use these instructions:

  • mutableStdout.muted = true; to mute the output stream of the readline interface
    this prevents default outputs to affect console in raw mode.
    note that you can still ouput in console using either console.log() or process.stdout.write()
  • mutableStdout.muted = false; to unmute the output stream of the readline interface

If we now take the first example and turn it into this :

var readline = require('readline');
var Writable = require('stream').Writable;

var mutableStdout = new Writable({
  write: function(chunk, encoding, callback) {
    if (!this.muted)
      process.stdout.write(chunk, encoding);
    callback();
  }
});

var rl = readline.createInterface({
  input: process.stdin,
  output: mutableStdout,
  terminal: true
});

process.stdin.on('keypress', (str, key) => {
    console.log(key);
});

process.stdin.setRawMode(true);
process.stdin.resume();

mutableStdout.muted = true; //

What was giving this result before:
a{ sequence: 'a', name: 'a', ctrl: false, meta: false, shift: false }

will now give that :
{ sequence: 'a', name: 'a', ctrl: false, meta: false, shift: false }

Now about the way to get more convenient keypress events
what about turning the original process.stdin.on('keypress',) into a console events emitter himself.

Just like this:

const event = require('events');
let event_ = new event.EventEmitter();

process.stdin.on('keypress', (str, key) => {
    event_.emit('keyPressed', {key: key});
});

process.stdin.setRawMode(true);
process.stdin.resume();

Using event_ you can now listen to the keypress from anywhere inside your program.

here is an example :

event_.on('keyPressed', (e) => {
   key = e.key; 
   console.log(`${key.name} pressed`);
});

with this every time a key is pressed it should log the message:

 keyName pressed 
or
 undefined pressed

if the key pressed has no name attribute.

For more informations on how to use those console events you could check this post on the nodejs website : What are Event Emitters?

Basically you can nearly do the same stuff with the console events that what you can do with events in a web navigator.

Upvotes: 0

Related Questions