summaryrefslogtreecommitdiffstats
path: root/Lib/idlelib/pyshell.py
diff options
context:
space:
mode:
authorTal Einat <532281+taleinat@users.noreply.github.com>2021-05-03 02:27:38 (GMT)
committerGitHub <noreply@github.com>2021-05-03 02:27:38 (GMT)
commitb43cc31a270d0dacbc69e35d6c6fbdb5edd7e711 (patch)
treef656c691cf80d2b927037808ea51d4f75ae20a16 /Lib/idlelib/pyshell.py
parent90d523910a61290597b4599f17363b532f0a4411 (diff)
downloadcpython-b43cc31a270d0dacbc69e35d6c6fbdb5edd7e711.zip
cpython-b43cc31a270d0dacbc69e35d6c6fbdb5edd7e711.tar.gz
cpython-b43cc31a270d0dacbc69e35d6c6fbdb5edd7e711.tar.bz2
bpo-37903: IDLE: add shell sidebar mouse interactions (GH-25708)
Left click and drag to select lines. With selection, right click for context menu with copy and copy-with-prompts. Also add copy-with-prompts to the text-box context menu. Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
Diffstat (limited to 'Lib/idlelib/pyshell.py')
-rwxr-xr-xLib/idlelib/pyshell.py45
1 files changed, 45 insertions, 0 deletions
diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py
index 447e9ec..4e74400 100755
--- a/Lib/idlelib/pyshell.py
+++ b/Lib/idlelib/pyshell.py
@@ -33,6 +33,7 @@ if TkVersion < 8.5:
raise SystemExit(1)
from code import InteractiveInterpreter
+import itertools
import linecache
import os
import os.path
@@ -865,6 +866,13 @@ class PyShell(OutputWindow):
rmenu_specs = OutputWindow.rmenu_specs + [
("Squeeze", "<<squeeze-current-text>>"),
]
+ _idx = 1 + len(list(itertools.takewhile(
+ lambda rmenu_item: rmenu_item[0] != "Copy", rmenu_specs)
+ ))
+ rmenu_specs.insert(_idx, ("Copy with prompts",
+ "<<copy-with-prompts>>",
+ "rmenu_check_copy"))
+ del _idx
allow_line_numbers = False
user_input_insert_tags = "stdin"
@@ -906,6 +914,7 @@ class PyShell(OutputWindow):
text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
text.bind("<<toggle-debugger>>", self.toggle_debugger)
text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
+ text.bind("<<copy-with-prompts>>", self.copy_with_prompts_callback)
if use_subprocess:
text.bind("<<view-restart>>", self.view_restart_mark)
text.bind("<<restart-shell>>", self.restart_shell)
@@ -979,6 +988,42 @@ class PyShell(OutputWindow):
def get_standard_extension_names(self):
return idleConf.GetExtensions(shell_only=True)
+ def copy_with_prompts_callback(self, event=None):
+ """Copy selected lines to the clipboard, with prompts.
+
+ This makes the copied text useful for doc-tests and interactive
+ shell code examples.
+
+ This always copies entire lines, even if only part of the first
+ and/or last lines is selected.
+ """
+ text = self.text
+
+ selection_indexes = (
+ self.text.index("sel.first linestart"),
+ self.text.index("sel.last +1line linestart"),
+ )
+ if selection_indexes[0] is None:
+ # There is no selection, so do nothing.
+ return
+
+ selected_text = self.text.get(*selection_indexes)
+ selection_lineno_range = range(
+ int(float(selection_indexes[0])),
+ int(float(selection_indexes[1]))
+ )
+ prompts = [
+ self.shell_sidebar.line_prompts.get(lineno)
+ for lineno in selection_lineno_range
+ ]
+ selected_text_with_prompts = "\n".join(
+ line if prompt is None else f"{prompt} {line}"
+ for prompt, line in zip(prompts, selected_text.splitlines())
+ ) + "\n"
+
+ text.clipboard_clear()
+ text.clipboard_append(selected_text_with_prompts)
+
reading = False
executing = False
canceled = False