better terminfo/cap discovery. fixes #17.

This commit is contained in:
Christopher Jeffrey 2013-08-24 22:25:38 -05:00
parent fdfdac63a8
commit 00ee15a32f

View File

@ -124,6 +124,19 @@ Tput.prototype._useInternalCap = function(name) {
* Terminfo
*/
Tput.ipaths = [
process.env.TERMINFO || '',
(process.env.TERMINFO_DIRS || '').split(':'),
(process.env.HOME || '') + '/.terminfo',
'/usr/share/terminfo',
'/usr/share/lib/terminfo',
'/usr/lib/terminfo',
'/usr/local/share/terminfo',
'/usr/local/share/lib/terminfo',
'/usr/local/lib/terminfo',
'/usr/local/ncurses/lib/terminfo'
];
Tput.prototype.readTerminfo = function(term) {
var term = term || this.terminal
, data
@ -143,33 +156,52 @@ Tput.prototype.readTerminfo = function(term) {
Tput._prefix =
Tput.prototype._prefix = function(term) {
var TERMINFO = process.env.TERMINFO || ''
, TERMINFO_DIRS = process.env.TERMINFO_DIRS || ''
, HOME = process.env.HOME || '';
// If we have a terminfoFile, or our
// term looks like a filename, use it.
if (term) {
if (~term.indexOf(path.sep)) {
return term;
}
if (this.terminfoFile) {
return this.terminfoFile;
}
}
return (term && ~term.indexOf(path.sep) && term)
|| (term && this.terminfoFile)
|| this._tprefix(this.terminfoPrefix, term)
|| this._tprefix(TERMINFO, term)
|| this._tprefix(TERMINFO_DIRS.split(':'), term)
|| this._tprefix(HOME + '/.terminfo', term)
|| this._tprefix('/usr/share/terminfo', term)
|| this._tprefix('/usr/share/lib/terminfo', term)
|| this._tprefix('/usr/lib/terminfo', term)
|| this._tprefix('/usr/local/share/terminfo', term)
|| this._tprefix('/usr/local/share/lib/terminfo', term)
|| this._tprefix('/usr/local/lib/terminfo', term)
|| this._tprefix('/usr/local/ncurses/lib/terminfo', term)
|| (function() { throw new Error('Terminfo directory not found.'); })();
var paths = Tput.ipaths.slice()
, file
, i;
if (this.terminfoPrefix) {
paths.unshift(this.terminfoPrefix);
}
// Try exact matches.
for (i = 0; i < paths.length; i++) {
file = this._tprefix(paths[i], term);
if (file) return file;
}
// Try similar matches.
for (i = 0; i < paths.length; i++) {
file = this._tprefix(paths[i], term, true);
if (file) return file;
}
// Not found.
throw new Error('Terminfo directory not found.');
};
Tput._tprefix =
Tput.prototype._tprefix = function(prefix, term) {
Tput.prototype._tprefix = function(prefix, term, soft) {
if (!prefix) return;
var file
, dir
, ch
, i;
, i
, sdiff
, sfile
, list;
if (Array.isArray(prefix)) {
for (i = 0; i < prefix.length; i++) {
@ -179,18 +211,40 @@ Tput.prototype._tprefix = function(prefix, term) {
return;
}
if (!term) {
file = path.resolve(prefix, 'x');
var find = function(word) {
var file, ch;
file = path.resolve(prefix, word[0]);
try {
fs.statSync(file);
return prefix;
return file;
} catch (e) {
;
}
file = path.resolve(prefix, '78');
ch = word[0].charCodeAt(0).toString(16);
if (ch.length < 2) ch = '0' + ch;
file = path.resolve(prefix, ch);
try {
fs.statSync(file);
return prefix;
return file;
} catch (e) {
;
}
};
if (!term) {
// Make sure the directory's sub-directories
// are all one-letter, or hex digits.
// return find('x') ? prefix : null;
try {
dir = fs.readdirSync(prefix).filter(function(file) {
return file.length !== 1 && !/^[0-9a-fA-F]{2}$/.test(file);
});
if (!dir.length) {
return prefix;
}
} catch (e) {
;
}
@ -198,19 +252,33 @@ Tput.prototype._tprefix = function(prefix, term) {
}
term = path.basename(term);
dir = find(term);
file = path.resolve(prefix, term[0], term);
try {
fs.statSync(file);
return file;
} catch (e) {
;
if (!dir) return;
if (soft) {
try {
list = fs.readdirSync(dir);
} catch (e) {
return;
}
list.forEach(function(file) {
if (file.indexOf(term) === 0) {
var diff = file.length - term.length;
if (!sfile || diff < sdiff) {
sdiff = diff;
sfile = file;
}
}
});
return sfile && (soft || sdiff === 0)
? path.resolve(dir, sfile)
: null;
}
ch = term[0].charCodeAt(0).toString(16);
if (ch.length < 2) ch = '0' + ch;
file = path.resolve(prefix, ch, term);
file = path.resolve(dir, term);
try {
fs.statSync(file);
return file;
@ -1154,6 +1222,14 @@ Tput.prototype._print = function(code, print, done) {
* Termcap
*/
Tput.cpaths = [
process.env.TERMCAP || '',
(process.env.TERMPATH || '').split(/[: ]/),
(process.env.HOME || '') + '/.termcap',
'/usr/share/misc/termcap',
'/etc/termcap'
];
Tput.prototype.readTermcap = function(term) {
var self = this
, term = term || this.terminal
@ -1162,7 +1238,9 @@ Tput.prototype.readTermcap = function(term) {
, HOME = process.env.HOME || ''
, terms
, term_
, root;
, root
, paths
, i;
// Termcap has a bunch of terminals usually stored in one file/string,
// so we need to find the one containing our desired terminal.
@ -1176,13 +1254,18 @@ Tput.prototype.readTermcap = function(term) {
term = Object.keys(terms)[0];
}
} else {
terms = this._tryCap(this.termcapFile, term)
|| this._tryCap(TERMCAP, term)
|| this._tryCap(TERMPATH && TERMPATH.split(/[: ]/), term)
|| this._tryCap(HOME + '/.termcap', term)
|| this._tryCap('/usr/share/misc/termcap', term)
|| this._tryCap('/etc/termcap', term)
|| this._tryCap(Tput.termcap, term);
paths = Tput.cpaths.slice();
if (this.termcapFile) {
paths.unshift(this.termcapFile);
}
paths.push(Tput.termcap);
for (i = 0; i < paths.length; i++) {
terms = this._tryCap(paths[i], term);
if (terms) break;
}
}
if (!terms) {