readline: fix tab completion bug
authorMatt Harrison <hi@matt-harrison.com>
Fri, 11 Sep 2015 14:47:41 +0000 (15:47 +0100)
committerJeremiah Senkpiel <fishrock123@rocketmail.com>
Sun, 20 Sep 2015 17:31:26 +0000 (10:31 -0700)
This fixes a problem where tab completion is empty when the input
stream column size is undefined. As a solution we can force maxColumns
to 1 in this scenario.

PR-URL: https://github.com/nodejs/node/pull/2816
Fixes: https://github.com/nodejs/node/issues/2396
Reviewed-By: Roman Reiss <me@silverwind.io>
lib/readline.js
test/parallel/test-readline-undefined-columns.js [new file with mode: 0644]

index 6164bcc..0bdf5c1 100644 (file)
@@ -390,7 +390,10 @@ Interface.prototype._tabComplete = function() {
         var width = completions.reduce(function(a, b) {
           return a.length > b.length ? a : b;
         }).length + 2;  // 2 space padding
-        var maxColumns = Math.floor(self.columns / width) || 1;
+        var maxColumns = Math.floor(self.columns / width);
+        if (!maxColumns || maxColumns === Infinity) {
+          maxColumns = 1;
+        }
         var group = [], c;
         for (var i = 0, compLen = completions.length; i < compLen; i++) {
           c = completions[i];
diff --git a/test/parallel/test-readline-undefined-columns.js b/test/parallel/test-readline-undefined-columns.js
new file mode 100644 (file)
index 0000000..f2baf92
--- /dev/null
@@ -0,0 +1,36 @@
+'use strict';
+
+const assert = require('assert');
+const PassThrough = require('stream').PassThrough;
+const readline = require('readline');
+
+// Checks that tab completion still works
+// when output column size is undefined
+
+const iStream = new PassThrough();
+const oStream = new PassThrough();
+
+const rli = readline.createInterface({
+  terminal: true,
+  input: iStream,
+  output: oStream,
+  completer: function(line, cb) {
+    cb(null, [['process.stdout', 'process.stdin', 'process.stderr'], line]);
+  }
+});
+
+var output = '';
+
+oStream.on('data', function(data) {
+  output += data;
+});
+
+oStream.on('end', function() {
+  const expect = 'process.stdout\r\n' +
+    'process.stdin\r\n' +
+    'process.stderr';
+  assert(new RegExp(expect).test(output));
+});
+
+iStream.write('process.std\t');
+oStream.end();