diff --git a/IPython/external/columnize.py b/IPython/external/columnize.py deleted file mode 100644 index fc70433..0000000 --- a/IPython/external/columnize.py +++ /dev/null @@ -1,160 +0,0 @@ -"""Return compact set of columns as a string with newlines for an -array of strings. - -Adapted from the routine of the same name inside cmd.py - -Author: Rocky Bernstein. -License: MIT Open Source License. -""" - -import types - -def columnize(array, displaywidth=80, colsep = ' ', - arrange_vertical=True, ljust=True, lineprefix=''): - """Return a list of strings as a compact set of columns arranged - horizontally or vertically. - - For example, for a line width of 4 characters (arranged vertically): - ['1', '2,', '3', '4'] => '1 3\n2 4\n' - - or arranged horizontally: - ['1', '2,', '3', '4'] => '1 2\n3 4\n' - - Each column is only as wide as necessary. By default, columns are - separated by two spaces - one was not legible enough. Set "colsep" - to adjust the string separate columns. Set `displaywidth' to set - the line width. - - Normally, consecutive items go down from the top to bottom from - the left-most column to the right-most. If "arrange_vertical" is - set false, consecutive items will go across, left to right, top to - bottom.""" - if not isinstance(array, list) and not isinstance(array, tuple): - raise TypeError, ( - 'array needs to be an instance of a list or a tuple') - - array = [str(i) for i in array] - - # Some degenerate cases - size = len(array) - if 0 == size: - return "\n" - elif size == 1: - return '%s\n' % str(array[0]) - - displaywidth = max(4, displaywidth - len(lineprefix)) - if arrange_vertical: - array_index = lambda nrows, row, col: nrows*col + row - # Try every row count from 1 upwards - for nrows in range(1, size): - ncols = (size+nrows-1) // nrows - colwidths = [] - totwidth = -len(colsep) - for col in range(ncols): - # get max column width for this column - colwidth = 0 - for row in range(nrows): - i = array_index(nrows, row, col) - if i >= size: break - x = array[i] - colwidth = max(colwidth, len(x)) - pass - colwidths.append(colwidth) - totwidth += colwidth + len(colsep) - if totwidth > displaywidth: - break - pass - if totwidth <= displaywidth: - break - pass - # The smallest number of rows computed and the - # max widths for each column has been obtained. - # Now we just have to format each of the - # rows. - s = '' - for row in range(nrows): - texts = [] - for col in range(ncols): - i = row + nrows*col - if i >= size: - x = "" - else: - x = array[i] - texts.append(x) - while texts and not texts[-1]: - del texts[-1] - for col in range(len(texts)): - if ljust: - texts[col] = texts[col].ljust(colwidths[col]) - else: - texts[col] = texts[col].rjust(colwidths[col]) - pass - pass - s += "%s%s\n" % (lineprefix, str(colsep.join(texts))) - pass - return s - else: - array_index = lambda nrows, row, col: ncols*(row-1) + col - # Try every column count from size downwards - prev_colwidths = [] - colwidths = [] - for ncols in range(size, 0, -1): - # Try every row count from 1 upwards - min_rows = (size+ncols-1) // ncols - for nrows in range(min_rows, size): - rounded_size = nrows * ncols - colwidths = [] - totwidth = -len(colsep) - for col in range(ncols): - # get max column width for this column - colwidth = 0 - for row in range(1, nrows+1): - i = array_index(nrows, row, col) - if i >= rounded_size: break - elif i < size: - x = array[i] - colwidth = max(colwidth, len(x)) - pass - pass - colwidths.append(colwidth) - totwidth += colwidth + len(colsep) - if totwidth >= displaywidth: - break - pass - if totwidth <= displaywidth and i >= rounded_size-1: - # Found the right nrows and ncols - nrows = row - break - elif totwidth >= displaywidth: - # Need to reduce ncols - break - pass - if totwidth <= displaywidth and i >= rounded_size-1: - break - pass - # The smallest number of rows computed and the - # max widths for each column has been obtained. - # Now we just have to format each of the - # rows. - s = '' - for row in range(1, nrows+1): - texts = [] - for col in range(ncols): - i = array_index(nrows, row, col) - if i >= size: - break - else: x = array[i] - texts.append(x) - pass - for col in range(len(texts)): - if ljust: - texts[col] = texts[col].ljust(colwidths[col]) - else: - texts[col] = texts[col].rjust(colwidths[col]) - pass - pass - s += "%s%s\n" % (lineprefix, str(colsep.join(texts))) - pass - return s - pass - diff --git a/IPython/frontend/qt/console/console_widget.py b/IPython/frontend/qt/console/console_widget.py index 2745443..aac9c09 100644 --- a/IPython/frontend/qt/console/console_widget.py +++ b/IPython/frontend/qt/console/console_widget.py @@ -5,7 +5,6 @@ import sys from PyQt4 import QtCore, QtGui # Local imports -from IPython.external.columnize import columnize from ansi_code_processor import QtAnsiCodeProcessor from completion_widget import CompletionWidget @@ -580,7 +579,7 @@ class ConsoleWidget(QtGui.QPlainTextEdit): text = self.format_as_columns(items) self._append_plain_text_keeping_prompt(text) - def format_as_columns(self, items, separator=' ', vertical=True): + def format_as_columns(self, items, separator=' '): """ Transform a list of strings into a single string with columns. Parameters @@ -591,19 +590,61 @@ class ConsoleWidget(QtGui.QPlainTextEdit): separator : str, optional [default is two spaces] The string that separates columns. - vertical: bool, optional [default True] - If set, consecutive items will be arranged from top to bottom, then - from left to right. Otherwise, consecutive items will be aranged - from left to right, then from top to bottom. - Returns ------- The formatted string. """ + # Note: this code is adapted from columnize 0.3.2. + # See http://code.google.com/p/pycolumnize/ + font_metrics = QtGui.QFontMetrics(self.font) - width = self.width() / font_metrics.width(' ') - return columnize(items, displaywidth=width, - colsep=separator, arrange_vertical=vertical) + displaywidth = max(5, (self.width() / font_metrics.width(' ')) - 1) + + # Some degenerate cases + size = len(items) + if size == 0: + return "\n" + elif size == 1: + return '%s\n' % str(items[0]) + + # Try every row count from 1 upwards + array_index = lambda nrows, row, col: nrows*col + row + for nrows in range(1, size): + ncols = (size + nrows - 1) // nrows + colwidths = [] + totwidth = -len(separator) + for col in range(ncols): + # Get max column width for this column + colwidth = 0 + for row in range(nrows): + i = array_index(nrows, row, col) + if i >= size: break + x = items[i] + colwidth = max(colwidth, len(x)) + colwidths.append(colwidth) + totwidth += colwidth + len(separator) + if totwidth > displaywidth: + break + if totwidth <= displaywidth: + break + + # The smallest number of rows computed and the max widths for each + # column has been obtained. Now we just have to format each of the rows. + string = '' + for row in range(nrows): + texts = [] + for col in range(ncols): + i = row + nrows*col + if i >= size: + texts.append('') + else: + texts.append(items[i]) + while texts and not texts[-1]: + del texts[-1] + for col in range(len(texts)): + texts[col] = texts[col].ljust(colwidths[col]) + string += "%s\n" % str(separator.join(texts)) + return string def _get_block_plain_text(self, block): """ Given a QTextBlock, return its unformatted text.