diff --git a/CHANGELOG b/CHANGELOG index 06192982a..929b56001 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,8 @@ slice operator. ### Changed - Renamed "chromium" style to "yapf". Chromium will now use PEP-8 directly. +- `CONTINUATION_ALIGN_STYLE` with `FIXED` or `VALIGN-RIGHT` now works with + space indentation. ### Fixed - Honor a disable directive at the end of a multiline comment. - Don't require splitting before comments in a list when diff --git a/README.rst b/README.rst index 316d8a0c6..e2db75128 100644 --- a/README.rst +++ b/README.rst @@ -434,15 +434,12 @@ Knobs - ``SPACE``: Use spaces for continuation alignment. This is default behavior. - ``FIXED``: Use fixed number (CONTINUATION_INDENT_WIDTH) of columns - (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs) for continuation - alignment. - - ``VALIGN-RIGHT``: Vertically align continuation lines with indent - characters. Slightly right (one more indent character) if cannot + (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs or CONTINUATION_INDENT_WIDTH + spaces) for continuation alignment. + - ``VALIGN-RIGHT``: Vertically align continuation lines to multiple of + INDENT_WIDTH columns. Slightly right (one tab or a few spaces) if cannot vertically align continuation lines with indent characters. - For options ``FIXED``, and ``VALIGN-RIGHT`` are only available when - ``USE_TABS`` is enabled. - ``CONTINUATION_INDENT_WIDTH`` Indent width used for line continuations. diff --git a/yapf/yapflib/format_decision_state.py b/yapf/yapflib/format_decision_state.py index e3057849c..577ae10d4 100644 --- a/yapf/yapflib/format_decision_state.py +++ b/yapf/yapflib/format_decision_state.py @@ -921,6 +921,18 @@ def _CalculateParameterListState(self, newline): return penalty + def _IndentWithContinuationAlignStyle(self, column): + if column == 0: + return column + align_style = style.Get('CONTINUATION_ALIGN_STYLE') + if align_style == 'FIXED': + return ((self.line.depth * style.Get('INDENT_WIDTH')) + + style.Get('CONTINUATION_INDENT_WIDTH')) + if align_style == 'VALIGN-RIGHT': + indent_width = style.Get('INDENT_WIDTH') + return indent_width * int((column + indent_width - 1) / indent_width) + return column + def _GetNewlineColumn(self): """Return the new column on the newline.""" current = self.next_token @@ -934,8 +946,11 @@ def _GetNewlineColumn(self): elif current.spaces_required_before > 2 or self.line.disable: return current.spaces_required_before + cont_aligned_indent = self._IndentWithContinuationAlignStyle( + top_of_stack.indent) + if current.OpensScope(): - return top_of_stack.indent if self.paren_level else self.first_indent + return cont_aligned_indent if self.paren_level else self.first_indent if current.ClosesScope(): if (previous.OpensScope() or @@ -973,7 +988,7 @@ def _GetNewlineColumn(self): format_token.Subtype.PARAMETER_START in previous.subtypes)): return top_of_stack.indent + style.Get('CONTINUATION_INDENT_WIDTH') - return top_of_stack.indent + return cont_aligned_indent def _FitsOnLine(self, start, end): """Determines if line between start and end can fit on the current line.""" diff --git a/yapf/yapflib/format_token.py b/yapf/yapflib/format_token.py index e6af9422f..0ed983fed 100644 --- a/yapf/yapflib/format_token.py +++ b/yapf/yapflib/format_token.py @@ -62,25 +62,21 @@ class Subtype(object): PARAMETER_STOP = 26 -def _TabbedContinuationAlignPadding(spaces, align_style, tab_width, - continuation_indent_width): +def _TabbedContinuationAlignPadding(spaces, align_style, tab_width): """Build padding string for continuation alignment in tabbed indentation. Arguments: spaces: (int) The number of spaces to place before the token for alignment. align_style: (str) The alignment style for continuation lines. tab_width: (int) Number of columns of each tab character. - continuation_indent_width: (int) Indent columns for line continuations. Returns: A padding string for alignment with style specified by align_style option. """ - if align_style == 'FIXED': + if align_style in ('FIXED', 'VALIGN-RIGHT'): if spaces > 0: - return '\t' * int(continuation_indent_width / tab_width) + return '\t' * int((spaces + tab_width - 1) / tab_width) return '' - elif align_style == 'VALIGN-RIGHT': - return '\t' * int((spaces + tab_width - 1) / tab_width) return ' ' * spaces @@ -171,7 +167,7 @@ def AddWhitespacePrefix(self, newlines_before, spaces=0, indent_level=0): if newlines_before > 0: indent_before = '\t' * indent_level + _TabbedContinuationAlignPadding( spaces, style.Get('CONTINUATION_ALIGN_STYLE'), - style.Get('INDENT_WIDTH'), style.Get('CONTINUATION_INDENT_WIDTH')) + style.Get('INDENT_WIDTH')) else: indent_before = '\t' * indent_level + ' ' * spaces else: diff --git a/yapf/yapflib/style.py b/yapf/yapflib/style.py index 4e0836549..7cb31805a 100644 --- a/yapf/yapflib/style.py +++ b/yapf/yapflib/style.py @@ -128,14 +128,11 @@ def method(): - SPACE: Use spaces for continuation alignment. This is default behavior. - FIXED: Use fixed number (CONTINUATION_INDENT_WIDTH) of columns - (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs) for continuation - alignment. - - VALIGN-RIGHT: Vertically align continuation lines with indent - characters. Slightly right (one more indent character) if cannot - vertically align continuation lines with indent characters. - - Options FIXED and VALIGN-RIGHT are only available when USE_TABS is - enabled."""), + (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs or + CONTINUATION_INDENT_WIDTH spaces) for continuation alignment. + - VALIGN-RIGHT: Vertically align continuation lines to multiple of + INDENT_WIDTH columns. Slightly right (one tab or a few spaces) if + cannot vertically align continuation lines with indent characters."""), CONTINUATION_INDENT_WIDTH=textwrap.dedent("""\ Indent width used for line continuations."""), DEDENT_CLOSING_BRACKETS=textwrap.dedent("""\ diff --git a/yapftests/format_token_test.py b/yapftests/format_token_test.py index 2f6f973ba..b4c715107 100644 --- a/yapftests/format_token_test.py +++ b/yapftests/format_token_test.py @@ -26,40 +26,40 @@ class TabbedContinuationAlignPaddingTest(unittest.TestCase): def testSpace(self): align_style = 'SPACE' - pad = format_token._TabbedContinuationAlignPadding(0, align_style, 2, 4) + pad = format_token._TabbedContinuationAlignPadding(0, align_style, 2) self.assertEqual(pad, '') - pad = format_token._TabbedContinuationAlignPadding(2, align_style, 2, 4) + pad = format_token._TabbedContinuationAlignPadding(2, align_style, 2) self.assertEqual(pad, ' ' * 2) - pad = format_token._TabbedContinuationAlignPadding(5, align_style, 2, 4) + pad = format_token._TabbedContinuationAlignPadding(5, align_style, 2) self.assertEqual(pad, ' ' * 5) def testFixed(self): align_style = 'FIXED' - pad = format_token._TabbedContinuationAlignPadding(0, align_style, 4, 8) + pad = format_token._TabbedContinuationAlignPadding(0, align_style, 4) self.assertEqual(pad, '') - pad = format_token._TabbedContinuationAlignPadding(2, align_style, 4, 8) - self.assertEqual(pad, '\t' * 2) + pad = format_token._TabbedContinuationAlignPadding(2, align_style, 4) + self.assertEqual(pad, '\t') - pad = format_token._TabbedContinuationAlignPadding(5, align_style, 4, 8) + pad = format_token._TabbedContinuationAlignPadding(5, align_style, 4) self.assertEqual(pad, '\t' * 2) def testVAlignRight(self): align_style = 'VALIGN-RIGHT' - pad = format_token._TabbedContinuationAlignPadding(0, align_style, 4, 8) + pad = format_token._TabbedContinuationAlignPadding(0, align_style, 4) self.assertEqual(pad, '') - pad = format_token._TabbedContinuationAlignPadding(2, align_style, 4, 8) + pad = format_token._TabbedContinuationAlignPadding(2, align_style, 4) self.assertEqual(pad, '\t') - pad = format_token._TabbedContinuationAlignPadding(4, align_style, 4, 8) + pad = format_token._TabbedContinuationAlignPadding(4, align_style, 4) self.assertEqual(pad, '\t') - pad = format_token._TabbedContinuationAlignPadding(5, align_style, 4, 8) + pad = format_token._TabbedContinuationAlignPadding(5, align_style, 4) self.assertEqual(pad, '\t' * 2) diff --git a/yapftests/yapf_test.py b/yapftests/yapf_test.py index 9bd09ac43..d68563397 100644 --- a/yapftests/yapf_test.py +++ b/yapftests/yapf_test.py @@ -1269,8 +1269,8 @@ def foo_function(arg1, arg2, arg3): return ['hello', 'world',] """ expected_formatted_code = """\ -def foo_function(arg1, arg2, - arg3): +def foo_function( + arg1, arg2, arg3): return [ 'hello', 'world', @@ -1312,6 +1312,60 @@ def foo_function(arg1, arg2, INDENT_WIDTH=4 CONTINUATION_INDENT_WIDTH=8 CONTINUATION_ALIGN_STYLE = valign-right +""" + with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style={0}'.format(stylepath)]) + + def testUseSpacesContinuationAlignStyleFixed(self): + unformatted_code = """\ +def foo_function(arg1, arg2, arg3): + return ['hello', 'world',] +""" + expected_formatted_code = """\ +def foo_function( + arg1, arg2, arg3): + return [ + 'hello', + 'world', + ] +""" + style_contents = u"""\ +[style] +based_on_style = chromium +COLUMN_LIMIT=32 +INDENT_WIDTH=4 +CONTINUATION_INDENT_WIDTH=8 +CONTINUATION_ALIGN_STYLE = fixed +""" + with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style={0}'.format(stylepath)]) + + def testUseSpacesContinuationAlignStyleVAlignRight(self): + unformatted_code = """\ +def foo_function(arg1, arg2, arg3): + return ['hello', 'world',] +""" + expected_formatted_code = """\ +def foo_function(arg1, arg2, + arg3): + return [ + 'hello', + 'world', + ] +""" + style_contents = u"""\ +[style] +based_on_style = chromium +COLUMN_LIMIT=32 +INDENT_WIDTH=4 +CONTINUATION_INDENT_WIDTH=8 +CONTINUATION_ALIGN_STYLE = valign-right """ with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: self.assertYapfReformats(