mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
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>
This commit is contained in:
parent
90d523910a
commit
b43cc31a27
10 changed files with 384 additions and 230 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue