refactor
This commit is contained in:
parent
df0aeb5005
commit
d5208b758f
189
lib/tput.js
189
lib/tput.js
|
@ -33,54 +33,39 @@ function Tput(options) {
|
||||||
|
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.term = options.term || process.env.TERM;
|
this.term = options.term || process.env.TERM;
|
||||||
this.data = null;
|
|
||||||
this.info = {};
|
|
||||||
this.methods = null;
|
|
||||||
this.termcap = null;
|
|
||||||
|
|
||||||
this.debug = options.debug;
|
this.debug = options.debug;
|
||||||
this.padding = options.padding;
|
this.padding = options.padding;
|
||||||
this.extended = options.extended;
|
this.extended = options.extended;
|
||||||
this.printf = options.printf;
|
this.printf = options.printf;
|
||||||
|
this.termcap = options.termcap;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (options.termcap) {
|
if (this.termcap) {
|
||||||
this.readTermcap();
|
|
||||||
this.compileTermcap();
|
this.compileTermcap();
|
||||||
} else {
|
} else {
|
||||||
this.readTerminfo();
|
this.compileTerminfo();
|
||||||
this.compile();
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.fallback();
|
this.term = 'vt102';
|
||||||
|
this.compileTermcap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Tput.prototype.fallback = function() {
|
/**
|
||||||
delete this.term;
|
* Terminfo
|
||||||
delete this.data;
|
*/
|
||||||
delete this.info;
|
|
||||||
delete this.methods;
|
|
||||||
delete this.termcap;
|
|
||||||
|
|
||||||
this.term = 'vt102';
|
Tput.prototype.readTerminfo = function(data) {
|
||||||
this.readTermcap(Tput.vt102);
|
if (!data) {
|
||||||
this.compileTermcap();
|
var file = path.resolve(
|
||||||
};
|
'/usr/share/terminfo',
|
||||||
|
path.basename(this.term[0]),
|
||||||
Tput.prototype.readTerminfo = function() {
|
path.basename(this.term)
|
||||||
// if (this.data) return;
|
);
|
||||||
|
data = fs.readFileSync(file);
|
||||||
var file = path.resolve(
|
}
|
||||||
'/usr/share/terminfo',
|
return this.parseTerminfo(data);
|
||||||
path.basename(this.term[0]),
|
|
||||||
path.basename(this.term)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.data = fs.readFileSync(file);
|
|
||||||
this.info = this.parseTerminfo(this.data);
|
|
||||||
|
|
||||||
return this.info;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -200,10 +185,10 @@ Tput.prototype.parseTerminfo = function(data) {
|
||||||
l = data.length;
|
l = data.length;
|
||||||
if (i < l - 1) {
|
if (i < l - 1) {
|
||||||
var extended = this.parseExtended(data.slice(i));
|
var extended = this.parseExtended(data.slice(i));
|
||||||
|
// info.header.extended = extended.header;
|
||||||
['bools', 'numbers', 'strings'].forEach(function(key) {
|
['bools', 'numbers', 'strings'].forEach(function(key) {
|
||||||
merge(info[key], extended[key]);
|
merge(info[key], extended[key]);
|
||||||
});
|
});
|
||||||
// info.extendedHexer = extended.header;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,78 +372,86 @@ Tput.prototype.parseExtended = function(data) {
|
||||||
return info;
|
return info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Tput.prototype.compileTerminfo = function() {
|
||||||
|
return this.compile.apply(this, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiler - terminfo cap->javascript
|
* Compiler - terminfo cap->javascript
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Tput.prototype.compile = function(key) {
|
Tput.prototype.compile = function(info, inject) {
|
||||||
var self = this
|
var self = this;
|
||||||
, info = this.info;
|
|
||||||
|
if (arguments.length === 0) {
|
||||||
|
info = this.readTerminfo();
|
||||||
|
}
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
throw new Error('Terminal not found.');
|
throw new Error('Terminal not found.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.debug) {
|
if (this.debug) {
|
||||||
console.log(this.info);
|
console.log(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.methods = {};
|
info.all = {};
|
||||||
this.info.all = {};
|
info.methods = {};
|
||||||
|
|
||||||
Object.keys(info.bools).forEach(function(key) {
|
['bools', 'numbers', 'strings'].forEach(function(type) {
|
||||||
info.all[key] = info.bools[key];
|
Object.keys(info[type]).forEach(function(key) {
|
||||||
});
|
info.all[key] = info[type][key];
|
||||||
|
if (self.debug) {
|
||||||
Object.keys(info.numbers).forEach(function(key) {
|
console.log('Compiling %s: %s', key, JSON.stringify(info.all[key]));
|
||||||
info.all[key] = info.numbers[key];
|
}
|
||||||
});
|
info.methods[key] = self._compile(info.all[key]);
|
||||||
|
});
|
||||||
Object.keys(info.strings).forEach(function(key) {
|
|
||||||
info.all[key] = info.strings[key];
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.keys(info.all).forEach(function(key) {
|
|
||||||
if (self.debug) {
|
|
||||||
console.log('Compiling %s: %s', key, JSON.stringify(info.all[key]));
|
|
||||||
}
|
|
||||||
self.methods[key] = self._compile(info.all[key]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Tput.bools.forEach(function(key) {
|
Tput.bools.forEach(function(key) {
|
||||||
if (self.methods[key] == null) self.methods[key] = false;
|
if (info.methods[key] == null) info.methods[key] = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
Tput.numbers.forEach(function(key) {
|
Tput.numbers.forEach(function(key) {
|
||||||
if (self.methods[key] == null) self.methods[key] = -1;
|
if (info.methods[key] == null) info.methods[key] = -1;
|
||||||
});
|
});
|
||||||
|
|
||||||
Tput.strings.forEach(function(key) {
|
Tput.strings.forEach(function(key) {
|
||||||
if (!self.methods[key]) self.methods[key] = noop;
|
if (!info.methods[key]) info.methods[key] = noop;
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.keys(this.methods).forEach(function(key) {
|
Object.keys(info.methods).forEach(function(key) {
|
||||||
var alias = Tput.alias[key];
|
var alias = Tput.alias[key];
|
||||||
if (alias) {
|
if (!alias) return;
|
||||||
if (!Array.isArray(alias)) alias = [alias];
|
if (!Array.isArray(alias)) alias = [alias];
|
||||||
alias.forEach(function(alias) {
|
alias.forEach(function(alias) {
|
||||||
if (self.methods[alias] && alias !== key && alias !== 'ML') {
|
if (info.methods[alias] && alias !== key && alias !== 'ML') {
|
||||||
// We can ignore `lines` and `ML` here.
|
// We can ignore `lines` and `ML` here.
|
||||||
throw new Error('Alias collision: ' + key + ' -> ' + alias);
|
throw new Error('Alias collision: ' + key + ' -> ' + alias);
|
||||||
}
|
}
|
||||||
self.methods[alias] = self.methods[key];
|
info.methods[alias] = info.methods[key];
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.keys(self.methods).forEach(function(key) {
|
if (inject !== false) {
|
||||||
if (typeof self.methods[key] !== 'function') {
|
this.inject(info);
|
||||||
self[key] = self.methods[key];
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tput.prototype.inject = function(info) {
|
||||||
|
var self = this
|
||||||
|
, methods = info.methods || info;
|
||||||
|
|
||||||
|
Object.keys(methods).forEach(function(key) {
|
||||||
|
if (typeof methods[key] !== 'function') {
|
||||||
|
self[key] = methods[key];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self[key] = function() {
|
self[key] = function() {
|
||||||
var args = Array.prototype.slice.call(arguments);
|
var args = Array.prototype.slice.call(arguments);
|
||||||
return self.methods[key].call(self, args);
|
return methods[key].call(self, args);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -871,7 +864,7 @@ Tput.prototype._compile = function(val) {
|
||||||
// arithmetic is possible using the stack.
|
// arithmetic is possible using the stack.
|
||||||
|
|
||||||
// $ man termcap
|
// $ man termcap
|
||||||
if (this.options.termcap) {
|
if (this.termcap) {
|
||||||
// %r Single parameter capability
|
// %r Single parameter capability
|
||||||
if (read(/^%r/)) {
|
if (read(/^%r/)) {
|
||||||
expr('()');
|
expr('()');
|
||||||
|
@ -991,19 +984,13 @@ Tput.prototype._parsePadding = function(code, print, done) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Tput.prototype.readTermcap = function(data) {
|
Tput.prototype.readTermcap = function(data) {
|
||||||
// if (this.termcap) return;
|
var data = data
|
||||||
|
|
||||||
this.termcap = {};
|
|
||||||
|
|
||||||
this.termcap.data = data
|
|
||||||
|| process.env.TERMCAP
|
|| process.env.TERMCAP
|
||||||
|| tryRead('/etc/termcap')
|
|| tryRead('/etc/termcap')
|
||||||
|| Tput.vt102;
|
|| Tput.vt102;
|
||||||
|
|
||||||
this.termcap.terms = this.parseTermcap(this.termcap.data);
|
var terms = this.parseTermcap(data);
|
||||||
this.termcap.info = this.termcap.terms[this.term];
|
return terms[this.term];
|
||||||
|
|
||||||
return this.termcap;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1092,15 +1079,18 @@ Tput.prototype.parseTermcap = function(data) {
|
||||||
* man termcap
|
* man termcap
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Tput.prototype.translateTermcap = function() {
|
Tput.prototype.translateTermcap = function(info) {
|
||||||
var self = this
|
var self = this
|
||||||
, info = this.termcap.info
|
|
||||||
, out = {};
|
, out = {};
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
throw new Error('Terminal not found.');
|
throw new Error('Terminal not found.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.debug) {
|
||||||
|
console.log(info);
|
||||||
|
}
|
||||||
|
|
||||||
['name', 'names', 'desc'].forEach(function(key) {
|
['name', 'names', 'desc'].forEach(function(key) {
|
||||||
out[key] = info[key];
|
out[key] = info[key];
|
||||||
});
|
});
|
||||||
|
@ -1112,13 +1102,15 @@ Tput.prototype.translateTermcap = function() {
|
||||||
|
|
||||||
Object.keys(alias).forEach(function(key) {
|
Object.keys(alias).forEach(function(key) {
|
||||||
var a = alias[key].slice()
|
var a = alias[key].slice()
|
||||||
, tc = a.terminfo || a.splice(1, 1)[0];
|
, tc = a.termcap || a.splice(1, 1)[0];
|
||||||
out[tc] = [key].concat(a);
|
out[tc] = [key].concat(a);
|
||||||
});
|
});
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// Translate termcap cap names to terminfo cap names.
|
||||||
|
// e.g. `up` -> `cursor_up`
|
||||||
['bools', 'numbers', 'strings'].forEach(function(key) {
|
['bools', 'numbers', 'strings'].forEach(function(key) {
|
||||||
out[key] = {};
|
out[key] = {};
|
||||||
Object.keys(info[key]).forEach(function(cap) {
|
Object.keys(info[key]).forEach(function(cap) {
|
||||||
|
@ -1131,9 +1123,14 @@ Tput.prototype.translateTermcap = function() {
|
||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
Tput.prototype.compileTermcap = function() {
|
Tput.prototype.compileTermcap = function(info) {
|
||||||
this.info = this.translateTermcap();
|
if (arguments.length === 0) {
|
||||||
this.compile();
|
info = this.readTermcap();
|
||||||
|
}
|
||||||
|
|
||||||
|
info = this.translateTermcap(info);
|
||||||
|
|
||||||
|
return this.compile(info);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1291,7 +1288,8 @@ delete Tput.alias.numbers;
|
||||||
merge(Tput.alias, Tput.alias.strings);
|
merge(Tput.alias, Tput.alias.strings);
|
||||||
delete Tput.alias.strings;
|
delete Tput.alias.strings;
|
||||||
|
|
||||||
// Make sure there are no collisions between cap and tcap.
|
// Make sure there are no collisions between terminfo names
|
||||||
|
// and termcap names. Terminfo takes precedence.
|
||||||
Tput._vec = Object.keys(Tput.alias).map(function(key) {
|
Tput._vec = Object.keys(Tput.alias).map(function(key) {
|
||||||
return Array.isArray(Tput.alias[key])
|
return Array.isArray(Tput.alias[key])
|
||||||
? Tput.alias[key][0]
|
? Tput.alias[key][0]
|
||||||
|
@ -1306,10 +1304,13 @@ Object.keys(Tput.alias).forEach(function(key) {
|
||||||
var alias = Tput.alias[key]
|
var alias = Tput.alias[key]
|
||||||
, tcap = alias[1];
|
, tcap = alias[1];
|
||||||
|
|
||||||
|
alias.name = key;
|
||||||
|
alias.terminfo = alias[0];
|
||||||
|
alias.termcap = alias[1];
|
||||||
|
|
||||||
if (!tcap) return;
|
if (!tcap) return;
|
||||||
|
|
||||||
if (~Tput._vec.indexOf(tcap)) {
|
if (~Tput._vec.indexOf(tcap)) {
|
||||||
alias.termcap = tcap;
|
|
||||||
alias.splice(1, 1);
|
alias.splice(1, 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1319,7 +1320,7 @@ assert.notEqual(Tput.alias.exit_delete_mode[1], 'ed');
|
||||||
// assert.notEqual(Tput.alias.set_lr_margin[1], 'ML');
|
// assert.notEqual(Tput.alias.set_lr_margin[1], 'ML');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fallback Termcap
|
* Fallback Termcap Entry
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Tput.vt102 = ''
|
Tput.vt102 = ''
|
||||||
|
|
Loading…
Reference in New Issue