mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	definitions (platform-specific), and generating accelerator strings automatically from the key definitions.
		
			
				
	
	
		
			198 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# This file defines the menu contents and key bindings.  Note that
 | 
						|
# there is additional configuration information in the EditorWindow
 | 
						|
# class (and subclasses): the menus are created there based on the
 | 
						|
# menu_specs (class) variable, and menus not created are silently
 | 
						|
# skipped by the code here.  This makes it possible to define the
 | 
						|
# Debug menu here, which is only present in the PythonShell window.
 | 
						|
 | 
						|
import sys
 | 
						|
import string
 | 
						|
import re
 | 
						|
 | 
						|
menudefs = [
 | 
						|
 # underscore prefixes character to underscore
 | 
						|
 ('file', [
 | 
						|
   ('_New window', '<<open-new-window>>'),
 | 
						|
   ('_Open...', '<<open-window-from-file>>'),
 | 
						|
   ('Open _module...', '<<open-module>>'),
 | 
						|
   ('Class _browser...', '<<open-class-browser>>'),
 | 
						|
   None,
 | 
						|
   ('_Save', '<<save-window>>'),
 | 
						|
   ('Save _As...', '<<save-window-as-file>>'),
 | 
						|
   ('Save Co_py As...', '<<save-copy-of-window-as-file>>'),
 | 
						|
   None,
 | 
						|
   ('_Close', '<<close-window>>'),
 | 
						|
   ('E_xit', '<<close-all-windows>>'),
 | 
						|
  ]),
 | 
						|
 ('edit', [
 | 
						|
   ('_Undo', '<<undo>>'),
 | 
						|
   ('_Redo', '<<redo>>'),
 | 
						|
   None,
 | 
						|
   ('Cu_t', '<<Cut>>'),
 | 
						|
   ('_Copy', '<<Copy>>'),
 | 
						|
   ('_Paste', '<<Paste>>'),
 | 
						|
   None,
 | 
						|
   ('_Find...', '<<find>>'),
 | 
						|
   ('Find _next', '<<find-next>>'),
 | 
						|
   ('Find _same', '<<find-same>>'),
 | 
						|
   ('_Go to line', '<<goto-line>>'),
 | 
						|
   None,
 | 
						|
   ('_Dedent region', '<<dedent-region>>'),
 | 
						|
   ('_Indent region', '<<indent-region>>'),
 | 
						|
   ('Comment _out region', '<<comment-region>>'),
 | 
						|
   ('U_ncomment region', '<<uncomment-region>>'),
 | 
						|
  ]),
 | 
						|
 ('debug', [
 | 
						|
   ('_Go to line from traceback', '<<goto-traceback-line>>'),
 | 
						|
   ('_Open stack viewer', '<<open-stack-viewer>>'),
 | 
						|
   ('_Debugger toggle', '<<toggle-debugger>>'),
 | 
						|
  ]),
 | 
						|
 ('help', [
 | 
						|
   ('_Help...', '<<help>>'),
 | 
						|
   None,
 | 
						|
   ('_About IDLE...', '<<about-idle>>'),
 | 
						|
  ]),
 | 
						|
]
 | 
						|
 | 
						|
windows_keydefs = {
 | 
						|
 '<<beginning-of-line>>': ['<Control-a>', '<Home>'],
 | 
						|
 '<<close-all-windows>>': ['<Control-q>'],
 | 
						|
 '<<comment-region>>': ['<Meta-Key-3>', '<Alt-Key-3>'],
 | 
						|
 '<<dedent-region>>': ['<Control-bracketleft>'],
 | 
						|
 '<<dump-undo-state>>': ['<Control-backslash>'],
 | 
						|
 '<<end-of-file>>': ['<Control-d>'],
 | 
						|
 '<<expand-word>>': ['<Meta-slash>', '<Alt-slash>'],
 | 
						|
 '<<find-next>>': ['<F3>', '<Control-g>'],
 | 
						|
 '<<find-same>>': ['<Control-F3>'],
 | 
						|
 '<<find>>': ['<Control-f>'],
 | 
						|
 '<<goto-line>>': ['<Alt-g>', '<Meta-g>'],
 | 
						|
 '<<history-next>>': ['<Meta-n>', '<Alt-n>'],
 | 
						|
 '<<history-previous>>': ['<Meta-p>', '<Alt-p>'],
 | 
						|
 '<<indent-region>>': ['<Control-bracketright>'],
 | 
						|
 '<<interrupt-execution>>': ['<Control-c>'],
 | 
						|
 '<<newline-and-indent>>': ['<Key-Return>', '<KP_Enter>'],
 | 
						|
 '<<open-new-window>>': ['<Control-n>'],
 | 
						|
 '<<open-window-from-file>>': ['<Control-o>'],
 | 
						|
 '<<plain-newline-and-indent>>': ['<Control-j>'],
 | 
						|
 '<<redo>>': ['<Control-y>'],
 | 
						|
 '<<save-copy-of-window-as-file>>': ['<Meta-w>'],
 | 
						|
 '<<save-window-as-file>>': ['<Control-w>'],
 | 
						|
 '<<save-window>>': ['<Control-s>'],
 | 
						|
 '<<toggle-auto-coloring>>': ['<Control-slash>'],
 | 
						|
 '<<uncomment-region>>': ['<Meta-Key-4>', '<Alt-Key-4>'],
 | 
						|
 '<<undo>>': ['<Control-z>'],
 | 
						|
}
 | 
						|
 | 
						|
emacs_keydefs = {
 | 
						|
 '<<Copy>>': ['<Alt-w>'],
 | 
						|
 '<<Cut>>': ['<Control-w>'],
 | 
						|
 '<<Paste>>': ['<Control-y>'],
 | 
						|
 '<<about-idle>>': [],
 | 
						|
 '<<beginning-of-line>>': ['<Control-a>', '<Home>'],
 | 
						|
 '<<center-insert>>': ['<Control-l>'],
 | 
						|
 '<<close-all-windows>>': ['<Control-x><Control-c>'],
 | 
						|
 '<<close-window>>': ['<Control-x><Control-0>'],
 | 
						|
 '<<comment-region>>': ['<Meta-Key-3>', '<Alt-Key-3>'],
 | 
						|
 '<<dedent-region>>': ['<Meta-bracketleft>',
 | 
						|
                       '<Alt-bracketleft>',
 | 
						|
                       '<Control-bracketleft>'],
 | 
						|
 '<<do-nothing>>': ['<Control-x>'],
 | 
						|
 '<<dump-undo-state>>': ['<Control-backslash>'],
 | 
						|
 '<<end-of-file>>': ['<Control-d>'],
 | 
						|
 '<<expand-word>>': ['<Meta-slash>', '<Alt-slash>'],
 | 
						|
 '<<find-next>>': ['<Control-u><Control-s>'],
 | 
						|
 '<<find-same>>': ['<Control-s>'],
 | 
						|
 '<<find>>': ['<Control-u><Control-u><Control-s>'],
 | 
						|
 '<<goto-line>>': ['<Alt-g>', '<Meta-g>'],
 | 
						|
 '<<goto-traceback-line>>': [],
 | 
						|
 '<<help>>': [],
 | 
						|
 '<<history-next>>': ['<Meta-n>', '<Alt-n>'],
 | 
						|
 '<<history-previous>>': ['<Meta-p>', '<Alt-p>'],
 | 
						|
 '<<indent-region>>': ['<Meta-bracketright>',
 | 
						|
                       '<Alt-bracketright>',
 | 
						|
                       '<Control-bracketright>'],
 | 
						|
 '<<interrupt-execution>>': ['<Control-c>'],
 | 
						|
 '<<newline-and-indent>>': ['<Key-Return>', '<KP_Enter>'],
 | 
						|
 '<<open-class-browser>>': ['<Control-x><Control-b>'],
 | 
						|
 '<<open-module>>': ['<Control-x><Control-m>'],
 | 
						|
 '<<open-new-window>>': ['<Control-x><Control-n>'],
 | 
						|
 '<<open-stack-viewer>>': [],
 | 
						|
 '<<open-window-from-file>>': ['<Control-x><Control-f>'],
 | 
						|
 '<<plain-newline-and-indent>>': ['<Control-j>'],
 | 
						|
 '<<redo>>': ['<Alt-z>', '<Meta-z>'],
 | 
						|
 '<<save-copy-of-window-as-file>>': ['<Control-x><w>'],
 | 
						|
 '<<save-window-as-file>>': ['<Control-x><Control-w>'],
 | 
						|
 '<<save-window>>': ['<Control-x><Control-s>'],
 | 
						|
 '<<toggle-auto-coloring>>': ['<Control-slash>'],
 | 
						|
 '<<toggle-debugger>>': [],
 | 
						|
 '<<uncomment-region>>': ['<Meta-Key-4>', '<Alt-Key-4>'],
 | 
						|
 '<<undo>>': ['<Control-z>'],
 | 
						|
}
 | 
						|
 | 
						|
def prepstr(s):
 | 
						|
    # Helper to extract the underscore from a string,
 | 
						|
    # e.g. prepstr("Co_py") returns (2, "Copy").
 | 
						|
    i = string.find(s, '_')
 | 
						|
    if i >= 0:
 | 
						|
        s = s[:i] + s[i+1:]
 | 
						|
    return i, s
 | 
						|
 | 
						|
keynames = {
 | 
						|
 'bracketleft': '[',
 | 
						|
 'bracketright': ']',
 | 
						|
}
 | 
						|
 | 
						|
def getaccelerator(keydefs, event):
 | 
						|
    keylist = keydefs.get(event)
 | 
						|
    if not keylist:
 | 
						|
        return ""
 | 
						|
    s = keylist[0]
 | 
						|
    if s[:6] == "<Meta-":
 | 
						|
        # Prefer Alt over Meta -- they should be the same thing anyway
 | 
						|
        alts = "<Alt-" + s[6:]
 | 
						|
        if alts in keylist:
 | 
						|
            s = alts
 | 
						|
    s = re.sub(r"-[a-z]\b", lambda m: string.upper(m.group()), s)
 | 
						|
    s = re.sub(r"\b\w+\b", lambda m: keynames.get(m.group(), m.group()), s)
 | 
						|
    s = re.sub("Key-", "", s)
 | 
						|
    s = re.sub("Control-", "Ctrl-", s)
 | 
						|
    s = re.sub("-", "+", s)
 | 
						|
    s = re.sub("><", " ", s)
 | 
						|
    s = re.sub("<", "", s)
 | 
						|
    s = re.sub(">", "", s)
 | 
						|
    return s
 | 
						|
 | 
						|
if sys.platform == 'win32':
 | 
						|
    default_keydefs = windows_keydefs
 | 
						|
else:
 | 
						|
    default_keydefs = emacs_keydefs
 | 
						|
 | 
						|
def apply_bindings(text, keydefs=default_keydefs):
 | 
						|
    text.keydefs = keydefs
 | 
						|
    for event, keylist in keydefs.items():
 | 
						|
        if keylist:
 | 
						|
            apply(text.event_add, (event,) + tuple(keylist))
 | 
						|
 | 
						|
def fill_menus(text, menudict, defs=menudefs):
 | 
						|
    # Fill the menus for the given text widget.  The menudict argument is
 | 
						|
    # a dictionary containing the menus, keyed by their lowercased name.
 | 
						|
    # Menus that are absent or None are ignored.
 | 
						|
    if hasattr(text, "keydefs"):
 | 
						|
        keydefs = text.keydefs
 | 
						|
    else:
 | 
						|
        keydefs = default_keydefs
 | 
						|
    for mname, itemlist in defs:
 | 
						|
        menu = menudict.get(mname)
 | 
						|
        if not menu:
 | 
						|
            continue
 | 
						|
        for item in itemlist:
 | 
						|
            if not item:
 | 
						|
                menu.add_separator()
 | 
						|
            else:
 | 
						|
                label, event = item
 | 
						|
                underline, label = prepstr(label)
 | 
						|
                accelerator = getaccelerator(keydefs, event)
 | 
						|
                def command(text=text, event=event):
 | 
						|
                    text.event_generate(event)
 | 
						|
                menu.add_command(label=label, underline=underline,
 | 
						|
                                 command=command, accelerator=accelerator)
 |