I am using node.js v4.5
I wrote the function below to send repeated messages with a delay.
function send_messages() {
Promise.resolve()
.then(() => send_msg() )
.then(() => Delay(1000) )
.then(() => send_msg() )
.then(() => Delay(1000))
.then(() => send_msg() )
;
}
function Delay(duration) {
return new Promise((resolve) => {
setTimeout(() => resolve(), duration);
});
}
Instead of delay, I would like to activate the sending of messages using a keypress. Something like the function below.
function send_messages_keystroke() {
Promise.resolve()
.then(() => send_msg() )
.then(() => keyPress('ctrl-b') ) //Run subsequent line of code send_msg() if keystroke ctrl-b is pressed
.then(() => send_msg() )
.then(() => keyPress('ctrl-b') )
.then(() => send_msg() )
;
}
I am using node.js v4.5
I wrote the function below to send repeated messages with a delay.
function send_messages() {
Promise.resolve()
.then(() => send_msg() )
.then(() => Delay(1000) )
.then(() => send_msg() )
.then(() => Delay(1000))
.then(() => send_msg() )
;
}
function Delay(duration) {
return new Promise((resolve) => {
setTimeout(() => resolve(), duration);
});
}
Instead of delay, I would like to activate the sending of messages using a keypress. Something like the function below.
function send_messages_keystroke() {
Promise.resolve()
.then(() => send_msg() )
.then(() => keyPress('ctrl-b') ) //Run subsequent line of code send_msg() if keystroke ctrl-b is pressed
.then(() => send_msg() )
.then(() => keyPress('ctrl-b') )
.then(() => send_msg() )
;
}
Share
Improve this question
edited Sep 12, 2016 at 12:35
Bergi
666k161 gold badges1k silver badges1.5k bronze badges
asked Sep 8, 2016 at 2:12
user6064424user6064424
2 Answers
Reset to default 6 +50You can put process.stdin
in raw mode to access individual keystrokes.
Here's a standalone example:
function send_msg(msg) {
console.log('Message:', msg);
}
// To map the `value` parameter to the required keystroke, see:
// http://academic.evergreen.edu/projects/biophysics/technotes/program/ascii_ctrl.htm
function keyPress(value) {
return new Promise((resolve, reject) => {
process.stdin.setRawMode(true);
process.stdin.once('data', keystroke => {
process.stdin.setRawMode(false);
if (keystroke[0] === value) return resolve();
return reject(Error('invalid keystroke'));
});
})
}
Promise.resolve()
.then(() => send_msg('1'))
.then(() => keyPress(2))
.then(() => send_msg('2'))
.then(() => keyPress(2))
.then(() => send_msg('done'))
.catch(e => console.error('Error', e))
It will reject any keystroke that isn't Ctrl-B, but the code is easily modifiable if you don't want that behaviour (and just want to wait for the first Ctrl-B, for instance).
The value passed to keyPress
is the decimal ASCII value of the key: Ctrl-A is 1, Ctrl-B is 2, a is 97, etc.
EDIT: as suggested by @mh-cbon in the ments, a better solution might be to use the keypress
module.
Give this one a try. As mentioned above, using keypress makes it really simple. The key
object in the code here tells you if ctrl
or shift
are pressed, as well as the character pressed. Unfortunately though, keypress
doesn't seem to handle numbers or special characters.
var keypress = require('keypress');
keypress(process.stdin);
process.stdin.on('keypress', function (ch, key) {
console.log("here's the key object", key);
shouldExit(key);
if (key) {
sendMessage(key);
}
});
function shouldExit(key) {
if (key && key.ctrl && key.name == 'c') {
process.stdin.pause();
}
}
function sendMessage(key) {
switch(key.name) {
case 'a';
console.log('you typed a'); break;
case 'b';
console.log('you typed b'); break;
default:
console.log('bob is cool');
}
}
And of course, in the sendMessage()
function here, you could easily replace the log statements with something else more plex, make some async calls, call some other function, whatever. The process.stdin.pause()
here causes the program to exit on ctrl-c
, otherwise, the program would just keep running, blocking your interrupt signal, and you'd have to kill the process manually via mand line.