From 58fc71c447049d0efe4e11db1b55edc307f1bede Mon Sep 17 00:00:00 2001 From: wohlganger Date: Sun, 10 Sep 2017 16:19:47 -0500 Subject: bpo-27099: IDLE - Convert built-in extensions to regular features (#2494) About 10 IDLE features were implemented as supposedly optional extensions. Their different behavior could be confusing or worse for users and not good for maintenance. Hence the conversion. The main difference for users is that user configurable key bindings for builtin features are now handled uniformly. Now, editing a binding in a keyset only affects its value in the keyset. All bindings are defined together in the system-specific default keysets in config- extensions.def. All custom keysets are saved as a whole in config- extension.cfg. All take effect as soon as one clicks Apply or Ok. The affected events are '<>', '<>', '<>', '<>', '<>', '<>', '<>', and '<>'. Any (global) customizations made before 3.6.3 will not affect their keyset- specific customization after 3.6.3. and vice versa. Inital patch by Charles Wohlganger, revised by Terry Jan Reedy. --- Lib/idlelib/configdialog.py | 116 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 99 insertions(+), 17 deletions(-) (limited to 'Lib/idlelib/configdialog.py') diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 4ef6197e71..604719f045 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -15,7 +15,7 @@ from tkinter import (Toplevel, Listbox, Text, Scale, Canvas, NONE, BOTH, X, Y, W, E, EW, NS, NSEW, NW, HORIZONTAL, VERTICAL, ANCHOR, ACTIVE, END) from tkinter.ttk import (Button, Checkbutton, Entry, Frame, Label, LabelFrame, - Notebook, Radiobutton, Scrollbar, Style) + OptionMenu, Notebook, Radiobutton, Scrollbar, Style) import tkinter.colorchooser as tkColorChooser import tkinter.font as tkFont from tkinter import messagebox @@ -198,7 +198,6 @@ class ConfigDialog(Toplevel): def deactivate_current_config(self): """Remove current key bindings. - Iterate over window instances defined in parent and remove the keybindings. """ @@ -288,6 +287,7 @@ class ConfigDialog(Toplevel): "Fill self.extensions with data from the default and user configs." self.extensions = {} for ext_name in idleConf.GetExtensions(active_only=False): + # Former built-in extensions are already filtered out. self.extensions[ext_name] = [] for ext_name in self.extensions: @@ -796,7 +796,8 @@ class HighPage(Frame): takefocus=FALSE, highlightthickness=0, wrap=NONE) text.bind('', lambda e: 'break') text.bind('', lambda e: 'break') - text_and_tags=(('\n', 'normal'), + text_and_tags=( + ('\n', 'normal'), ('#you can click here', 'comment'), ('\n', 'normal'), ('#to choose items', 'comment'), ('\n', 'normal'), ('def', 'keyword'), (' ', 'normal'), @@ -858,11 +859,10 @@ class HighPage(Frame): frame_theme, text='Delete Custom Theme', command=self.delete_custom) self.theme_message = Label(frame_theme, borderwidth=2) - # Pack widgets: # body. frame_custom.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH) - frame_theme.pack(side=LEFT, padx=5, pady=5, fill=Y) + frame_theme.pack(side=TOP, padx=5, pady=5, fill=X) # frame_custom. self.frame_color_set.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=X) frame_fg_bg_toggle.pack(side=TOP, padx=5, pady=0) @@ -1764,15 +1764,30 @@ class GenPage(Frame): (*)helplist: ListBox scroll_helplist: Scrollbar """ + # Integer values need StringVar because int('') raises. self.startup_edit = tracers.add( IntVar(self), ('main', 'General', 'editor-on-startup')) - self.autosave = tracers.add( - IntVar(self), ('main', 'General', 'autosave')) self.win_width = tracers.add( StringVar(self), ('main', 'EditorWindow', 'width')) self.win_height = tracers.add( StringVar(self), ('main', 'EditorWindow', 'height')) + self.autocomplete_wait = tracers.add( + StringVar(self), ('extensions', 'AutoComplete', 'popupwait')) + self.paren_style = tracers.add( + StringVar(self), ('extensions', 'ParenMatch', 'style')) + self.flash_delay = tracers.add( + StringVar(self), ('extensions', 'ParenMatch', 'flash-delay')) + self.paren_bell = tracers.add( + BooleanVar(self), ('extensions', 'ParenMatch', 'bell')) + + self.autosave = tracers.add( + IntVar(self), ('main', 'General', 'autosave')) + self.format_width = tracers.add( + StringVar(self), ('extensions', 'FormatParagraph', 'max-width')) + self.context_lines = tracers.add( + StringVar(self), ('extensions', 'CodeContext', 'numlines')) + # Create widgets: # Section frames. frame_window = LabelFrame(self, borderwidth=2, relief=GROOVE, text=' Window Preferences') @@ -1790,7 +1805,7 @@ class GenPage(Frame): frame_run, variable=self.startup_edit, value=0, text='Open Shell Window') - frame_win_size = Frame(frame_window, borderwidth=0,) + frame_win_size = Frame(frame_window, borderwidth=0) win_size_title = Label( frame_win_size, text='Initial Window Size (in characters)') win_width_title = Label(frame_win_size, text='Width') @@ -1800,6 +1815,26 @@ class GenPage(Frame): self.win_height_int = Entry( frame_win_size, textvariable=self.win_height, width=3) + frame_autocomplete = Frame(frame_window, borderwidth=0,) + auto_wait_title = Label(frame_autocomplete, + text='Completions Popup Wait (milliseconds)') + self.auto_wait_int = Entry(frame_autocomplete, width=6, + textvariable=self.autocomplete_wait) + + frame_paren1 = Frame(frame_window, borderwidth=0) + paren_style_title = Label(frame_paren1, text='Paren Match Style') + self.paren_style_type = OptionMenu( + frame_paren1, self.paren_style, 'expression', + "opener","parens","expression") + frame_paren2 = Frame(frame_window, borderwidth=0) + paren_time_title = Label( + frame_paren2, text='Time Match Displayed (milliseconds)\n' + '(0 is until next input)') + self.paren_flash_time = Entry( + frame_paren2, textvariable=self.flash_delay, width=6) + self.bell_on = Checkbutton( + frame_paren2, text="Bell on Mismatch", variable=self.paren_bell) + # Frame_editor. frame_save = Frame(frame_editor, borderwidth=0) run_save_title = Label(frame_save, text='At Start of Run (F5) ') @@ -1810,6 +1845,18 @@ class GenPage(Frame): frame_save, variable=self.autosave, value=1, text='No Prompt') + frame_format = Frame(frame_editor, borderwidth=0) + format_width_title = Label(frame_format, + text='Format Paragraph Max Width') + self.format_width_int = Entry( + frame_format, textvariable=self.format_width, width=4) + + frame_context = Frame(frame_editor, borderwidth=0) + context_title = Label(frame_context, text='Context Lines :') + self.context_int = Entry( + frame_context, textvariable=self.context_lines, width=3) + + # frame_help. frame_helplist = Frame(frame_help) frame_helplist_buttons = Frame(frame_helplist) @@ -1847,11 +1894,33 @@ class GenPage(Frame): win_height_title.pack(side=RIGHT, anchor=E, pady=5) self.win_width_int.pack(side=RIGHT, anchor=E, padx=10, pady=5) win_width_title.pack(side=RIGHT, anchor=E, pady=5) + # frame_autocomplete. + frame_autocomplete.pack(side=TOP, padx=5, pady=0, fill=X) + auto_wait_title.pack(side=LEFT, anchor=W, padx=5, pady=5) + self.auto_wait_int.pack(side=TOP, padx=10, pady=5) + # frame_paren. + frame_paren1.pack(side=TOP, padx=5, pady=0, fill=X) + paren_style_title.pack(side=LEFT, anchor=W, padx=5, pady=5) + self.paren_style_type.pack(side=TOP, padx=10, pady=5) + frame_paren2.pack(side=TOP, padx=5, pady=0, fill=X) + paren_time_title.pack(side=LEFT, anchor=W, padx=5) + self.bell_on.pack(side=RIGHT, anchor=E, padx=15, pady=5) + self.paren_flash_time.pack(side=TOP, anchor=W, padx=15, pady=5) + # frame_save. frame_save.pack(side=TOP, padx=5, pady=0, fill=X) run_save_title.pack(side=LEFT, anchor=W, padx=5, pady=5) self.save_auto_on.pack(side=RIGHT, anchor=W, padx=5, pady=5) self.save_ask_on.pack(side=RIGHT, anchor=W, padx=5, pady=5) + # frame_format. + frame_format.pack(side=TOP, padx=5, pady=0, fill=X) + format_width_title.pack(side=LEFT, anchor=W, padx=5, pady=5) + self.format_width_int.pack(side=TOP, padx=10, pady=5) + # frame_context. + frame_context.pack(side=TOP, padx=5, pady=0, fill=X) + context_title.pack(side=LEFT, anchor=W, padx=5, pady=5) + self.context_int.pack(side=TOP, padx=5, pady=5) + # frame_help. frame_helplist_buttons.pack(side=RIGHT, padx=5, pady=5, fill=Y) frame_helplist.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) @@ -1863,17 +1932,30 @@ class GenPage(Frame): def load_general_cfg(self): "Load current configuration settings for the general options." - # Set startup state. + # Set variables for all windows. self.startup_edit.set(idleConf.GetOption( - 'main', 'General', 'editor-on-startup', default=0, type='bool')) - # Set autosave state. - self.autosave.set(idleConf.GetOption( - 'main', 'General', 'autosave', default=0, type='bool')) - # Set initial window size. + 'main', 'General', 'editor-on-startup', type='bool')) self.win_width.set(idleConf.GetOption( 'main', 'EditorWindow', 'width', type='int')) self.win_height.set(idleConf.GetOption( 'main', 'EditorWindow', 'height', type='int')) + self.autocomplete_wait.set(idleConf.GetOption( + 'extensions', 'AutoComplete', 'popupwait', type='int')) + self.paren_style.set(idleConf.GetOption( + 'extensions', 'ParenMatch', 'style')) + self.flash_delay.set(idleConf.GetOption( + 'extensions', 'ParenMatch', 'flash-delay', type='int')) + self.paren_bell.set(idleConf.GetOption( + 'extensions', 'ParenMatch', 'bell')) + + # Set variables for editor windows. + self.autosave.set(idleConf.GetOption( + 'main', 'General', 'autosave', default=0, type='bool')) + self.format_width.set(idleConf.GetOption( + 'extensions', 'FormatParagraph', 'max-width', type='int')) + self.context_lines.set(idleConf.GetOption( + 'extensions', 'CodeContext', 'numlines', type='int')) + # Set additional help sources. self.user_helplist = idleConf.GetAllExtraHelpSourcesList() self.helplist.delete(0, 'end') @@ -2034,10 +2116,10 @@ The IDLE Modern Unix key set is new in June 2016. It can only be used with older IDLE releases if it is saved as a custom key set, with a different name. ''', - 'Extensions': ''' -Extensions: + 'General': ''' +General: -Autocomplete: Popupwait is milleseconds to wait after key char, without +AutoComplete: Popupwait is milleseconds to wait after key char, without cursor movement, before popping up completion box. Key char is '.' after identifier or a '/' (or '\\' on Windows) within a string. -- cgit v1.2.1