Skip to content

Commit dd851d6

Browse files
bpo-33679: IDLE: Re-enable color configuration for code context (GH-7199)
The difference from before is that the settings are now on the Highlights tab instead of the Extensions tab and only change one theme at a time instead of all themes. The default for light themes is black on light gray, as before. The default for the IDLE Dark theme is white on dark gray, which better fits the dark theme. When one starts IDLE from a console and loads a custom theme without definitions for 'context', one will see a warning message on the console. To stop the warning, go to Options => Configure IDLE => Highlights, select the custom theme if not selected already, select 'Code Context', and select foreground and background colors. (cherry picked from commit de65162) Co-authored-by: Cheryl Sabella <cheryl.sabella@gmail.com>
1 parent a42fe3c commit dd851d6

File tree

6 files changed

+79
-35
lines changed

6 files changed

+79
-35
lines changed

Lib/idlelib/codecontext.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
BLOCKOPENERS = {"class", "def", "elif", "else", "except", "finally", "for",
2121
"if", "try", "while", "with", "async"}
2222
UPDATEINTERVAL = 100 # millisec
23-
FONTUPDATEINTERVAL = 1000 # millisec
23+
CONFIGUPDATEINTERVAL = 1000 # millisec
2424

2525

2626
def get_spaces_firstword(codeline, c=re.compile(r"^(\s*)(\w*)")):
@@ -45,9 +45,6 @@ def get_line_info(codeline):
4545
class CodeContext:
4646
"Display block context above the edit window."
4747

48-
bgcolor = "LightGray"
49-
fgcolor = "Black"
50-
5148
def __init__(self, editwin):
5249
"""Initialize settings for context block.
5350
@@ -69,22 +66,20 @@ def __init__(self, editwin):
6966
self.editwin = editwin
7067
self.text = editwin.text
7168
self.textfont = self.text["font"]
69+
self.contextcolors = CodeContext.colors
7270
self.label = None
7371
self.topvisible = 1
7472
self.info = [(0, -1, "", False)]
7573
# Start two update cycles, one for context lines, one for font changes.
7674
self.t1 = self.text.after(UPDATEINTERVAL, self.timer_event)
77-
self.t2 = self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
75+
self.t2 = self.text.after(CONFIGUPDATEINTERVAL, self.config_timer_event)
7876

7977
@classmethod
8078
def reload(cls):
8179
"Load class variables from config."
8280
cls.context_depth = idleConf.GetOption("extensions", "CodeContext",
8381
"maxlines", type="int", default=15)
84-
## cls.bgcolor = idleConf.GetOption("extensions", "CodeContext",
85-
## "bgcolor", type="str", default="LightGray")
86-
## cls.fgcolor = idleConf.GetOption("extensions", "CodeContext",
87-
## "fgcolor", type="str", default="Black")
82+
cls.colors = idleConf.GetHighlight(idleConf.CurrentTheme(), 'context')
8883

8984
def __del__(self):
9085
"Cancel scheduled events."
@@ -118,7 +113,8 @@ def toggle_code_context_event(self, event=None):
118113
self.label = tkinter.Label(
119114
self.editwin.top, text="",
120115
anchor=W, justify=LEFT, font=self.textfont,
121-
bg=self.bgcolor, fg=self.fgcolor,
116+
bg=self.contextcolors['background'],
117+
fg=self.contextcolors['foreground'],
122118
width=1, # Don't request more than we get.
123119
padx=padx, border=border, relief=SUNKEN)
124120
# Pack the label widget before and above the text_frame widget,
@@ -202,13 +198,17 @@ def timer_event(self):
202198
self.update_code_context()
203199
self.t1 = self.text.after(UPDATEINTERVAL, self.timer_event)
204200

205-
def font_timer_event(self):
206-
"Event on editor text widget triggered every FONTUPDATEINTERVAL ms."
201+
def config_timer_event(self):
202+
"Event on editor text widget triggered every CONFIGUPDATEINTERVAL ms."
207203
newtextfont = self.text["font"]
208-
if self.label and newtextfont != self.textfont:
204+
if (self.label and (newtextfont != self.textfont or
205+
CodeContext.colors != self.contextcolors)):
209206
self.textfont = newtextfont
207+
self.contextcolors = CodeContext.colors
210208
self.label["font"] = self.textfont
211-
self.t2 = self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
209+
self.label['background'] = self.contextcolors['background']
210+
self.label['foreground'] = self.contextcolors['foreground']
211+
self.t2 = self.text.after(CONFIGUPDATEINTERVAL, self.config_timer_event)
212212

213213

214214
CodeContext.reload()

Lib/idlelib/config-highlight.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ stderr-foreground= red
3131
stderr-background= #ffffff
3232
console-foreground= #770000
3333
console-background= #ffffff
34+
context-foreground= #000000
35+
context-background= lightgray
3436

3537
[IDLE New]
3638
normal-foreground= #000000
@@ -62,6 +64,8 @@ stderr-foreground= red
6264
stderr-background= #ffffff
6365
console-foreground= #770000
6466
console-background= #ffffff
67+
context-foreground= #000000
68+
context-background= lightgray
6569

6670
[IDLE Dark]
6771
comment-foreground = #dd0000
@@ -91,3 +95,5 @@ stdout-background = #002240
9195
hit-foreground = #002240
9296
comment-background = #002240
9397
break-foreground = #FFFFFF
98+
context-foreground= #ffffff
99+
context-background= #454545

Lib/idlelib/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,8 @@ def GetThemeDict(self, type, themeName):
360360
'stderr-background':'#ffffff',
361361
'console-foreground':'#000000',
362362
'console-background':'#ffffff',
363+
'context-foreground':'#000000',
364+
'context-background':'#ffffff',
363365
}
364366
for element in theme:
365367
if not cfgParser.has_option(themeName, element):

Lib/idlelib/configdialog.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -799,19 +799,20 @@ def create_page_highlight(self):
799799
"""
800800
self.theme_elements = {
801801
'Normal Text': ('normal', '00'),
802-
'Python Keywords': ('keyword', '01'),
803-
'Python Definitions': ('definition', '02'),
804-
'Python Builtins': ('builtin', '03'),
805-
'Python Comments': ('comment', '04'),
806-
'Python Strings': ('string', '05'),
807-
'Selected Text': ('hilite', '06'),
808-
'Found Text': ('hit', '07'),
809-
'Cursor': ('cursor', '08'),
810-
'Editor Breakpoint': ('break', '09'),
811-
'Shell Normal Text': ('console', '10'),
812-
'Shell Error Text': ('error', '11'),
813-
'Shell Stdout Text': ('stdout', '12'),
814-
'Shell Stderr Text': ('stderr', '13'),
802+
'Code Context': ('context', '01'),
803+
'Python Keywords': ('keyword', '02'),
804+
'Python Definitions': ('definition', '03'),
805+
'Python Builtins': ('builtin', '04'),
806+
'Python Comments': ('comment', '05'),
807+
'Python Strings': ('string', '06'),
808+
'Selected Text': ('hilite', '07'),
809+
'Found Text': ('hit', '08'),
810+
'Cursor': ('cursor', '09'),
811+
'Editor Breakpoint': ('break', '10'),
812+
'Shell Normal Text': ('console', '11'),
813+
'Shell Error Text': ('error', '12'),
814+
'Shell Stdout Text': ('stdout', '13'),
815+
'Shell Stderr Text': ('stderr', '14'),
815816
}
816817
self.builtin_name = tracers.add(
817818
StringVar(self), self.var_changed_builtin_name)
@@ -842,6 +843,7 @@ def create_page_highlight(self):
842843
('\n', 'normal'),
843844
('#you can click here', 'comment'), ('\n', 'normal'),
844845
('#to choose items', 'comment'), ('\n', 'normal'),
846+
('code context section', 'context'), ('\n\n', 'normal'),
845847
('def', 'keyword'), (' ', 'normal'),
846848
('func', 'definition'), ('(param):\n ', 'normal'),
847849
('"""string"""', 'string'), ('\n var0 = ', 'normal'),

Lib/idlelib/idle_test/test_codecontext.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ def test_del(self):
110110

111111
def test_reload(self):
112112
codecontext.CodeContext.reload()
113+
self.assertEqual(self.cc.colors, {'background': 'lightgray',
114+
'foreground': '#000000'})
113115
self.assertEqual(self.cc.context_depth, 15)
114116

115117
def test_toggle_code_context_event(self):
@@ -125,8 +127,8 @@ def test_toggle_code_context_event(self):
125127
eq(toggle(), 'break')
126128
self.assertIsNotNone(cc.label)
127129
eq(cc.label['font'], cc.textfont)
128-
eq(cc.label['fg'], cc.fgcolor)
129-
eq(cc.label['bg'], cc.bgcolor)
130+
eq(cc.label['fg'], cc.colors['foreground'])
131+
eq(cc.label['bg'], cc.colors['background'])
130132
eq(cc.label['text'], '')
131133

132134
# Toggle off.
@@ -275,36 +277,56 @@ def test_timer_event(self, mock_update):
275277
self.cc.timer_event()
276278
mock_update.assert_called()
277279

278-
def test_font_timer_event(self):
280+
def test_config_timer_event(self):
279281
eq = self.assertEqual
280282
cc = self.cc
281283
save_font = cc.text['font']
284+
save_colors = codecontext.CodeContext.colors
282285
test_font = 'FakeFont'
286+
test_colors = {'background': '#222222', 'foreground': '#ffff00'}
283287

284288
# Ensure code context is not active.
285289
if cc.label:
286290
cc.toggle_code_context_event()
287291

288292
# Nothing updates on inactive code context.
289293
cc.text['font'] = test_font
290-
cc.font_timer_event()
294+
codecontext.CodeContext.colors = test_colors
295+
cc.config_timer_event()
291296
eq(cc.textfont, save_font)
297+
eq(cc.contextcolors, save_colors)
292298

293-
# Activate code context, but no change to font.
299+
# Activate code context, but no change to font or color.
294300
cc.toggle_code_context_event()
295301
cc.text['font'] = save_font
296-
cc.font_timer_event()
302+
codecontext.CodeContext.colors = save_colors
303+
cc.config_timer_event()
297304
eq(cc.textfont, save_font)
305+
eq(cc.contextcolors, save_colors)
298306
eq(cc.label['font'], save_font)
307+
eq(cc.label['background'], save_colors['background'])
308+
eq(cc.label['foreground'], save_colors['foreground'])
299309

300310
# Active code context, change font.
301311
cc.text['font'] = test_font
302-
cc.font_timer_event()
312+
cc.config_timer_event()
303313
eq(cc.textfont, test_font)
314+
eq(cc.contextcolors, save_colors)
304315
eq(cc.label['font'], test_font)
316+
eq(cc.label['background'], save_colors['background'])
317+
eq(cc.label['foreground'], save_colors['foreground'])
305318

319+
# Active code context, change color.
306320
cc.text['font'] = save_font
307-
cc.font_timer_event()
321+
codecontext.CodeContext.colors = test_colors
322+
cc.config_timer_event()
323+
eq(cc.textfont, save_font)
324+
eq(cc.contextcolors, test_colors)
325+
eq(cc.label['font'], save_font)
326+
eq(cc.label['background'], test_colors['background'])
327+
eq(cc.label['foreground'], test_colors['foreground'])
328+
codecontext.CodeContext.colors = save_colors
329+
cc.config_timer_event()
308330

309331

310332
class HelperFunctionText(unittest.TestCase):
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
IDLE: Re-enable color configuration for Code Context.
2+
The difference from before is that the settings are now on the
3+
Highlights tab instead of the Extensions tab and only change one theme
4+
at a time instead of all themes. The default for light themes is black
5+
on light gray, as before. The default for the IDLE Dark theme is white
6+
on dark gray, which better fits the dark theme.
7+
8+
When one starts IDLE from a console and loads a custom theme without
9+
definitions for 'context', one will see a warning message on the console.
10+
To stop the warning, go to Options => Configure IDLE => Highlights,
11+
select the custom theme if not selected already, select 'Code Context',
12+
and select foreground and background colors.

0 commit comments

Comments
 (0)