add --fit-width option to table formatter

Change the table formatter to not fit the terminal width by default. Add
a new --fit-width option to turn on that behavior. Width fitting is
implied if the --max-width argument is used. The old behavior can be
restored by setting CLIFF_FIT_WIDTH=1 in the shell environment.

Change-Id: I7b41b38ed25def416605d38c962aea55de842529
Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
Doug Hellmann 2017-06-07 17:02:46 -04:00 committed by Dean Troyer
parent 807c910c4f
commit 180d7ce3ce
2 changed files with 40 additions and 12 deletions

View File

@ -56,6 +56,15 @@ class TableFormatter(base.ListFormatter, base.SingleFormatter):
'use the CLIFF_MAX_TERM_WIDTH environment variable, '
'but the parameter takes precedence.'),
)
group.add_argument(
'--fit-width',
action='store_true',
default=bool(int(os.environ.get('CLIFF_FIT_WIDTH', 0))),
help=('Fit the table to the display width. '
'Implied if --max-width greater than 0. '
'Set the environment variable CLIFF_FIT_WIDTH=1 '
'to always enable'),
)
group.add_argument(
'--print-empty',
action='store_true',
@ -96,7 +105,8 @@ class TableFormatter(base.ListFormatter, base.SingleFormatter):
# preference to wrapping columns smaller than 8 characters.
min_width = 8
self._assign_max_widths(
stdout, x, int(parsed_args.max_width), min_width)
stdout, x, int(parsed_args.max_width), min_width,
parsed_args.fit_width)
formatted = x.get_string()
stdout.write(formatted)
@ -120,7 +130,8 @@ class TableFormatter(base.ListFormatter, base.SingleFormatter):
# the Field column readable.
min_width = 16
self._assign_max_widths(
stdout, x, int(parsed_args.max_width), min_width)
stdout, x, int(parsed_args.max_width), min_width,
parsed_args.fit_width)
formatted = x.get_string()
stdout.write(formatted)
@ -164,12 +175,15 @@ class TableFormatter(base.ListFormatter, base.SingleFormatter):
return shrink_fields, shrink_remaining
@staticmethod
def _assign_max_widths(stdout, x, max_width, min_width=0):
def _assign_max_widths(stdout, x, max_width, min_width=0, fit_width=False):
if min_width:
x.min_width = min_width
if max_width > 0:
term_width = max_width
elif not fit_width:
# Fitting is disabled
return
else:
term_width = utils.terminal_width(stdout)
if not term_width:

View File

@ -25,7 +25,8 @@ from cliff.tests import test_columns
class args(object):
def __init__(self, max_width=0, print_empty=False):
def __init__(self, max_width=0, print_empty=False, fit_width=False):
self.fit_width = fit_width
if max_width > 0:
self.max_width = max_width
else:
@ -133,7 +134,7 @@ class TestTerminalWidth(base.TestBase):
d = ('A', 'B', 'C', 'd' * 77)
self.assertEqual(
self.expected_ml_80_val,
_table_tester_helper(c, d, extra_args=args()),
_table_tester_helper(c, d, extra_args=args(fit_width=True)),
)
@mock.patch('cliff.utils.terminal_width')
@ -223,7 +224,10 @@ class TestMaxWidth(base.TestBase):
| | field |
+--------------------------+-----------------------------------------+
''')
self.assertEqual(expected, _table_tester_helper(c, d))
self.assertEqual(
expected,
_table_tester_helper(c, d, extra_args=['--fit-width']),
)
@mock.patch('cliff.utils.terminal_width')
def test_50(self, tw):
@ -240,7 +244,10 @@ class TestMaxWidth(base.TestBase):
| ame | longer than the field |
+-----------------------+------------------------+
''')
self.assertEqual(expected, _table_tester_helper(c, d))
self.assertEqual(
expected,
_table_tester_helper(c, d, extra_args=['--fit-width']),
)
@mock.patch('cliff.utils.terminal_width')
def test_10(self, tw):
@ -259,7 +266,10 @@ class TestMaxWidth(base.TestBase):
| | field |
+------------------+------------------+
''')
self.assertEqual(expected, _table_tester_helper(c, d))
self.assertEqual(
expected,
_table_tester_helper(c, d, extra_args=['--fit-width']),
)
class TestListFormatter(base.TestBase):
@ -390,7 +400,8 @@ class TestListFormatter(base.TestBase):
def test_max_width_50(self, tw):
# resize 1 column
l = tw.return_value = 50
actual = _table_tester_helper(self._col_names, self._col_data)
actual = _table_tester_helper(self._col_names, self._col_data,
extra_args=['--fit-width'])
self.assertEqual(self._expected_mv[l], actual)
self.assertEqual(l, len(actual.splitlines()[0]))
@ -398,7 +409,8 @@ class TestListFormatter(base.TestBase):
def test_max_width_45(self, tw):
# resize 2 columns
l = tw.return_value = 45
actual = _table_tester_helper(self._col_names, self._col_data)
actual = _table_tester_helper(self._col_names, self._col_data,
extra_args=['--fit-width'])
self.assertEqual(self._expected_mv[l], actual)
self.assertEqual(l, len(actual.splitlines()[0]))
@ -406,7 +418,8 @@ class TestListFormatter(base.TestBase):
def test_max_width_40(self, tw):
# resize all columns
l = tw.return_value = 40
actual = _table_tester_helper(self._col_names, self._col_data)
actual = _table_tester_helper(self._col_names, self._col_data,
extra_args=['--fit-width'])
self.assertEqual(self._expected_mv[l], actual)
self.assertEqual(l, len(actual.splitlines()[0]))
@ -414,7 +427,8 @@ class TestListFormatter(base.TestBase):
def test_max_width_10(self, tw):
# resize all columns limited by min_width=8
l = tw.return_value = 10
actual = _table_tester_helper(self._col_names, self._col_data)
actual = _table_tester_helper(self._col_names, self._col_data,
extra_args=['--fit-width'])
self.assertEqual(self._expected_mv[l], actual)
# 3 columns each 8 wide, plus table spacing and borders
expected_width = 11 * 3 + 1