mirror of
https://github.com/python/cpython.git
synced 2025-10-31 21:51:50 +00:00
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 <cheryl.sabella@gmail.com>
This commit is contained in:
parent
c527eb1c2a
commit
46f1c78eeb
1 changed files with 102 additions and 25 deletions
|
|
@ -446,6 +446,26 @@ def set_line_and_column(self, event=None):
|
||||||
self.status_bar.set_label('column', 'Col: %s' % column)
|
self.status_bar.set_label('column', 'Col: %s' % column)
|
||||||
self.status_bar.set_label('line', 'Ln: %s' % line)
|
self.status_bar.set_label('line', 'Ln: %s' % line)
|
||||||
|
|
||||||
|
|
||||||
|
""" Menu definitions and functions.
|
||||||
|
* self.menubar - the always visible horizontal menu bar.
|
||||||
|
* mainmenu.menudefs - a list of tuples, one for each menubar item.
|
||||||
|
Each tuple pairs a lower-case name and list of dropdown items.
|
||||||
|
Each item is a name, virtual event pair or None for separator.
|
||||||
|
* mainmenu.default_keydefs - maps events to keys.
|
||||||
|
* text.keydefs - same.
|
||||||
|
* cls.menu_specs - menubar name, titlecase display form pairs
|
||||||
|
with Alt-hotkey indicator. A subset of menudefs items.
|
||||||
|
* self.menudict - map menu name to dropdown menu.
|
||||||
|
* self.recent_files_menu - 2nd level cascade in the file cascade.
|
||||||
|
* self.wmenu_end - set in __init__ (purpose unclear).
|
||||||
|
|
||||||
|
createmenubar, postwindowsmenu, update_menu_label, update_menu_state,
|
||||||
|
ApplyKeybings (2nd part), reset_help_menu_entries,
|
||||||
|
_extra_help_callback, update_recent_files_list,
|
||||||
|
apply_bindings, fill_menus, (other functions?)
|
||||||
|
"""
|
||||||
|
|
||||||
menu_specs = [
|
menu_specs = [
|
||||||
("file", "_File"),
|
("file", "_File"),
|
||||||
("edit", "_Edit"),
|
("edit", "_Edit"),
|
||||||
|
|
@ -456,8 +476,22 @@ def set_line_and_column(self, event=None):
|
||||||
("help", "_Help"),
|
("help", "_Help"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def createmenubar(self):
|
def createmenubar(self):
|
||||||
|
"""Populate the menu bar widget for the editor window.
|
||||||
|
|
||||||
|
Each option on the menubar is itself a cascade-type Menu widget
|
||||||
|
with the menubar as the parent. The names, labels, and menu
|
||||||
|
shortcuts for the menubar items are stored in menu_specs. Each
|
||||||
|
submenu is subsequently populated in fill_menus(), except for
|
||||||
|
'Recent Files' which is added to the File menu here.
|
||||||
|
|
||||||
|
Instance variables:
|
||||||
|
menubar: Menu widget containing first level menu items.
|
||||||
|
menudict: Dictionary of {menuname: Menu instance} items. The keys
|
||||||
|
represent the valid menu items for this window and may be a
|
||||||
|
subset of all the menudefs available.
|
||||||
|
recent_files_menu: Menu widget contained within the 'file' menudict.
|
||||||
|
"""
|
||||||
mbar = self.menubar
|
mbar = self.menubar
|
||||||
self.menudict = menudict = {}
|
self.menudict = menudict = {}
|
||||||
for name, label in self.menu_specs:
|
for name, label in self.menu_specs:
|
||||||
|
|
@ -480,7 +514,10 @@ def createmenubar(self):
|
||||||
self.reset_help_menu_entries()
|
self.reset_help_menu_entries()
|
||||||
|
|
||||||
def postwindowsmenu(self):
|
def postwindowsmenu(self):
|
||||||
# Only called when Window menu exists
|
"""Callback to register window.
|
||||||
|
|
||||||
|
Only called when Window menu exists.
|
||||||
|
"""
|
||||||
menu = self.menudict['window']
|
menu = self.menudict['window']
|
||||||
end = menu.index("end")
|
end = menu.index("end")
|
||||||
if end is None:
|
if end is None:
|
||||||
|
|
@ -859,8 +896,11 @@ def ResetFont(self):
|
||||||
self.set_width()
|
self.set_width()
|
||||||
|
|
||||||
def RemoveKeybindings(self):
|
def RemoveKeybindings(self):
|
||||||
"Remove the keybindings before they are changed."
|
"""Remove the virtual, configurable keybindings.
|
||||||
# Called from configdialog.py
|
|
||||||
|
Leaves the default Tk Text keybindings.
|
||||||
|
"""
|
||||||
|
# Called from configdialog.deactivate_current_config.
|
||||||
self.mainmenu.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
|
self.mainmenu.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
|
||||||
for event, keylist in keydefs.items():
|
for event, keylist in keydefs.items():
|
||||||
self.text.event_delete(event, *keylist)
|
self.text.event_delete(event, *keylist)
|
||||||
|
|
@ -871,15 +911,19 @@ def RemoveKeybindings(self):
|
||||||
self.text.event_delete(event, *keylist)
|
self.text.event_delete(event, *keylist)
|
||||||
|
|
||||||
def ApplyKeybindings(self):
|
def ApplyKeybindings(self):
|
||||||
"Update the keybindings after they are changed"
|
"""Apply the virtual, configurable keybindings.
|
||||||
# Called from configdialog.py
|
|
||||||
|
Alse update hotkeys to current keyset.
|
||||||
|
"""
|
||||||
|
# Called from configdialog.activate_config_changes.
|
||||||
self.mainmenu.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
|
self.mainmenu.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
|
||||||
self.apply_bindings()
|
self.apply_bindings()
|
||||||
for extensionName in self.get_standard_extension_names():
|
for extensionName in self.get_standard_extension_names():
|
||||||
xkeydefs = idleConf.GetExtensionBindings(extensionName)
|
xkeydefs = idleConf.GetExtensionBindings(extensionName)
|
||||||
if xkeydefs:
|
if xkeydefs:
|
||||||
self.apply_bindings(xkeydefs)
|
self.apply_bindings(xkeydefs)
|
||||||
#update menu accelerators
|
|
||||||
|
# Update menu accelerators.
|
||||||
menuEventDict = {}
|
menuEventDict = {}
|
||||||
for menu in self.mainmenu.menudefs:
|
for menu in self.mainmenu.menudefs:
|
||||||
menuEventDict[menu[0]] = {}
|
menuEventDict[menu[0]] = {}
|
||||||
|
|
@ -914,25 +958,25 @@ def set_notabs_indentwidth(self):
|
||||||
type='int')
|
type='int')
|
||||||
|
|
||||||
def reset_help_menu_entries(self):
|
def reset_help_menu_entries(self):
|
||||||
"Update the additional help entries on the Help menu"
|
"""Update the additional help entries on the Help menu."""
|
||||||
help_list = idleConf.GetAllExtraHelpSourcesList()
|
help_list = idleConf.GetAllExtraHelpSourcesList()
|
||||||
helpmenu = self.menudict['help']
|
helpmenu = self.menudict['help']
|
||||||
# first delete the extra help entries, if any
|
# First delete the extra help entries, if any.
|
||||||
helpmenu_length = helpmenu.index(END)
|
helpmenu_length = helpmenu.index(END)
|
||||||
if helpmenu_length > self.base_helpmenu_length:
|
if helpmenu_length > self.base_helpmenu_length:
|
||||||
helpmenu.delete((self.base_helpmenu_length + 1), helpmenu_length)
|
helpmenu.delete((self.base_helpmenu_length + 1), helpmenu_length)
|
||||||
# then rebuild them
|
# Then rebuild them.
|
||||||
if help_list:
|
if help_list:
|
||||||
helpmenu.add_separator()
|
helpmenu.add_separator()
|
||||||
for entry in help_list:
|
for entry in help_list:
|
||||||
cmd = self.__extra_help_callback(entry[1])
|
cmd = self._extra_help_callback(entry[1])
|
||||||
helpmenu.add_command(label=entry[0], command=cmd)
|
helpmenu.add_command(label=entry[0], command=cmd)
|
||||||
# and update the menu dictionary
|
# And update the menu dictionary.
|
||||||
self.menudict['help'] = helpmenu
|
self.menudict['help'] = helpmenu
|
||||||
|
|
||||||
def __extra_help_callback(self, helpfile):
|
def _extra_help_callback(self, resource):
|
||||||
"Create a callback with the helpfile value frozen at definition time"
|
"""Return a callback that loads resource (file or web page)."""
|
||||||
def display_extra_help(helpfile=helpfile):
|
def display_extra_help(helpfile=resource):
|
||||||
if not helpfile.startswith(('www', 'http')):
|
if not helpfile.startswith(('www', 'http')):
|
||||||
helpfile = os.path.normpath(helpfile)
|
helpfile = os.path.normpath(helpfile)
|
||||||
if sys.platform[:3] == 'win':
|
if sys.platform[:3] == 'win':
|
||||||
|
|
@ -1158,6 +1202,7 @@ def load_extension(self, name):
|
||||||
self.text.bind(vevent, getattr(ins, methodname))
|
self.text.bind(vevent, getattr(ins, methodname))
|
||||||
|
|
||||||
def apply_bindings(self, keydefs=None):
|
def apply_bindings(self, keydefs=None):
|
||||||
|
"""Add events with keys to self.text."""
|
||||||
if keydefs is None:
|
if keydefs is None:
|
||||||
keydefs = self.mainmenu.default_keydefs
|
keydefs = self.mainmenu.default_keydefs
|
||||||
text = self.text
|
text = self.text
|
||||||
|
|
@ -1167,9 +1212,10 @@ def apply_bindings(self, keydefs=None):
|
||||||
text.event_add(event, *keylist)
|
text.event_add(event, *keylist)
|
||||||
|
|
||||||
def fill_menus(self, menudefs=None, keydefs=None):
|
def fill_menus(self, menudefs=None, keydefs=None):
|
||||||
"""Add appropriate entries to the menus and submenus
|
"""Fill in dropdown menus used by this window.
|
||||||
|
|
||||||
Menus that are absent or None in self.menudict are ignored.
|
Items whose name begins with '!' become checkbuttons.
|
||||||
|
Other names indicate commands. None becomes a separator.
|
||||||
"""
|
"""
|
||||||
if menudefs is None:
|
if menudefs is None:
|
||||||
menudefs = self.mainmenu.menudefs
|
menudefs = self.mainmenu.menudefs
|
||||||
|
|
@ -1182,7 +1228,7 @@ def fill_menus(self, menudefs=None, keydefs=None):
|
||||||
if not menu:
|
if not menu:
|
||||||
continue
|
continue
|
||||||
for entry in entrylist:
|
for entry in entrylist:
|
||||||
if not entry:
|
if entry is None:
|
||||||
menu.add_separator()
|
menu.add_separator()
|
||||||
else:
|
else:
|
||||||
label, eventname = entry
|
label, eventname = entry
|
||||||
|
|
@ -1218,11 +1264,13 @@ def setvar(self, name, value, vartype=None):
|
||||||
else:
|
else:
|
||||||
raise NameError(name)
|
raise NameError(name)
|
||||||
|
|
||||||
def get_var_obj(self, name, vartype=None):
|
def get_var_obj(self, eventname, vartype=None):
|
||||||
var = self.tkinter_vars.get(name)
|
"""Return a tkinter variable instance for the event.
|
||||||
|
"""
|
||||||
|
var = self.tkinter_vars.get(eventname)
|
||||||
if not var and vartype:
|
if not var and vartype:
|
||||||
# create a Tkinter variable object with self.text as master:
|
# Create a Tkinter variable object.
|
||||||
self.tkinter_vars[name] = var = vartype(self.text)
|
self.tkinter_vars[eventname] = var = vartype(self.text)
|
||||||
return var
|
return var
|
||||||
|
|
||||||
# Tk implementations of "virtual text methods" -- each platform
|
# Tk implementations of "virtual text methods" -- each platform
|
||||||
|
|
@ -1613,8 +1661,16 @@ def run(self):
|
||||||
### end autoindent code ###
|
### end autoindent code ###
|
||||||
|
|
||||||
def prepstr(s):
|
def prepstr(s):
|
||||||
# Helper to extract the underscore from a string, e.g.
|
"""Extract the underscore from a string.
|
||||||
# prepstr("Co_py") returns (2, "Copy").
|
|
||||||
|
For example, prepstr("Co_py") returns (2, "Copy").
|
||||||
|
|
||||||
|
Args:
|
||||||
|
s: String with underscore.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Tuple of (position of underscore, string without underscore).
|
||||||
|
"""
|
||||||
i = s.find('_')
|
i = s.find('_')
|
||||||
if i >= 0:
|
if i >= 0:
|
||||||
s = s[:i] + s[i+1:]
|
s = s[:i] + s[i+1:]
|
||||||
|
|
@ -1628,6 +1684,18 @@ def prepstr(s):
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_accelerator(keydefs, eventname):
|
def get_accelerator(keydefs, eventname):
|
||||||
|
"""Return a formatted string for the keybinding of an event.
|
||||||
|
|
||||||
|
Convert the first keybinding for a given event to a form that
|
||||||
|
can be displayed as an accelerator on the menu.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
keydefs: Dictionary of valid events to keybindings.
|
||||||
|
eventname: Event to retrieve keybinding for.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Formatted string of the keybinding.
|
||||||
|
"""
|
||||||
keylist = keydefs.get(eventname)
|
keylist = keydefs.get(eventname)
|
||||||
# issue10940: temporary workaround to prevent hang with OS X Cocoa Tk 8.5
|
# issue10940: temporary workaround to prevent hang with OS X Cocoa Tk 8.5
|
||||||
# if not keylist:
|
# if not keylist:
|
||||||
|
|
@ -1637,14 +1705,23 @@ def get_accelerator(keydefs, eventname):
|
||||||
"<<change-indentwidth>>"}):
|
"<<change-indentwidth>>"}):
|
||||||
return ""
|
return ""
|
||||||
s = keylist[0]
|
s = keylist[0]
|
||||||
|
# Convert strings of the form -singlelowercase to -singleuppercase.
|
||||||
s = re.sub(r"-[a-z]\b", lambda m: m.group().upper(), s)
|
s = re.sub(r"-[a-z]\b", lambda m: m.group().upper(), s)
|
||||||
|
# Convert certain keynames to their symbol.
|
||||||
s = re.sub(r"\b\w+\b", lambda m: keynames.get(m.group(), m.group()), s)
|
s = re.sub(r"\b\w+\b", lambda m: keynames.get(m.group(), m.group()), s)
|
||||||
|
# Remove Key- from string.
|
||||||
s = re.sub("Key-", "", s)
|
s = re.sub("Key-", "", s)
|
||||||
s = re.sub("Cancel","Ctrl-Break",s) # dscherer@cmu.edu
|
# Convert Cancel to Ctrl-Break.
|
||||||
|
s = re.sub("Cancel", "Ctrl-Break", s) # dscherer@cmu.edu
|
||||||
|
# Convert Control to Ctrl-.
|
||||||
s = re.sub("Control-", "Ctrl-", s)
|
s = re.sub("Control-", "Ctrl-", s)
|
||||||
|
# Change - to +.
|
||||||
s = re.sub("-", "+", s)
|
s = re.sub("-", "+", s)
|
||||||
|
# Change >< to space.
|
||||||
s = re.sub("><", " ", s)
|
s = re.sub("><", " ", s)
|
||||||
|
# Remove <.
|
||||||
s = re.sub("<", "", s)
|
s = re.sub("<", "", s)
|
||||||
|
# Remove >.
|
||||||
s = re.sub(">", "", s)
|
s = re.sub(">", "", s)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue