Merge IDLE-syntax-branch r39668:41449 into trunk

A    idlelib/AutoCompleteWindow.py
A    idlelib/AutoComplete.py
A    idlelib/HyperParser.py
M    idlelib/PyShell.py
M    idlelib/ParenMatch.py
M    idlelib/configDialog.py
M    idlelib/EditorWindow.py
M    idlelib/PyParse.py
M    idlelib/CallTips.py
M    idlelib/CallTipWindow.py
M    idlelib/run.py
M    idlelib/config-extensions.def
A    idlelib/MultiCall.py
diff --git a/Lib/idlelib/PyParse.py b/Lib/idlelib/PyParse.py
index 1bf4919..1a9db67 100644
--- a/Lib/idlelib/PyParse.py
+++ b/Lib/idlelib/PyParse.py
@@ -14,9 +14,7 @@
 _synchre = re.compile(r"""
     ^
     [ \t]*
-    (?: if
-    |   for
-    |   while
+    (?: while
     |   else
     |   def
     |   return
@@ -145,29 +143,11 @@
     # This will be reliable iff given a reliable is_char_in_string
     # function, meaning that when it says "no", it's absolutely
     # guaranteed that the char is not in a string.
-    #
-    # Ack, hack: in the shell window this kills us, because there's
-    # no way to tell the differences between output, >>> etc and
-    # user input.  Indeed, IDLE's first output line makes the rest
-    # look like it's in an unclosed paren!:
-    # Python 1.5.2 (#0, Apr 13 1999, ...
 
-    def find_good_parse_start(self, use_ps1, is_char_in_string=None,
+    def find_good_parse_start(self, is_char_in_string=None,
                               _synchre=_synchre):
         str, pos = self.str, None
-        if use_ps1:
-            # shell window
-            ps1 = '\n' + sys.ps1
-            i = str.rfind(ps1)
-            if i >= 0:
-                pos = i + len(ps1)
-                # make it look like there's a newline instead
-                # of ps1 at the start -- hacking here once avoids
-                # repeated hackery later
-                self.str = str[:pos-1] + '\n' + str[pos:]
-            return pos
 
-        # File window -- real work.
         if not is_char_in_string:
             # no clue -- make the caller pass everything
             return None
@@ -363,6 +343,11 @@
     # Creates:
     #     self.stmt_start, stmt_end
     #         slice indices of last interesting stmt
+    #     self.stmt_bracketing
+    #         the bracketing structure of the last interesting stmt;
+    #         for example, for the statement "say(boo) or die", stmt_bracketing
+    #         will be [(0, 0), (3, 1), (8, 0)]. Strings and comments are
+    #         treated as brackets, for the matter.
     #     self.lastch
     #         last non-whitespace character before optional trailing
     #         comment
@@ -404,6 +389,7 @@
         lastch = ""
         stack = []  # stack of open bracket indices
         push_stack = stack.append
+        bracketing = [(p, 0)]
         while p < q:
             # suck up all except ()[]{}'"#\\
             m = _chew_ordinaryre(str, p, q)
@@ -424,6 +410,7 @@
 
             if ch in "([{":
                 push_stack(p)
+                bracketing.append((p, len(stack)))
                 lastch = ch
                 p = p+1
                 continue
@@ -433,6 +420,7 @@
                     del stack[-1]
                 lastch = ch
                 p = p+1
+                bracketing.append((p, len(stack)))
                 continue
 
             if ch == '"' or ch == "'":
@@ -443,14 +431,18 @@
                 # strings to a couple of characters per line.  study1
                 # also needed to keep track of newlines, and we don't
                 # have to.
+                bracketing.append((p, len(stack)+1))
                 lastch = ch
                 p = _match_stringre(str, p, q).end()
+                bracketing.append((p, len(stack)))
                 continue
 
             if ch == '#':
                 # consume comment and trailing newline
+                bracketing.append((p, len(stack)+1))
                 p = str.find('\n', p, q) + 1
                 assert p > 0
+                bracketing.append((p, len(stack)))
                 continue
 
             assert ch == '\\'
@@ -466,6 +458,7 @@
         self.lastch = lastch
         if stack:
             self.lastopenbracketpos = stack[-1]
+        self.stmt_bracketing = tuple(bracketing)
 
     # Assuming continuation is C_BRACKET, return the number
     # of spaces the next line should be indented.
@@ -590,3 +583,12 @@
     def get_last_open_bracket_pos(self):
         self._study2()
         return self.lastopenbracketpos
+
+    # the structure of the bracketing of the last interesting statement,
+    # in the format defined in _study2, or None if the text didn't contain
+    # anything
+    stmt_bracketing = None
+
+    def get_last_stmt_bracketing(self):
+        self._study2()
+        return self.stmt_bracketing