Skip to content

Commit

Permalink
Merge from 3.x: PR #3826
Browse files Browse the repository at this point in the history
Fixes #3800
  • Loading branch information
ccordoba12 committed Jan 5, 2017
2 parents 6380abe + 530f50e commit 014f733
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 15 deletions.
47 changes: 34 additions & 13 deletions spyder/widgets/sourcecode/codeeditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1711,18 +1711,18 @@ def fix_indent(self, forward=True, comment_or_string=False):
for prevline in range(block_nb-1, -1, -1):
cursor.movePosition(QTextCursor.PreviousBlock)
prevtext = to_text_string(cursor.block().text()).rstrip()
if ((self.is_python_like()
and not prevtext.strip().startswith('#')
and prevtext)
or prevtext):
if (prevtext.strip().endswith(')')
or prevtext.strip().endswith(']')
or prevtext.strip().endswith('}')):

if ((self.is_python_like() and
not prevtext.strip().startswith('#') and prevtext) or
prevtext):

if not prevtext.strip().startswith('return') and \
(prevtext.strip().endswith(')') or
prevtext.strip().endswith(']') or
prevtext.strip().endswith('}')):

comment_or_string = True # prevent further parsing

elif prevtext.strip().endswith(':') and self.is_python_like():
add_indent = True
comment_or_string = True
Expand Down Expand Up @@ -1761,8 +1761,13 @@ def fix_indent(self, forward=True, comment_or_string=False):
correct_indent += self.tab_stop_width_spaces
else:
correct_indent += len(self.indent_chars)
elif (prevtext.endswith('continue') or prevtext.endswith('break') \
or prevtext.endswith('pass')) and self.is_python_like():
elif self.is_python_like() and \
(prevtext.endswith('continue') or
prevtext.endswith('break') or
prevtext.endswith('pass') or
(prevtext.strip().startswith("return") and
len(re.split(r'\(|\{|\[', prevtext)) ==
len(re.split(r'\)|\}|\]', prevtext)))):
# Unindent
if self.indent_chars == '\t':
correct_indent -= self.tab_stop_width_spaces
Expand Down Expand Up @@ -1797,6 +1802,22 @@ def fix_indent(self, forward=True, comment_or_string=False):
else:
correct_indent = len(prevtext)

if not (diff_paren or diff_brack or diff_curly) and \
not prevtext.endswith(':'):
cur_indent = self.get_block_indentation(block_nb - 1)
is_blank = not self.get_text_line(block_nb - 1).strip()
prevline_indent = self.get_block_indentation(prevline)
trailing_text = self.get_text_line(block_nb).strip()

if cur_indent < prevline_indent and \
(trailing_text or is_blank):
if cur_indent % len(self.indent_chars) == 0:
correct_indent = cur_indent
else:
correct_indent = cur_indent \
+ (len(self.indent_chars) -
cur_indent % len(self.indent_chars))

if (forward and indent >= correct_indent) or \
(not forward and indent <= correct_indent):
# No indentation fix is necessary
Expand Down
50 changes: 48 additions & 2 deletions spyder/widgets/sourcecode/tests/test_autoindent.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@

# --- Fixtures
# -----------------------------------------------------------------------------
def get_indent_fix(text, indent_chars=" " * 4, tab_stop_width_spaces=4):
def get_indent_fix(text, indent_chars=" " * 4, tab_stop_width_spaces=4,
sol=False):
"""Return text with last line's indentation fixed."""
app = qapplication()
editor = CodeEditor(parent=None)
editor.setup_editor(language='Python', indent_chars=indent_chars,
Expand All @@ -29,6 +31,10 @@ def get_indent_fix(text, indent_chars=" " * 4, tab_stop_width_spaces=4):
editor.set_text(text)
cursor = editor.textCursor()
cursor.movePosition(QTextCursor.End)
if sol:
lines = text.splitlines(True)
repeat = len(lines[-1].lstrip())
cursor.movePosition(QTextCursor.Left, n=repeat)
editor.setTextCursor(cursor)
editor.fix_indent()
return to_text_string(editor.toPlainText())
Expand Down Expand Up @@ -92,7 +98,47 @@ def test_align_on_curly():
# An open curly bracket with one or more item is followed by an indent
# up to the parenthesis.
text = get_indent_fix("curly_w_item = (1,\n")
assert text == "curly_w_item = (1,\n ", repr(text)
assert text == "curly_w_item = (1,\n ", repr(text)


def test_keep_unindent():
# Keep line unindented if there is more than one line under the statement
text = (" def foo(bar):\n"
" generic = bar\n"
" \n"
" keep_unindent\n")
correct_text = (" def foo(bar):\n"
" generic = bar\n"
" \n"
" keep_unindent\n")
text = get_indent_fix(text, sol=True)
assert text == correct_text, repr(text)


def test_keep_unindent_fix_indent():
# Keep line unindented but fix indent if not multiple of len(indent_chars)
text = (" for x in range(n):\n"
" increment += 1\n"
" \n"
" keep_unindent\n")
correct_text = (" for x in range(n):\n"
" increment += 1\n"
" \n"
" keep_unindent\n")
text = get_indent_fix(text, sol=True)
assert text == correct_text, repr(text)


def test_keep_unindent_if_blank():
# Keep line unindented if return is pressed on a line which is both
# blank and unindented.
text = (" def f(x):\n"
" return x\n"
"\n"
"")
text = get_indent_fix(text)
assert text == " def f(x):\n return x\n\n", repr(text)


# --- Failing tests
# -----------------------------------------------------------------------------
Expand Down

0 comments on commit 014f733

Please sign in to comment.