diff --git a/CHANGELOG b/CHANGELOG index 2195884e7..126586f9b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,7 @@ parameter list is formatted, keeping state along the way. This helps when supporting Python 3 type annotations. - Catch and report `UnicodeDecodeError` exceptions. +- `CONTINUATION_ALIGN_STYLE = FIXED` now work with space indentation. ### Fixed - Format subscript lists so that splits are essentially free after a comma. - Don't add a space between a string and its subscript. diff --git a/README.rst b/README.rst index 6ab3132f5..e59985bee 100644 --- a/README.rst +++ b/README.rst @@ -424,14 +424,13 @@ 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. + (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs or CONTINUATION_INDENT_WIDTH + spaces) 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. - For options ``FIXED``, and ``VALIGN-RIGHT`` are only available when - ``USE_TABS`` is enabled. + The ``VALIGN-RIGHT`` option only available when ``USE_TABS`` is enabled. ``CONTINUATION_INDENT_WIDTH`` Indent width used for line continuations. diff --git a/yapf/yapflib/format_token.py b/yapf/yapflib/format_token.py index 79b2b5c92..7c8d1cc80 100644 --- a/yapf/yapflib/format_token.py +++ b/yapf/yapflib/format_token.py @@ -84,6 +84,25 @@ def _TabbedContinuationAlignPadding(spaces, align_style, tab_width, return ' ' * spaces +def _SpacedContinuationAlignPadding(spaces, align_style, + continuation_indent_width): + """Build padding string for continuation alignment in space indentation. + + Arguments: + spaces: (int) The number of spaces to place before the token for alignment. + align_style: (str) The alignment style for continuation lines. + 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 spaces > 0: + return ' ' * continuation_indent_width + return '' + return ' ' * spaces + + class FormatToken(object): """A wrapper around pytree Leaf nodes. @@ -175,8 +194,14 @@ def AddWhitespacePrefix(self, newlines_before, spaces=0, indent_level=0): else: indent_before = '\t' * indent_level + ' ' * spaces else: - indent_before = (' ' * indent_level * style.Get('INDENT_WIDTH') + - ' ' * spaces) + if newlines_before > 0: + indent_before = (' ' * indent_level * style.Get('INDENT_WIDTH') + + _SpacedContinuationAlignPadding( + spaces, style.Get('CONTINUATION_ALIGN_STYLE'), + style.Get('CONTINUATION_INDENT_WIDTH'))) + else: + indent_before = (' ' * indent_level * style.Get('INDENT_WIDTH') + + ' ' * spaces) if self.is_comment: comment_lines = [s.lstrip() for s in self.value.splitlines()] diff --git a/yapf/yapflib/style.py b/yapf/yapflib/style.py index e614e6252..4161acbcc 100644 --- a/yapf/yapflib/style.py +++ b/yapf/yapflib/style.py @@ -123,14 +123,13 @@ 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. + (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs or + CONTINUATION_INDENT_WIDTH spaces) 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. - For options FIXED, and VALIGN-RIGHT are only available when USE_TABS is - enabled."""), + Option VALIGN-RIGHT only available when USE_TABS is enabled."""), 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..638c1ff76 100644 --- a/yapftests/format_token_test.py +++ b/yapftests/format_token_test.py @@ -63,6 +63,33 @@ def testVAlignRight(self): self.assertEqual(pad, '\t' * 2) +class SpacedContinuationAlignPaddingTest(unittest.TestCase): + + def testSpace(self): + align_style = 'SPACE' + + pad = format_token._SpacedContinuationAlignPadding(0, align_style, 4) + self.assertEqual(pad, '') + + pad = format_token._SpacedContinuationAlignPadding(2, align_style, 4) + self.assertEqual(pad, ' ' * 2) + + pad = format_token._SpacedContinuationAlignPadding(5, align_style, 4) + self.assertEqual(pad, ' ' * 5) + + def testFixed(self): + align_style = 'FIXED' + + pad = format_token._SpacedContinuationAlignPadding(0, align_style, 8) + self.assertEqual(pad, '') + + pad = format_token._SpacedContinuationAlignPadding(2, align_style, 8) + self.assertEqual(pad, ' ' * 8) + + pad = format_token._SpacedContinuationAlignPadding(5, align_style, 8) + self.assertEqual(pad, ' ' * 8) + + class FormatTokenTest(unittest.TestCase): def testSimple(self): diff --git a/yapftests/yapf_test.py b/yapftests/yapf_test.py index e13955fde..2b0993714 100644 --- a/yapftests/yapf_test.py +++ b/yapftests/yapf_test.py @@ -1302,6 +1302,33 @@ 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(