Skip to content

Commit 58fc71c

Browse files
wohlgangerterryjreedy
authored andcommitted
bpo-27099: IDLE - Convert built-in extensions to regular features (python#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 '<<force-open-completions>>', '<<expand-word>>', '<<force-open-calltip>>', '<<flash-paren>>', '<<format-paragraph>>', '<<run-module>>', '<<check-module>>', and '<<zoom-height>>'. 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.
1 parent d39dbf4 commit 58fc71c

21 files changed

+451
-272
lines changed

Doc/library/idle.rst

+3-20
Original file line numberDiff line numberDiff line change
@@ -672,23 +672,6 @@ Extensions
672672

673673
IDLE contains an extension facility. Preferences for extensions can be
674674
changed with Configure Extensions. See the beginning of config-extensions.def
675-
in the idlelib directory for further information. The default extensions
676-
are currently:
677-
678-
* FormatParagraph
679-
680-
* AutoExpand
681-
682-
* ZoomHeight
683-
684-
* ScriptBinding
685-
686-
* CallTips
687-
688-
* ParenMatch
689-
690-
* AutoComplete
691-
692-
* CodeContext
693-
694-
* RstripExtension
675+
in the idlelib directory for further information. The only current default
676+
extension is zoomheight. It exists as an extension primarily to be an example
677+
and for testing purposes.

Lib/idlelib/autocomplete.py

+12-13
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
"""autocomplete.py - An IDLE extension for automatically completing names.
1+
"""Complete either attribute names or file names.
22
3-
This extension can complete either attribute names or file names. It can pop
4-
a window with all available names, for the user to select from.
3+
Either on demand or after a user-selected delay after a key character,
4+
pop up a list of candidates.
55
"""
66
import os
77
import string
@@ -27,18 +27,9 @@
2727

2828
class AutoComplete:
2929

30-
menudefs = [
31-
('edit', [
32-
("Show Completions", "<<force-open-completions>>"),
33-
])
34-
]
35-
36-
popupwait = idleConf.GetOption("extensions", "AutoComplete",
37-
"popupwait", type="int", default=0)
38-
3930
def __init__(self, editwin=None):
4031
self.editwin = editwin
41-
if editwin is not None: # not in subprocess or test
32+
if editwin is not None: # not in subprocess or test
4233
self.text = editwin.text
4334
self.autocompletewindow = None
4435
# id of delayed call, and the index of the text insert when
@@ -47,6 +38,11 @@ def __init__(self, editwin=None):
4738
self._delayed_completion_id = None
4839
self._delayed_completion_index = None
4940

41+
@classmethod
42+
def reload(cls):
43+
cls.popupwait = idleConf.GetOption(
44+
"extensions", "AutoComplete", "popupwait", type="int", default=0)
45+
5046
def _make_autocomplete_window(self):
5147
return autocomplete_w.AutoCompleteWindow(self.text)
5248

@@ -228,6 +224,9 @@ def get_entity(self, name):
228224
return eval(name, namespace)
229225

230226

227+
AutoComplete.reload()
228+
229+
231230
if __name__ == '__main__':
232231
from unittest import main
233232
main('idlelib.idle_test.test_autocomplete', verbosity=2)

Lib/idlelib/autoexpand.py

+2-11
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,13 @@
1010
place before requesting the next selection causes AutoExpand to reset
1111
its state.
1212
13-
This is an extension file and there is only one instance of AutoExpand.
13+
There is only one instance of Autoexpand.
1414
'''
1515
import re
1616
import string
1717

18-
###$ event <<expand-word>>
19-
###$ win <Alt-slash>
20-
###$ unix <Alt-slash>
2118

2219
class AutoExpand:
23-
24-
menudefs = [
25-
('edit', [
26-
('E_xpand Word', '<<expand-word>>'),
27-
]),
28-
]
29-
3020
wordchars = string.ascii_letters + string.digits + "_"
3121

3222
def __init__(self, editwin):
@@ -100,6 +90,7 @@ def getprevword(self):
10090
i = i-1
10191
return line[i:]
10292

93+
10394
if __name__ == '__main__':
10495
import unittest
10596
unittest.main('idlelib.idle_test.test_autoexpand', verbosity=2)

Lib/idlelib/calltips.py

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
"""calltips.py - An IDLE Extension to Jog Your Memory
1+
"""Pop up a reminder of how to call a function.
22
33
Call Tips are floating windows which display function, class, and method
44
parameter and docstring information when you type an opening parenthesis, and
55
which disappear when you type a closing parenthesis.
6-
76
"""
87
import inspect
98
import re
@@ -15,13 +14,8 @@
1514
from idlelib.hyperparser import HyperParser
1615
import __main__
1716

18-
class CallTips:
1917

20-
menudefs = [
21-
('edit', [
22-
("Show call tip", "<<force-open-calltip>>"),
23-
])
24-
]
18+
class CallTips:
2519

2620
def __init__(self, editwin=None):
2721
if editwin is None: # subprocess and test
@@ -103,6 +97,7 @@ def fetch_tip(self, expression):
10397
else:
10498
return get_argspec(get_entity(expression))
10599

100+
106101
def get_entity(expression):
107102
"""Return the object corresponding to expression evaluated
108103
in a namespace spanning sys.modules and __main.dict__.
@@ -126,7 +121,6 @@ def get_entity(expression):
126121
_invalid_method = "invalid method signature"
127122
_argument_positional = "\n['/' marks preceding arguments as positional-only]\n"
128123

129-
130124
def get_argspec(ob):
131125
'''Return a string describing the signature of a callable object, or ''.
132126

Lib/idlelib/codecontext.py

+16-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""codecontext - Extension to display the block context above the edit window
1+
"""codecontext - display the block context above the edit window
22
33
Once code has scrolled off the top of a window, it can be difficult to
44
determine which block you are in. This extension implements a pane at the top
@@ -25,10 +25,8 @@
2525
getspacesfirstword =\
2626
lambda s, c=re.compile(r"^(\s*)(\w*)"): c.match(s).groups()
2727

28+
2829
class CodeContext:
29-
menudefs = [('options', [('!Code Conte_xt', '<<toggle-code-context>>')])]
30-
context_depth = idleConf.GetOption("extensions", "CodeContext",
31-
"numlines", type="int", default=3)
3230
bgcolor = idleConf.GetOption("extensions", "CodeContext",
3331
"bgcolor", type="str", default="LightGray")
3432
fgcolor = idleConf.GetOption("extensions", "CodeContext",
@@ -45,15 +43,20 @@ def __init__(self, editwin):
4543
# starts the toplevel 'block' of the module.
4644
self.info = [(0, -1, "", False)]
4745
self.topvisible = 1
48-
visible = idleConf.GetOption("extensions", "CodeContext",
49-
"visible", type="bool", default=False)
50-
if visible:
51-
self.toggle_code_context_event()
52-
self.editwin.setvar('<<toggle-code-context>>', True)
46+
self.reload()
5347
# Start two update cycles, one for context lines, one for font changes.
5448
self.text.after(UPDATEINTERVAL, self.timer_event)
5549
self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
5650

51+
@classmethod
52+
def reload(cls):
53+
cls.context_depth = idleConf.GetOption("extensions", "CodeContext",
54+
"numlines", type="int", default=3)
55+
cls.bgcolor = idleConf.GetOption("extensions", "CodeContext",
56+
"bgcolor", type="str", default="LightGray")
57+
cls.fgcolor = idleConf.GetOption("extensions", "CodeContext",
58+
"fgcolor", type="str", default="Black")
59+
5760
def toggle_code_context_event(self, event=None):
5861
if not self.label:
5962
# Calculate the border width and horizontal padding required to
@@ -86,7 +89,7 @@ def toggle_code_context_event(self, event=None):
8689
else:
8790
self.label.destroy()
8891
self.label = None
89-
idleConf.SetOption("extensions", "CodeContext", "visible",
92+
idleConf.SetOption("main", "Theme", "contexton",
9093
str(self.label is not None))
9194
idleConf.SaveUserCfgFiles()
9295
return "break"
@@ -177,3 +180,6 @@ def font_timer_event(self):
177180
self.textfont = newtextfont
178181
self.label["font"] = self.textfont
179182
self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
183+
184+
185+
CodeContext.reload()

Lib/idlelib/config-extensions.def

+32-66
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
# config-extensions.def
22
#
3+
# The following sections are for features that are no longer extensions.
4+
# Their options values are left here for back-compatibility.
5+
6+
[AutoComplete]
7+
popupwait= 2000
8+
9+
[CodeContext]
10+
numlines= 3
11+
visible= False
12+
bgcolor= LightGray
13+
fgcolor= Black
14+
15+
[FormatParagraph]
16+
max-width= 72
17+
18+
[ParenMatch]
19+
style= expression
20+
flash-delay= 500
21+
bell= True
22+
323
# IDLE reads several config files to determine user preferences. This
424
# file is the default configuration file for IDLE extensions settings.
525
#
@@ -19,7 +39,7 @@
1939
# extension that may be sensibly re-configured.
2040
#
2141
# If there are no keybindings for a menus' virtual events, include lines
22-
# like <<toggle-code-context>>= (See [CodeContext], below.)
42+
# like <<toggle-code-context>>=.
2343
#
2444
# Currently it is necessary to manually modify this file to change
2545
# extension key bindings and default values. To customize, create
@@ -32,68 +52,14 @@
3252
# See config-keys.def for notes on specifying keys and extend.txt for
3353
# information on creating IDLE extensions.
3454

35-
[AutoComplete]
36-
enable=True
37-
popupwait=2000
38-
[AutoComplete_cfgBindings]
39-
force-open-completions=<Control-Key-space>
40-
[AutoComplete_bindings]
41-
autocomplete=<Key-Tab>
42-
try-open-completions=<KeyRelease-period> <KeyRelease-slash> <KeyRelease-backslash>
43-
44-
[AutoExpand]
45-
enable=True
46-
[AutoExpand_cfgBindings]
47-
expand-word=<Alt-Key-slash>
48-
49-
[CallTips]
50-
enable=True
51-
[CallTips_cfgBindings]
52-
force-open-calltip=<Control-Key-backslash>
53-
[CallTips_bindings]
54-
try-open-calltip=<KeyRelease-parenleft>
55-
refresh-calltip=<KeyRelease-parenright> <KeyRelease-0>
56-
57-
[CodeContext]
58-
enable=True
59-
enable_shell=False
60-
numlines=3
61-
visible=False
62-
bgcolor=LightGray
63-
fgcolor=Black
64-
[CodeContext_bindings]
65-
toggle-code-context=
66-
67-
[FormatParagraph]
68-
enable=True
69-
max-width=72
70-
[FormatParagraph_cfgBindings]
71-
format-paragraph=<Alt-Key-q>
72-
73-
[ParenMatch]
74-
enable=True
75-
style= expression
76-
flash-delay= 500
77-
bell=True
78-
[ParenMatch_cfgBindings]
79-
flash-paren=<Control-Key-0>
80-
[ParenMatch_bindings]
81-
paren-closed=<KeyRelease-parenright> <KeyRelease-bracketright> <KeyRelease-braceright>
82-
83-
[RstripExtension]
84-
enable=True
85-
enable_shell=False
86-
enable_editor=True
87-
88-
[ScriptBinding]
89-
enable=True
90-
enable_shell=False
91-
enable_editor=True
92-
[ScriptBinding_cfgBindings]
93-
run-module=<Key-F5>
94-
check-module=<Alt-Key-x>
95-
96-
[ZoomHeight]
97-
enable=True
98-
[ZoomHeight_cfgBindings]
99-
zoom-height=<Alt-Key-2>
55+
# A fake extension for testing and example purposes. When enabled and
56+
# invoked, inserts or deletes z-text at beginning of every line.
57+
[ZzDummy]
58+
enable= True
59+
enable_shell = False
60+
enable_editor = True
61+
z-text= Z
62+
[ZzDummy_cfgBindings]
63+
z-in= <Control-Shift-KeyRelease-Insert>
64+
[ZzDummy_bindings]
65+
z-out= <Control-Shift-KeyRelease-Delete>

0 commit comments

Comments
 (0)