}
historySize = historySize || kHistorySize;
- completer = completer || function() { return []; };
-
- if (typeof completer !== 'function') {
+ if (completer && typeof completer !== 'function') {
throw new TypeError('Argument \'completer\' must be a function');
}
this.historySize = historySize;
// Check arity, 2 - for async, 1 for sync
- this.completer = completer.length === 2 ? completer : function(v, callback) {
- callback(null, completer(v));
- };
+ if (typeof completer === 'function') {
+ this.completer = completer.length === 2 ? completer : function(v, cb) {
+ cb(null, completer(v));
+ };
+ }
this.setPrompt('> ');
};
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) {
var beg = this.line.slice(0, this.cursor);
var end = this.line.slice(this.cursor, this.line.length);
this._deleteRight();
break;
- case 'tab': // tab completion
- this._tabComplete();
- break;
-
case 'left':
this._moveCursor(-1);
break;
this._historyNext();
break;
+ case 'tab':
+ // If tab completion enabled, do that...
+ if (typeof this.completer === 'function') {
+ this._tabComplete();
+ break;
+ }
+ // falls through
+
default:
if (s instanceof Buffer)
s = s.toString('utf-8');
assert.equal(callCount, expectedLines.length);
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
var buf = Buffer('☮', 'utf8');
fi = new FakeInput();