diff --git a/lib/tput.js b/lib/tput.js index 2dd6b41..86cfc17 100644 --- a/lib/tput.js +++ b/lib/tput.js @@ -40,6 +40,10 @@ function Tput(options) { this.printf = options.printf; this.termcap = options.termcap; + this.terminfoPrefix = options.terminfoPrefix; + this.terminfoFile = options.terminfoFile; + this.termcapFile = options.termcapFile; + try { if (this.termcap) { this.compileTermcap(); @@ -59,11 +63,10 @@ function Tput(options) { Tput.prototype.readTerminfo = function(data) { if (!data) { - var file = path.resolve( - '/usr/share/terminfo', - path.basename(this.term[0]), - path.basename(this.term) - ); + var file = this.terminfoFile + || this._terminfoPrefix(this.terminfoPrefix) + || this._terminfoPrefix('/usr/share/terminfo') + || this._terminfoPrefix(process.env.HOME + '/.terminfo'); data = fs.readFileSync(file); } @@ -76,6 +79,23 @@ Tput.prototype.readTerminfo = function(data) { return info; }; +Tput.prototype._terminfoPrefix = function(prefix) { + if (!prefix) return; + + var file = path.resolve( + prefix, + path.basename(this.term[0]), + path.basename(this.term) + ); + + try { + fs.statSync(file); + return file; + } catch (e) { + ; + } +}; + /** * Terminfo Parser * All shorts are little-endian @@ -1000,7 +1020,10 @@ Tput.prototype._parsePadding = function(code, print, done) { */ Tput.prototype.readTermcap = function(data) { + var self = this; + var data = data + || tryRead(this.termcapFile) || tryRead(process.env.TERMCAP) || process.env.TERMCAP || tryRead('/etc/termcap') @@ -1015,8 +1038,23 @@ Tput.prototype.readTermcap = function(data) { (function tc(term) { if (term && term.strings.tc) { + if (self.debug && terms[term.strings.tc]) { + console.log(term.names.join('/') + + ' inherits from ' + + terms[term.strings.tc].names.join('/')); + } + + var t = terms[self.term]; + t.inherits = t.inherits || []; + t.inherits.push(term.strings.tc); + var inherit = tc(terms[term.strings.tc]); if (inherit) { + if (0 && self.debug) { + console.log(term.names.join('/') + + ' inherits from ' + + inherit.names.join('/')); + } ['bools', 'numbers', 'strings'].forEach(function(type) { merge(term[type], inherit[type]); }); @@ -1200,9 +1238,9 @@ function write(data) { return process.stdout.write(data); } -function tryRead() { +function tryRead(file) { if (!file) return ''; - var file = path.resolve.apply(path, arguments); + file = path.resolve.apply(path, arguments); try { return fs.readFileSync(file, 'utf8'); } catch (e) { diff --git a/test/tput.js b/test/tput.js index 5590b9c..855cbfa 100644 --- a/test/tput.js +++ b/test/tput.js @@ -1,25 +1,92 @@ +/** + * Tput for node.js + * Copyright (c) 2013, Christopher Jeffrey (MIT License) + * https://github.com/chjj/blessed + */ + +// $ node test/tput.js | tee out +// $ node test/tput.js vt102 --termcap | tee out +// $ node test/tput.js --cfile usr/xterm.termcap | tee out +// $ node test/tput.js --iprefix ~/.terminfo | tee out +// $ node test/tput.js xterm-256color --ifile ~/.terminfo/x/xterm-256color | tee out +// $ cdiff test/terminfo out + var Tput = require('../').Tput; -var termcap = ~process.argv.indexOf('--termcap') - , term = termcap ? 'vt102' : process.argv[2] || 'xterm'; +// Simple argument parser +// Copyright (c) 2012, Christopher Jeffrey (MIT License) + +function parseArg() { + var argv = process.argv.slice(2) + , options = []; + + function getarg() { + var arg = argv.shift(); + + if (arg.indexOf('--') === 0) { + // e.g. --opt + arg = arg.split('='); + if (arg.length > 1) { + // e.g. --opt=val + argv.unshift(arg.slice(1).join('=')); + } + arg = arg[0]; + } else if (arg[0] === '-') { + if (arg.length > 2) { + // e.g. -abc + argv = arg.substring(1).split('').map(function(ch) { + return '-' + ch; + }).concat(argv); + arg = argv.shift(); + } else { + // e.g. -a + } + } else { + // e.g. foo + } + + return arg; + } + + while (argv.length) { + arg = getarg(); + if (arg.indexOf('-') === 0) { + arg = arg.replace(/^--?/, ''); + if (argv[0] && argv[0].indexOf('-') !== 0) { + options[arg] = argv.shift(); + } else { + options[arg] = true; + } + } else { + options.push(arg); + } + } + + return options; +} + +var argv = parseArg(); var tput = Tput({ - term: term, + term: argv[0] || 'xterm', extended: true, debug: true, - termcap: termcap + termcap: argv.termcap || !!argv.cfile || !!argv.c, + terminfoFile: argv.i || argv.ifile, + terminfoPrefix: argv.p || argv.iprefix, + termcapFile: argv.c || argv.cfile }); console.log('Max colors: %d.', tput.colors); -//process.stdout.write(Tput.sprintf('%-10s\n', 'hello')); +// process.stdout.write(Tput.sprintf('%-10s\n', 'hello')); -//tput._compile('%?%p9%t\u001b(0%e\u001b(B%;\u001b[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m'); +// tput._compile('%?%p9%t\u001b(0%e\u001b(B%;\u001b[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m'); -//console.log(tput.setaf(4) + 'foo' + tput.sgr0()); -//console.log(tput.setaf(4) + 'foo' + tput.sgr(0)); +// console.log(tput.setaf(4) + 'foo' + tput.sgr0()); +// console.log(tput.setaf(4) + 'foo' + tput.sgr(0)); -//tput.padding = true; -//tput._print('hello$<1000/>world', console.log, function() { -// tput._print('$<1000*>foo$<1000/>bar', console.log, process.exit); -//}); +// tput.padding = true; +// tput._print('hello$<1000/>world', console.log, function() { +// tput._print('$<1000*>foo$<1000/>bar', console.log, process.exit); +// });