readline: allow tabs in input
If tab completion is not being used, allow user to enter tab characters. PR-URL: https://github.com/nodejs/io.js/pull/1761 Reviewed-By: Brendan Ashworth <brendan.ashworth@me.com>
This commit is contained in:
parent
6e78e5feaa
commit
4b3d493c4b
@ -47,9 +47,7 @@ function Interface(input, output, completer, terminal) {
|
|||||||
}
|
}
|
||||||
historySize = historySize || kHistorySize;
|
historySize = historySize || kHistorySize;
|
||||||
|
|
||||||
completer = completer || function() { return []; };
|
if (completer && typeof completer !== 'function') {
|
||||||
|
|
||||||
if (typeof completer !== 'function') {
|
|
||||||
throw new TypeError('Argument \'completer\' must be a function');
|
throw new TypeError('Argument \'completer\' must be a function');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,9 +70,11 @@ function Interface(input, output, completer, terminal) {
|
|||||||
this.historySize = historySize;
|
this.historySize = historySize;
|
||||||
|
|
||||||
// Check arity, 2 - for async, 1 for sync
|
// Check arity, 2 - for async, 1 for sync
|
||||||
this.completer = completer.length === 2 ? completer : function(v, callback) {
|
if (typeof completer === 'function') {
|
||||||
callback(null, completer(v));
|
this.completer = completer.length === 2 ? completer : function(v, cb) {
|
||||||
};
|
cb(null, completer(v));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
this.setPrompt('> ');
|
this.setPrompt('> ');
|
||||||
|
|
||||||
@ -344,9 +344,6 @@ Interface.prototype._normalWrite = function(b) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Interface.prototype._insertString = function(c) {
|
Interface.prototype._insertString = function(c) {
|
||||||
//BUG: Problem when adding tabs with following content.
|
|
||||||
// Perhaps the bug is in _refreshLine(). Not sure.
|
|
||||||
// A hack would be to insert spaces instead of literal '\t'.
|
|
||||||
if (this.cursor < this.line.length) {
|
if (this.cursor < this.line.length) {
|
||||||
var beg = this.line.slice(0, this.cursor);
|
var beg = this.line.slice(0, this.cursor);
|
||||||
var end = this.line.slice(this.cursor, this.line.length);
|
var end = this.line.slice(this.cursor, this.line.length);
|
||||||
@ -839,10 +836,6 @@ Interface.prototype._ttyWrite = function(s, key) {
|
|||||||
this._deleteRight();
|
this._deleteRight();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'tab': // tab completion
|
|
||||||
this._tabComplete();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'left':
|
case 'left':
|
||||||
this._moveCursor(-1);
|
this._moveCursor(-1);
|
||||||
break;
|
break;
|
||||||
@ -867,6 +860,14 @@ Interface.prototype._ttyWrite = function(s, key) {
|
|||||||
this._historyNext();
|
this._historyNext();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'tab':
|
||||||
|
// If tab completion enabled, do that...
|
||||||
|
if (typeof this.completer === 'function') {
|
||||||
|
this._tabComplete();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// falls through
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (s instanceof Buffer)
|
if (s instanceof Buffer)
|
||||||
s = s.toString('utf-8');
|
s = s.toString('utf-8');
|
||||||
|
@ -175,6 +175,59 @@ function isWarned(emitter) {
|
|||||||
assert.equal(callCount, expectedLines.length);
|
assert.equal(callCount, expectedLines.length);
|
||||||
rli.close();
|
rli.close();
|
||||||
|
|
||||||
|
// \t when there is no completer function should behave like an ordinary
|
||||||
|
// character
|
||||||
|
fi = new FakeInput();
|
||||||
|
rli = new readline.Interface({ input: fi, output: fi, terminal: true });
|
||||||
|
called = false;
|
||||||
|
rli.on('line', function(line) {
|
||||||
|
assert.equal(line, '\t');
|
||||||
|
assert.strictEqual(called, false);
|
||||||
|
called = true;
|
||||||
|
});
|
||||||
|
fi.emit('data', '\t');
|
||||||
|
fi.emit('data', '\n');
|
||||||
|
assert.ok(called);
|
||||||
|
rli.close();
|
||||||
|
|
||||||
|
// \t does not become part of the input when there is a completer function
|
||||||
|
fi = new FakeInput();
|
||||||
|
var completer = function(line) {
|
||||||
|
return [[], line];
|
||||||
|
};
|
||||||
|
rli = new readline.Interface({
|
||||||
|
input: fi,
|
||||||
|
output: fi,
|
||||||
|
terminal: true,
|
||||||
|
completer: completer
|
||||||
|
});
|
||||||
|
called = false;
|
||||||
|
rli.on('line', function(line) {
|
||||||
|
assert.equal(line, 'foo');
|
||||||
|
assert.strictEqual(called, false);
|
||||||
|
called = true;
|
||||||
|
});
|
||||||
|
fi.emit('data', '\tfo\to\t');
|
||||||
|
fi.emit('data', '\n');
|
||||||
|
assert.ok(called);
|
||||||
|
rli.close();
|
||||||
|
|
||||||
|
// constructor throws if completer is not a function or undefined
|
||||||
|
fi = new FakeInput();
|
||||||
|
assert.throws(function() {
|
||||||
|
readline.createInterface({
|
||||||
|
input: fi,
|
||||||
|
completer: 'string is not valid'
|
||||||
|
});
|
||||||
|
}, function(err) {
|
||||||
|
if (err instanceof TypeError) {
|
||||||
|
if (/Argument \'completer\' must be a function/.test(err)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
// sending a multi-byte utf8 char over multiple writes
|
// sending a multi-byte utf8 char over multiple writes
|
||||||
var buf = Buffer('☮', 'utf8');
|
var buf = Buffer('☮', 'utf8');
|
||||||
fi = new FakeInput();
|
fi = new FakeInput();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user