Skip to content

Instantly share code, notes, and snippets.

@dmarcelino
Forked from alfonsodev/cursor-position.js
Last active August 29, 2015 14:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmarcelino/e39b18c6a06c211a896f to your computer and use it in GitHub Desktop.
Save dmarcelino/e39b18c6a06c211a896f to your computer and use it in GitHub Desktop.
/**
* Example on how to get cursor position programatically with JS
*/
var stdin = process.stdin;
var firstAttempt = true;
function callback() {
var buf = stdin.read();
if(buf === null){
if(firstAttempt){
firstAttempt = false;
console.log('1st call is always null, so we subscribe again');
stdin.once('readable', callback);
return;
}
//stdin.pause();
stdin.setRawMode( false );
return;
}
// detect cursor position: ESC[n;mR
if (buf[0] === 27 &&
buf[1] === '['.charCodeAt(0) &&
buf[buf.length - 1] === 'R'.charCodeAt(0)) {
var pos = buf.toString().slice(2, -1).split(';').map(Number);
stdin.setRawMode( false );
stdin.pause();
console.log(' ---> position:', pos);
return;
}
// Detect Ctrl + c, just in case...
if(buf.length === 1 && buf[0] === 3){
process.exist();
};
console.log(' --> oops: ' + buf);
//process.stdout.write(buf);
}
// So we don't wait for enter'
stdin.setRawMode( true );
stdin.once('readable', callback);
process.stdout.write("some text to move the cursor");
process.stdout.write("\x1b[6n");
//stdin.resume();
/**
* Attempt to create a module to read and return cursor position. So far not that great...
*/
var stdin = process.stdin;
var maxAttempts = 1;
var previousRawValue = stdin.isRaw;
stdin.setMaxListeners(50);
module.exports.getCursorPosition = function getCursorPosition(cb){
cb = cb || function(){};
var attempts = 0;
// without this, we would only get streams once enter is pressed
stdin.setRawMode( true );
function callback() {
var buf = stdin.read();
if(buf === null){
attempts++;
if(attempts >= maxAttempts){
//stdin.pause();
stdin.setRawMode( previousRawValue );
return cb();
}
// 1st call is always null, so we subscribe again
stdin.once('readable', callback);
return;
}
if (buf[0] === 27 &&
buf[1] === '['.charCodeAt(0) &&
buf[buf.length - 1] === 'R'.charCodeAt(0)) {
var pos = buf.toString().slice(2, -1).split(';').map(Number);
//stdin.pause();
stdin.setRawMode( previousRawValue );
console.log(' ---> success! ', pos);
return cb(pos[0], pos[1]);
}
console.log(' --> oops:', buf);
//process.stdout.write(buf);
}
stdin.once('readable', callback);
process.stdout.write("\x1b[6n");
//stdin.resume();
};
/**
* Attempt to create a module to read and return cursor position. Still no luck
*/
var stdin = process.stdin;
var previousRawValue = stdin.isRaw;
stdin.setMaxListeners(50);
module.exports.getCursorPosition = function getCursorPosition(cb){
cb = cb || function(){};
function callback(buf) {
if (buf[0] === 27 &&
buf[1] === '['.charCodeAt(0) &&
buf[buf.length - 1] === 'R'.charCodeAt(0)) {
var pos = buf.toString().slice(2, -1).split(';').map(Number);
stdin.setRawMode( previousRawValue );
stdin.removeListener('data', callback);
stdin.pause();
// console.log(' ---> success! ', pos);
return cb(pos[0], pos[pos.length-1]);
}
console.log(' --> oops:', buf);
process.stdout.write(buf);
}
// without this, we would only get streams once enter is pressed
stdin.setRawMode( true );
// resume stdin in the parent process (node app won't quit all by itself
// unless an error or process.exit() happens)
stdin.resume();
stdin.on('data', callback);
process.stdout.write("\x1b[6n");
//stdin.resume();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment