M EditorWindow.py
M PyShell.py

1. PyShell Rev 1.39, EditorWindow Rev 1.37 fix was not handling a
   multiline prompt.
2. The same fix introduced a bug where hitting <enter> at a previous
   prompt-only line would copy the prompt to the iomark.
3. Move the setting of sys.ps1 earlier, into PyShell.main(), to allow
   this code to work before a shell is started up.
4. If cursor is on the input line in the prompt, and you hit <enter>,
   process the line instead of complaining.
5. If line has no stdin range (this includes the last line before shell
   restart) strip any prompt before recalling.
diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py
index 5719352..f039503 100644
--- a/Lib/idlelib/EditorWindow.py
+++ b/Lib/idlelib/EditorWindow.py
@@ -952,9 +952,11 @@
         have = len(chars.expandtabs(tabwidth))
         assert have > 0
         want = ((have - 1) // self.indentwidth) * self.indentwidth
+        # Debug prompt is multilined....
+        last_line_of_prompt = sys.ps1.split('\n')[-1]
         ncharsdeleted = 0
         while 1:
-            if chars == sys.ps1:
+            if chars == last_line_of_prompt:
                 break
             chars = chars[:-1]
             ncharsdeleted = ncharsdeleted + 1
@@ -1011,19 +1013,18 @@
                 text.mark_set("insert", first)
             line = text.get("insert linestart", "insert")
             i, n = 0, len(line)
-            if line == sys.ps1:
-                return "break"
             while i < n and line[i] in " \t":
                 i = i+1
             if i == n:
-                # the cursor is in or at leading indentation; 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
+            # strip whitespace before insert point unless it's in the prompt
             i = 0
-            while line and line[-1] in " \t":
+            last_line_of_prompt = sys.ps1.split('\n')[-1]
+            while line and line[-1] in " \t" and line != last_line_of_prompt:
                 line = line[:-1]
                 i = i+1
             if i:
diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py
index f4485bd..eb5c6af 100644
--- a/Lib/idlelib/PyShell.py
+++ b/Lib/idlelib/PyShell.py
@@ -825,10 +825,6 @@
         self.write("Python %s on %s\n%s\nIDLEfork %s\n" %
                    (sys.version, sys.platform, self.COPYRIGHT,
                     idlever.IDLE_VERSION))
-        try:
-            sys.ps1
-        except AttributeError:
-            sys.ps1 = ">>> "
         self.showprompt()
         import Tkinter
         Tkinter._default_root = None
@@ -943,14 +939,17 @@
             if next and self.text.compare("insert lineend", ">=", next[0]):
                 self.recall(self.text.get(next[0], next[1]))
                 return "break"
-            # No stdin mark -- just get the current line
-            self.recall(self.text.get("insert linestart", "insert lineend"))
+            # No stdin mark -- just get the current line, less any prompt
+            line = self.text.get("insert linestart", "insert lineend")
+            last_line_of_prompt = sys.ps1.split('\n')[-1]
+            if line.startswith(last_line_of_prompt):
+                line = line[len(last_line_of_prompt):]
+            self.recall(line)
             return "break"
         # If we're between the beginning of the line and the iomark, i.e.
-        # in the prompt area, complain.
+        # in the prompt area, move to the end of the prompt
         if self.text.compare("insert", "<", "iomark"):
-            self.text.bell()
-            return "break"
+            self.text.mark_set("insert", "iomark")
         # If we're in the current input and there's only whitespace
         # beyond the cursor, erase that whitespace first
         s = self.text.get("insert", "end-1c")
@@ -1136,6 +1135,10 @@
     script = None
     startup = False
     try:
+        sys.ps1
+    except AttributeError:
+        sys.ps1 = '>>> '
+    try:
         opts, args = getopt.getopt(sys.argv[1:], "c:deihr:st:")
     except getopt.error, msg:
         sys.stderr.write("Error: %s\n" % str(msg))