Permalink
Browse files

position() works

  • Loading branch information...
0 parents commit fc5e8010bab423262b553f767bdc62b5f325ae3d @substack committed Aug 13, 2011
Showing with 108 additions and 0 deletions.
  1. +90 −0 index.js
  2. +18 −0 lib/encode.js
@@ -0,0 +1,90 @@
+var tty = require('tty');
+var encode = require('./lib/encode');
+var EventEmitter = require('events').EventEmitter;
+
+var exports = module.exports = function () {
+ var input = null;
+ function setInput (s) {
+ if (input) throw new Error('multiple inputs specified')
+ else input = s
+ }
+
+ var output = null;
+ function setOutput (s) {
+ if (output) throw new Error('multiple outputs specified')
+ else output = s
+ }
+
+ for (var i = 0; i < arguments.length; i++) {
+ var arg = arguments[i];
+ if (!arg) continue;
+ if (arg.readable) setInput(arg)
+ if (arg.writable) setOutput(arg)
+ if (arg.stdin || arg.input) setInput(arg.stdin || arg.input)
+ if (arg.stdout || arg.output) setOutput(arg.stdout || arg.output)
+ }
+
+ return new Charm(input, output);
+};
+
+function Charm (input, output) {
+ var self = this;
+ self.input = input;
+ self.output = output;
+ self.pending = [];
+
+ if (input === process.stdin) {
+ tty.setRawMode(true);
+ input.resume();
+ }
+
+ if (input) {
+ input.on('data', function (buf) {
+ if (self.pending.length && buf[0] === 27) {
+ for (var i = 0; i < self.pending.length; i++) {
+ var cb = self.pending[0];
+ if (cb(buf)) {
+ self.pending.shift();
+ return;
+ }
+ }
+ }
+
+ self.emit('data', buf)
+ });
+ }
+}
+
+Charm.prototype = new EventEmitter;
+
+Charm.prototype.position = function (x, y) {
+ if (!this.output) {
+ this.emit('error', new Error(
+ 'output stream required to query position'
+ ));
+ }
+ else if (typeof x === 'function') {
+ var cb = x;
+ this.output.write(encode('[6n'));
+ this.pending.push(function (buf) {
+ if (buf[0] === 27 && buf[1] === encode.ord('[')
+ && buf[buf.length-1] === encode.ord('R')) {
+ var pos = buf.toString()
+ .slice(2,-1)
+ .split(';')
+ .map(Number)
+ ;
+ cb(pos[0], pos[1]);
+ return true;
+ }
+ });
+ }
+ else {
+ this.output.write(encode('[' + x + ';' + y + 'f'));
+ }
+ return this;
+};
+
+Charm.prototype.destroy = function () {
+ if (this.input) this.input.destroy()
+};
@@ -0,0 +1,18 @@
+var encode = module.exports = function (xs) {
+ function bytes (s) {
+ if (typeof s === 'string') {
+ return s.split('').map(ord);
+ }
+ else if (Array.isArray(s)) {
+ return s.reduce(function (acc, c) {
+ return acc.concat(bytes(c));
+ }, []);
+ }
+ }
+
+ return new Buffer([ 0x1b ].concat(bytes(xs)));
+};
+
+var ord = encode.ord = function ord (c) {
+ return c.charCodeAt(0)
+};

0 comments on commit fc5e801

Please sign in to comment.