Skip to content

Commit 46f1c78

Browse files
gh-75710: IDLE - add docstrings and comments to editor module (#104446)
Commit extracted from PR #3669. Will edit more later. Co-authored-by: Cheryl Sabella <[email protected]>
1 parent c527eb1 commit 46f1c78

File tree

1 file changed

+102
-25
lines changed

1 file changed

+102
-25
lines changed

Lib/idlelib/editor.py

+102-25
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,26 @@ def set_line_and_column(self, event=None):
446446
self.status_bar.set_label('column', 'Col: %s' % column)
447447
self.status_bar.set_label('line', 'Ln: %s' % line)
448448

449+
450+
""" Menu definitions and functions.
451+
* self.menubar - the always visible horizontal menu bar.
452+
* mainmenu.menudefs - a list of tuples, one for each menubar item.
453+
Each tuple pairs a lower-case name and list of dropdown items.
454+
Each item is a name, virtual event pair or None for separator.
455+
* mainmenu.default_keydefs - maps events to keys.
456+
* text.keydefs - same.
457+
* cls.menu_specs - menubar name, titlecase display form pairs
458+
with Alt-hotkey indicator. A subset of menudefs items.
459+
* self.menudict - map menu name to dropdown menu.
460+
* self.recent_files_menu - 2nd level cascade in the file cascade.
461+
* self.wmenu_end - set in __init__ (purpose unclear).
462+
463+
createmenubar, postwindowsmenu, update_menu_label, update_menu_state,
464+
ApplyKeybings (2nd part), reset_help_menu_entries,
465+
_extra_help_callback, update_recent_files_list,
466+
apply_bindings, fill_menus, (other functions?)
467+
"""
468+
449469
menu_specs = [
450470
("file", "_File"),
451471
("edit", "_Edit"),
@@ -456,8 +476,22 @@ def set_line_and_column(self, event=None):
456476
("help", "_Help"),
457477
]
458478

459-
460479
def createmenubar(self):
480+
"""Populate the menu bar widget for the editor window.
481+
482+
Each option on the menubar is itself a cascade-type Menu widget
483+
with the menubar as the parent. The names, labels, and menu
484+
shortcuts for the menubar items are stored in menu_specs. Each
485+
submenu is subsequently populated in fill_menus(), except for
486+
'Recent Files' which is added to the File menu here.
487+
488+
Instance variables:
489+
menubar: Menu widget containing first level menu items.
490+
menudict: Dictionary of {menuname: Menu instance} items. The keys
491+
represent the valid menu items for this window and may be a
492+
subset of all the menudefs available.
493+
recent_files_menu: Menu widget contained within the 'file' menudict.
494+
"""
461495
mbar = self.menubar
462496
self.menudict = menudict = {}
463497
for name, label in self.menu_specs:
@@ -480,7 +514,10 @@ def createmenubar(self):
480514
self.reset_help_menu_entries()
481515

482516
def postwindowsmenu(self):
483-
# Only called when Window menu exists
517+
"""Callback to register window.
518+
519+
Only called when Window menu exists.
520+
"""
484521
menu = self.menudict['window']
485522
end = menu.index("end")
486523
if end is None:
@@ -859,8 +896,11 @@ def ResetFont(self):
859896
self.set_width()
860897

861898
def RemoveKeybindings(self):
862-
"Remove the keybindings before they are changed."
863-
# Called from configdialog.py
899+
"""Remove the virtual, configurable keybindings.
900+
901+
Leaves the default Tk Text keybindings.
902+
"""
903+
# Called from configdialog.deactivate_current_config.
864904
self.mainmenu.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
865905
for event, keylist in keydefs.items():
866906
self.text.event_delete(event, *keylist)
@@ -871,15 +911,19 @@ def RemoveKeybindings(self):
871911
self.text.event_delete(event, *keylist)
872912

873913
def ApplyKeybindings(self):
874-
"Update the keybindings after they are changed"
875-
# Called from configdialog.py
914+
"""Apply the virtual, configurable keybindings.
915+
916+
Alse update hotkeys to current keyset.
917+
"""
918+
# Called from configdialog.activate_config_changes.
876919
self.mainmenu.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
877920
self.apply_bindings()
878921
for extensionName in self.get_standard_extension_names():
879922
xkeydefs = idleConf.GetExtensionBindings(extensionName)
880923
if xkeydefs:
881924
self.apply_bindings(xkeydefs)
882-
#update menu accelerators
925+
926+
# Update menu accelerators.
883927
menuEventDict = {}
884928
for menu in self.mainmenu.menudefs:
885929
menuEventDict[menu[0]] = {}
@@ -914,25 +958,25 @@ def set_notabs_indentwidth(self):
914958
type='int')
915959

916960
def reset_help_menu_entries(self):
917-
"Update the additional help entries on the Help menu"
961+
"""Update the additional help entries on the Help menu."""
918962
help_list = idleConf.GetAllExtraHelpSourcesList()
919963
helpmenu = self.menudict['help']
920-
# first delete the extra help entries, if any
964+
# First delete the extra help entries, if any.
921965
helpmenu_length = helpmenu.index(END)
922966
if helpmenu_length > self.base_helpmenu_length:
923967
helpmenu.delete((self.base_helpmenu_length + 1), helpmenu_length)
924-
# then rebuild them
968+
# Then rebuild them.
925969
if help_list:
926970
helpmenu.add_separator()
927971
for entry in help_list:
928-
cmd = self.__extra_help_callback(entry[1])
972+
cmd = self._extra_help_callback(entry[1])
929973
helpmenu.add_command(label=entry[0], command=cmd)
930-
# and update the menu dictionary
974+
# And update the menu dictionary.
931975
self.menudict['help'] = helpmenu
932976

933-
def __extra_help_callback(self, helpfile):
934-
"Create a callback with the helpfile value frozen at definition time"
935-
def display_extra_help(helpfile=helpfile):
977+
def _extra_help_callback(self, resource):
978+
"""Return a callback that loads resource (file or web page)."""
979+
def display_extra_help(helpfile=resource):
936980
if not helpfile.startswith(('www', 'http')):
937981
helpfile = os.path.normpath(helpfile)
938982
if sys.platform[:3] == 'win':
@@ -1158,6 +1202,7 @@ def load_extension(self, name):
11581202
self.text.bind(vevent, getattr(ins, methodname))
11591203

11601204
def apply_bindings(self, keydefs=None):
1205+
"""Add events with keys to self.text."""
11611206
if keydefs is None:
11621207
keydefs = self.mainmenu.default_keydefs
11631208
text = self.text
@@ -1167,9 +1212,10 @@ def apply_bindings(self, keydefs=None):
11671212
text.event_add(event, *keylist)
11681213

11691214
def fill_menus(self, menudefs=None, keydefs=None):
1170-
"""Add appropriate entries to the menus and submenus
1215+
"""Fill in dropdown menus used by this window.
11711216
1172-
Menus that are absent or None in self.menudict are ignored.
1217+
Items whose name begins with '!' become checkbuttons.
1218+
Other names indicate commands. None becomes a separator.
11731219
"""
11741220
if menudefs is None:
11751221
menudefs = self.mainmenu.menudefs
@@ -1182,7 +1228,7 @@ def fill_menus(self, menudefs=None, keydefs=None):
11821228
if not menu:
11831229
continue
11841230
for entry in entrylist:
1185-
if not entry:
1231+
if entry is None:
11861232
menu.add_separator()
11871233
else:
11881234
label, eventname = entry
@@ -1218,11 +1264,13 @@ def setvar(self, name, value, vartype=None):
12181264
else:
12191265
raise NameError(name)
12201266

1221-
def get_var_obj(self, name, vartype=None):
1222-
var = self.tkinter_vars.get(name)
1267+
def get_var_obj(self, eventname, vartype=None):
1268+
"""Return a tkinter variable instance for the event.
1269+
"""
1270+
var = self.tkinter_vars.get(eventname)
12231271
if not var and vartype:
1224-
# create a Tkinter variable object with self.text as master:
1225-
self.tkinter_vars[name] = var = vartype(self.text)
1272+
# Create a Tkinter variable object.
1273+
self.tkinter_vars[eventname] = var = vartype(self.text)
12261274
return var
12271275

12281276
# Tk implementations of "virtual text methods" -- each platform
@@ -1613,8 +1661,16 @@ def run(self):
16131661
### end autoindent code ###
16141662

16151663
def prepstr(s):
1616-
# Helper to extract the underscore from a string, e.g.
1617-
# prepstr("Co_py") returns (2, "Copy").
1664+
"""Extract the underscore from a string.
1665+
1666+
For example, prepstr("Co_py") returns (2, "Copy").
1667+
1668+
Args:
1669+
s: String with underscore.
1670+
1671+
Returns:
1672+
Tuple of (position of underscore, string without underscore).
1673+
"""
16181674
i = s.find('_')
16191675
if i >= 0:
16201676
s = s[:i] + s[i+1:]
@@ -1628,6 +1684,18 @@ def prepstr(s):
16281684
}
16291685

16301686
def get_accelerator(keydefs, eventname):
1687+
"""Return a formatted string for the keybinding of an event.
1688+
1689+
Convert the first keybinding for a given event to a form that
1690+
can be displayed as an accelerator on the menu.
1691+
1692+
Args:
1693+
keydefs: Dictionary of valid events to keybindings.
1694+
eventname: Event to retrieve keybinding for.
1695+
1696+
Returns:
1697+
Formatted string of the keybinding.
1698+
"""
16311699
keylist = keydefs.get(eventname)
16321700
# issue10940: temporary workaround to prevent hang with OS X Cocoa Tk 8.5
16331701
# if not keylist:
@@ -1637,14 +1705,23 @@ def get_accelerator(keydefs, eventname):
16371705
"<<change-indentwidth>>"}):
16381706
return ""
16391707
s = keylist[0]
1708+
# Convert strings of the form -singlelowercase to -singleuppercase.
16401709
s = re.sub(r"-[a-z]\b", lambda m: m.group().upper(), s)
1710+
# Convert certain keynames to their symbol.
16411711
s = re.sub(r"\b\w+\b", lambda m: keynames.get(m.group(), m.group()), s)
1712+
# Remove Key- from string.
16421713
s = re.sub("Key-", "", s)
1643-
s = re.sub("Cancel","Ctrl-Break",s) # [email protected]
1714+
# Convert Cancel to Ctrl-Break.
1715+
s = re.sub("Cancel", "Ctrl-Break", s) # [email protected]
1716+
# Convert Control to Ctrl-.
16441717
s = re.sub("Control-", "Ctrl-", s)
1718+
# Change - to +.
16451719
s = re.sub("-", "+", s)
1720+
# Change >< to space.
16461721
s = re.sub("><", " ", s)
1722+
# Remove <.
16471723
s = re.sub("<", "", s)
1724+
# Remove >.
16481725
s = re.sub(">", "", s)
16491726
return s
16501727

0 commit comments

Comments
 (0)