Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d183767

Browse files
committed
Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu
Patch by Todd Rovito.
1 parent 5bb4207 commit d183767

6 files changed

Lines changed: 98 additions & 13 deletions

File tree

Doc/library/idle.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,25 @@ Edit context menu
183183

184184
* Right-click in Edit window (Control-click on OS X)
185185

186+
Cut
187+
Copy selection into system-wide clipboard; then delete selection
188+
189+
Copy
190+
Copy selection into system-wide clipboard
191+
192+
Paste
193+
Insert system-wide clipboard into window
194+
186195
Set Breakpoint
187196
Sets a breakpoint. Breakpoints are only enabled when the debugger is open.
188197

189198
Clear Breakpoint
190199
Clears the breakpoint on that line.
191200

192201
.. index::
202+
single: Cut
203+
single: Copy
204+
single: Paste
193205
single: Set Breakpoint
194206
single: Clear Breakpoint
195207
single: breakpoints
@@ -200,6 +212,15 @@ Shell context menu
200212

201213
* Right-click in Python Shell window (Control-click on OS X)
202214

215+
Cut
216+
Copy selection into system-wide clipboard; then delete selection
217+
218+
Copy
219+
Copy selection into system-wide clipboard
220+
221+
Paste
222+
Insert system-wide clipboard into window
223+
203224
Go to file/line
204225
Same as in Debug menu.
205226

Lib/idlelib/EditorWindow.py

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,6 @@ def postwindowsmenu(self):
464464
rmenu = None
465465

466466
def right_menu_event(self, event):
467-
self.text.tag_remove("sel", "1.0", "end")
468467
self.text.mark_set("insert", "@%d,%d" % (event.x, event.y))
469468
if not self.rmenu:
470469
self.make_rmenu()
@@ -473,23 +472,53 @@ def right_menu_event(self, event):
473472
iswin = sys.platform[:3] == 'win'
474473
if iswin:
475474
self.text.config(cursor="arrow")
475+
476+
for label, eventname, verify_state in self.rmenu_specs:
477+
if verify_state is None:
478+
continue
479+
state = getattr(self, verify_state)()
480+
rmenu.entryconfigure(label, state=state)
481+
482+
476483
rmenu.tk_popup(event.x_root, event.y_root)
477484
if iswin:
478485
self.text.config(cursor="ibeam")
479486

480487
rmenu_specs = [
481-
# ("Label", "<<virtual-event>>"), ...
482-
("Close", "<<close-window>>"), # Example
488+
# ("Label", "<<virtual-event>>", "statefuncname"), ...
489+
("Close", "<<close-window>>", None), # Example
483490
]
484491

485492
def make_rmenu(self):
486493
rmenu = Menu(self.text, tearoff=0)
487-
for label, eventname in self.rmenu_specs:
488-
def command(text=self.text, eventname=eventname):
489-
text.event_generate(eventname)
490-
rmenu.add_command(label=label, command=command)
494+
for label, eventname, _ in self.rmenu_specs:
495+
if label is not None:
496+
def command(text=self.text, eventname=eventname):
497+
text.event_generate(eventname)
498+
rmenu.add_command(label=label, command=command)
499+
else:
500+
rmenu.add_separator()
491501
self.rmenu = rmenu
492502

503+
def rmenu_check_cut(self):
504+
return self.rmenu_check_copy()
505+
506+
def rmenu_check_copy(self):
507+
try:
508+
indx = self.text.index('sel.first')
509+
except TclError:
510+
return 'disabled'
511+
else:
512+
return 'normal' if indx else 'disabled'
513+
514+
def rmenu_check_paste(self):
515+
try:
516+
self.text.tk.call('tk::GetSelection', self.text, 'CLIPBOARD')
517+
except TclError:
518+
return 'disabled'
519+
else:
520+
return 'normal'
521+
493522
def about_dialog(self, event=None):
494523
aboutDialog.AboutDialog(self.top,'About IDLE')
495524

Lib/idlelib/OutputWindow.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ def flush(self):
5252
# Our own right-button menu
5353

5454
rmenu_specs = [
55-
("Go to file/line", "<<goto-file-line>>"),
55+
("Cut", "<<cut>>", "rmenu_check_cut"),
56+
("Copy", "<<copy>>", "rmenu_check_copy"),
57+
("Paste", "<<paste>>", "rmenu_check_paste"),
58+
(None, None, None),
59+
("Go to file/line", "<<goto-file-line>>", None),
5660
]
5761

5862
file_line_pats = [

Lib/idlelib/PyShell.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,14 @@ def filename_changed_hook(old_hook=self.io.filename_change_hook,
117117
old_hook()
118118
self.io.set_filename_change_hook(filename_changed_hook)
119119

120-
rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
121-
("Clear Breakpoint", "<<clear-breakpoint-here>>")]
120+
rmenu_specs = [
121+
("Cut", "<<cut>>", "rmenu_check_cut"),
122+
("Copy", "<<copy>>", "rmenu_check_copy"),
123+
("Paste", "<<paste>>", "rmenu_check_paste"),
124+
(None, None, None),
125+
("Set Breakpoint", "<<set-breakpoint-here>>", None),
126+
("Clear Breakpoint", "<<clear-breakpoint-here>>", None)
127+
]
122128

123129
def set_breakpoint(self, lineno):
124130
text = self.text
@@ -1240,6 +1246,19 @@ def write(self, s, tags=()):
12401246
raise KeyboardInterrupt
12411247
return count
12421248

1249+
def rmenu_check_cut(self):
1250+
try:
1251+
if self.text.compare('sel.first', '<', 'iomark'):
1252+
return 'disabled'
1253+
except TclError: # no selection, so the index 'sel.first' doesn't exist
1254+
return 'disabled'
1255+
return super().rmenu_check_cut()
1256+
1257+
def rmenu_check_paste(self):
1258+
if self.text.compare('insert','<','iomark'):
1259+
return 'disabled'
1260+
return super().rmenu_check_paste()
1261+
12431262
class PseudoFile(object):
12441263

12451264
def __init__(self, shell, tags, encoding=None):

Lib/idlelib/help.txt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,23 @@ Help Menu:
120120
---
121121
(Additional Help Sources may be added here)
122122

123-
Edit context menu (Right-click / Control-click in Edit window):
123+
Edit context menu (Right-click / Control-click on OS X in Edit window):
124124

125+
Cut -- Copy a selection into system-wide clipboard,
126+
then delete the selection
127+
Copy -- Copy selection into system-wide clipboard
128+
Paste -- Insert system-wide clipboard into window
125129
Set Breakpoint -- Sets a breakpoint (when debugger open)
126130
Clear Breakpoint -- Clears the breakpoint on that line
127131

128-
Shell context menu (Right-click / Control-click in Shell window):
132+
Shell context menu (Right-click / Control-click on OS X in Shell window):
129133

130-
Go to file/line -- Same as in Debug menu
134+
Cut -- Copy a selection into system-wide clipboard,
135+
then delete the selection
136+
Copy -- Copy selection into system-wide clipboard
137+
Paste -- Insert system-wide clipboard into window
138+
---
139+
Go to file/line -- Same as in Debug menu
131140

132141

133142
** TIPS **

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ Core and Builtins
143143
Library
144144
-------
145145

146+
- Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu
147+
Patch by Todd Rovito.
148+
146149
- Issue #16230: Fix a crash in select.select() when one the lists changes
147150
size while iterated on. Patch by Serhiy Storchaka.
148151

0 commit comments

Comments
 (0)