diff --git a/lib/readline.js b/lib/readline.js index 2562124b60..d4b1ea60ad 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -41,7 +41,6 @@ function Interface (output, completer) { // Check process.env.TERM ? stdio.setRawMode(true); this._tty = true; - this.columns = stdio.getColumns(); // Cursor position on the line. this.cursor = 0; @@ -53,6 +52,11 @@ function Interface (output, completer) { inherits(Interface, EventEmitter); +Interface.prototype.__defineGetter__("columns", function () { + if (this._tty) { + return stdio.getColumns(); + } +}); Interface.prototype.setPrompt = function (prompt, length) { this._prompt = prompt; @@ -156,14 +160,48 @@ Interface.prototype._tabComplete = function () { self._insertString(completions[0].slice(completeOn.length)); self._refreshLine(); } else { - //TODO: Multi-column display. Request to show if more than N completions. - self.output.write("\n"); - completions.forEach(function (c) { - //TODO: try using '\r\n' instead of the following goop for getting to column 0 - self.output.write('\x1b[0G'); - self.output.write(c + "\n"); - }) - self.output.write('\n'); + //TODO: If there is a common prefix to all matches (e.g. Python `sys.exi`) then apply that portion + self.output.write("\r\n"); + var width = completions.reduce(function(a, b) { + return a.length > b.length ? a : b; + }).length + 2; // 2 space padding + var maxColumns = Math.floor(this.columns / width) || 1; + + function handleGroup(group) { + if (group.length == 0) { + return; + } + var minRows = Math.ceil(group.length / maxColumns); + for (var row = 0; row < minRows; row++) { + for (var col = 0; col < maxColumns; col++) { + var idx = row * maxColumns + col; + if (idx >= group.length) { + break; + } + var item = group[idx]; + self.output.write(item); + if (col < maxColumns - 1) { + for (var s = 0; s < width - item.length; s++) { + self.output.write(' '); + } + } + } + self.output.write('\r\n'); + } + self.output.write('\r\n'); + } + + var group = [], c; + for (var i = 0; i < completions.length; i++) { + c = completions[i]; + if (c === "") { + handleGroup(group); + group = []; + } else { + group.push(c); + } + } + handleGroup(group); self._refreshLine(); } }