Skip to content

Instantly share code, notes, and snippets.

@amite
Created January 27, 2017 06:17
Show Gist options
  • Select an option

  • Save amite/c1744388d53168cf2f914e0272ed4497 to your computer and use it in GitHub Desktop.

Select an option

Save amite/c1744388d53168cf2f914e0272ed4497 to your computer and use it in GitHub Desktop.
Excerpt from readline source library
function Interface(input, output, completer, terminal) {
if (!(this instanceof Interface)) {
return new Interface(input, output, completer, terminal);
}
this._sawReturnAt = 0;
this.isCompletionEnabled = true;
this._sawKeyPress = false;
this._previousKey = null;
EventEmitter.call(this);
var historySize;
let crlfDelay;
let prompt = '> ';
if (input && input.input) {
// an options object was given
output = input.output;
completer = input.completer;
terminal = input.terminal;
historySize = input.historySize;
if (input.prompt !== undefined) {
prompt = input.prompt;
}
crlfDelay = input.crlfDelay;
input = input.input;
}
if (completer && typeof completer !== 'function') {
throw new TypeError('Argument "completer" must be a function');
}
if (historySize === undefined) {
historySize = kHistorySize;
}
if (typeof historySize !== 'number' ||
isNaN(historySize) ||
historySize < 0) {
throw new TypeError('Argument "historySize" must be a positive number');
}
// backwards compat; check the isTTY prop of the output stream
// when `terminal` was not specified
if (terminal === undefined && !(output === null || output === undefined)) {
terminal = !!output.isTTY;
}
var self = this;
this.output = output;
this.input = input;
this.historySize = historySize;
this.crlfDelay = Math.max(kMincrlfDelay,
Math.min(kMaxcrlfDelay, crlfDelay >>> 0));
// Check arity, 2 - for async, 1 for sync
if (typeof completer === 'function') {
this.completer = completer.length === 2 ? completer : function(v, cb) {
cb(null, completer(v));
};
}
this.setPrompt(prompt);
this.terminal = !!terminal;
function ondata(data) {
self._normalWrite(data);
}
function onend() {
if (typeof self._line_buffer === 'string' &&
self._line_buffer.length > 0) {
self.emit('line', self._line_buffer);
}
self.close();
}
function ontermend() {
if (typeof self.line === 'string' && self.line.length > 0) {
self.emit('line', self.line);
}
self.close();
}
function onkeypress(s, key) {
self._ttyWrite(s, key);
if (key && key.sequence) {
// if the key.sequence is half of a surrogate pair
// (>= 0xd800 and <= 0xdfff), refresh the line so
// the character is displayed appropriately.
const ch = key.sequence.codePointAt(0);
if (ch >= 0xd800 && ch <= 0xdfff)
self._refreshLine();
}
}
function onresize() {
self._refreshLine();
}
if (!this.terminal) {
input.on('data', ondata);
input.on('end', onend);
self.once('close', function() {
input.removeListener('data', ondata);
input.removeListener('end', onend);
});
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
this._decoder = new StringDecoder('utf8');
} else {
emitKeypressEvents(input, this);
// input usually refers to stdin
input.on('keypress', onkeypress);
input.on('end', ontermend);
// Current line
this.line = '';
this._setRawMode(true);
this.terminal = true;
// Cursor position on the line.
this.cursor = 0;
this.history = [];
this.historyIndex = -1;
if (output !== null && output !== undefined)
output.on('resize', onresize);
self.once('close', function() {
input.removeListener('keypress', onkeypress);
input.removeListener('end', ontermend);
if (output !== null && output !== undefined) {
output.removeListener('resize', onresize);
}
});
}
input.resume();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment