bpo-32989: IDLE - fix bad editor call of pyparse method (GH-5968)

Fix comments and add tests for editor newline_and_indent_event method.
Remove unused None default for function parameter of pyparse find_good_parse_start method
and code triggered by that default.

Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
This commit is contained in:
Cheryl Sabella 2020-01-21 05:11:26 -05:00 committed by Terry Jan Reedy
parent 8698b34b68
commit ec64640a2c
6 changed files with 154 additions and 39 deletions

View file

@ -1342,38 +1342,51 @@ class EditorWindow(object):
text.undo_block_stop()
def newline_and_indent_event(self, event):
"""Insert a newline and indentation after Enter keypress event.
Properly position the cursor on the new line based on information
from the current line. This takes into account if the current line
is a shell prompt, is empty, has selected text, contains a block
opener, contains a block closer, is a continuation line, or
is inside a string.
"""
text = self.text
first, last = self.get_selection_indices()
text.undo_block_start()
try:
try: # Close undo block and expose new line in finally clause.
if first and last:
text.delete(first, last)
text.mark_set("insert", first)
line = text.get("insert linestart", "insert")
# Count leading whitespace for indent size.
i, n = 0, len(line)
while i < n and line[i] in " \t":
i = i+1
i += 1
if i == n:
# the cursor is in or at leading indentation in a continuation
# line; just inject an empty line at the start
# The cursor is in or at leading indentation in a continuation
# line; just inject an empty line at the start.
text.insert("insert linestart", '\n')
return "break"
indent = line[:i]
# strip whitespace before insert point unless it's in the prompt
# Strip whitespace before insert point unless it's in the prompt.
i = 0
while line and line[-1] in " \t" and line != self.prompt_last_line:
line = line[:-1]
i = i+1
i += 1
if i:
text.delete("insert - %d chars" % i, "insert")
# strip whitespace after insert point
# Strip whitespace after insert point.
while text.get("insert") in " \t":
text.delete("insert")
# start new line
# Insert new line.
text.insert("insert", '\n')
# adjust indentation for continuations and block
# open/close first need to find the last stmt
# Adjust indentation for continuations and block open/close.
# First need to find the last statement.
lno = index2line(text.index('insert'))
y = pyparse.Parser(self.indentwidth, self.tabwidth)
if not self.prompt_last_line:
@ -1383,7 +1396,7 @@ class EditorWindow(object):
rawtext = text.get(startatindex, "insert")
y.set_code(rawtext)
bod = y.find_good_parse_start(
self._build_char_in_string_func(startatindex))
self._build_char_in_string_func(startatindex))
if bod is not None or startat == 1:
break
y.set_lo(bod or 0)
@ -1399,26 +1412,26 @@ class EditorWindow(object):
c = y.get_continuation_type()
if c != pyparse.C_NONE:
# The current stmt hasn't ended yet.
# The current statement hasn't ended yet.
if c == pyparse.C_STRING_FIRST_LINE:
# after the first line of a string; do not indent at all
# After the first line of a string do not indent at all.
pass
elif c == pyparse.C_STRING_NEXT_LINES:
# inside a string which started before this line;
# just mimic the current indent
# Inside a string which started before this line;
# just mimic the current indent.
text.insert("insert", indent)
elif c == pyparse.C_BRACKET:
# line up with the first (if any) element of the
# Line up with the first (if any) element of the
# last open bracket structure; else indent one
# level beyond the indent of the line with the
# last open bracket
# last open bracket.
self.reindent_to(y.compute_bracket_indent())
elif c == pyparse.C_BACKSLASH:
# if more than one line in this stmt already, just
# If more than one line in this statement already, just
# mimic the current indent; else if initial line
# has a start on an assignment stmt, indent to
# beyond leftmost =; else to beyond first chunk of
# non-whitespace on initial line
# non-whitespace on initial line.
if y.get_num_lines_in_stmt() > 1:
text.insert("insert", indent)
else:
@ -1427,9 +1440,9 @@ class EditorWindow(object):
assert 0, "bogus continuation type %r" % (c,)
return "break"
# This line starts a brand new stmt; indent relative to
# This line starts a brand new statement; indent relative to
# indentation of initial line of closest preceding
# interesting stmt.
# interesting statement.
indent = y.get_base_indent_string()
text.insert("insert", indent)
if y.is_block_opener():