BLOCKOPENERS = {"class", "def", "elif", "else", "except", "finally", "for",
"if", "try", "while", "with", "async"}
UPDATEINTERVAL = 100 # millisec
-FONTUPDATEINTERVAL = 1000 # millisec
+CONFIGUPDATEINTERVAL = 1000 # millisec
def get_spaces_firstword(codeline, c=re.compile(r"^(\s*)(\w*)")):
class CodeContext:
"Display block context above the edit window."
- bgcolor = "LightGray"
- fgcolor = "Black"
-
def __init__(self, editwin):
"""Initialize settings for context block.
self.editwin = editwin
self.text = editwin.text
self.textfont = self.text["font"]
+ self.contextcolors = CodeContext.colors
self.label = None
self.topvisible = 1
self.info = [(0, -1, "", False)]
# Start two update cycles, one for context lines, one for font changes.
self.t1 = self.text.after(UPDATEINTERVAL, self.timer_event)
- self.t2 = self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
+ self.t2 = self.text.after(CONFIGUPDATEINTERVAL, self.config_timer_event)
@classmethod
def reload(cls):
"Load class variables from config."
cls.context_depth = idleConf.GetOption("extensions", "CodeContext",
"maxlines", type="int", default=15)
-## cls.bgcolor = idleConf.GetOption("extensions", "CodeContext",
-## "bgcolor", type="str", default="LightGray")
-## cls.fgcolor = idleConf.GetOption("extensions", "CodeContext",
-## "fgcolor", type="str", default="Black")
+ cls.colors = idleConf.GetHighlight(idleConf.CurrentTheme(), 'context')
def __del__(self):
"Cancel scheduled events."
self.label = tkinter.Label(
self.editwin.top, text="",
anchor=W, justify=LEFT, font=self.textfont,
- bg=self.bgcolor, fg=self.fgcolor,
+ bg=self.contextcolors['background'],
+ fg=self.contextcolors['foreground'],
width=1, # Don't request more than we get.
padx=padx, border=border, relief=SUNKEN)
# Pack the label widget before and above the text_frame widget,
self.update_code_context()
self.t1 = self.text.after(UPDATEINTERVAL, self.timer_event)
- def font_timer_event(self):
- "Event on editor text widget triggered every FONTUPDATEINTERVAL ms."
+ def config_timer_event(self):
+ "Event on editor text widget triggered every CONFIGUPDATEINTERVAL ms."
newtextfont = self.text["font"]
- if self.label and newtextfont != self.textfont:
+ if (self.label and (newtextfont != self.textfont or
+ CodeContext.colors != self.contextcolors)):
self.textfont = newtextfont
+ self.contextcolors = CodeContext.colors
self.label["font"] = self.textfont
- self.t2 = self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
+ self.label['background'] = self.contextcolors['background']
+ self.label['foreground'] = self.contextcolors['foreground']
+ self.t2 = self.text.after(CONFIGUPDATEINTERVAL, self.config_timer_event)
CodeContext.reload()
stderr-background= #ffffff
console-foreground= #770000
console-background= #ffffff
+context-foreground= #000000
+context-background= lightgray
[IDLE New]
normal-foreground= #000000
stderr-background= #ffffff
console-foreground= #770000
console-background= #ffffff
+context-foreground= #000000
+context-background= lightgray
[IDLE Dark]
comment-foreground = #dd0000
hit-foreground = #002240
comment-background = #002240
break-foreground = #FFFFFF
+context-foreground= #ffffff
+context-background= #454545
'stderr-background':'#ffffff',
'console-foreground':'#000000',
'console-background':'#ffffff',
+ 'context-foreground':'#000000',
+ 'context-background':'#ffffff',
}
for element in theme:
if not cfgParser.has_option(themeName, element):
"""
self.theme_elements = {
'Normal Text': ('normal', '00'),
- 'Python Keywords': ('keyword', '01'),
- 'Python Definitions': ('definition', '02'),
- 'Python Builtins': ('builtin', '03'),
- 'Python Comments': ('comment', '04'),
- 'Python Strings': ('string', '05'),
- 'Selected Text': ('hilite', '06'),
- 'Found Text': ('hit', '07'),
- 'Cursor': ('cursor', '08'),
- 'Editor Breakpoint': ('break', '09'),
- 'Shell Normal Text': ('console', '10'),
- 'Shell Error Text': ('error', '11'),
- 'Shell Stdout Text': ('stdout', '12'),
- 'Shell Stderr Text': ('stderr', '13'),
+ 'Code Context': ('context', '01'),
+ 'Python Keywords': ('keyword', '02'),
+ 'Python Definitions': ('definition', '03'),
+ 'Python Builtins': ('builtin', '04'),
+ 'Python Comments': ('comment', '05'),
+ 'Python Strings': ('string', '06'),
+ 'Selected Text': ('hilite', '07'),
+ 'Found Text': ('hit', '08'),
+ 'Cursor': ('cursor', '09'),
+ 'Editor Breakpoint': ('break', '10'),
+ 'Shell Normal Text': ('console', '11'),
+ 'Shell Error Text': ('error', '12'),
+ 'Shell Stdout Text': ('stdout', '13'),
+ 'Shell Stderr Text': ('stderr', '14'),
}
self.builtin_name = tracers.add(
StringVar(self), self.var_changed_builtin_name)
('\n', 'normal'),
('#you can click here', 'comment'), ('\n', 'normal'),
('#to choose items', 'comment'), ('\n', 'normal'),
+ ('code context section', 'context'), ('\n\n', 'normal'),
('def', 'keyword'), (' ', 'normal'),
('func', 'definition'), ('(param):\n ', 'normal'),
('"""string"""', 'string'), ('\n var0 = ', 'normal'),
def test_reload(self):
codecontext.CodeContext.reload()
+ self.assertEqual(self.cc.colors, {'background': 'lightgray',
+ 'foreground': '#000000'})
self.assertEqual(self.cc.context_depth, 15)
def test_toggle_code_context_event(self):
eq(toggle(), 'break')
self.assertIsNotNone(cc.label)
eq(cc.label['font'], cc.textfont)
- eq(cc.label['fg'], cc.fgcolor)
- eq(cc.label['bg'], cc.bgcolor)
+ eq(cc.label['fg'], cc.colors['foreground'])
+ eq(cc.label['bg'], cc.colors['background'])
eq(cc.label['text'], '')
# Toggle off.
self.cc.timer_event()
mock_update.assert_called()
- def test_font_timer_event(self):
+ def test_config_timer_event(self):
eq = self.assertEqual
cc = self.cc
save_font = cc.text['font']
+ save_colors = codecontext.CodeContext.colors
test_font = 'FakeFont'
+ test_colors = {'background': '#222222', 'foreground': '#ffff00'}
# Ensure code context is not active.
if cc.label:
# Nothing updates on inactive code context.
cc.text['font'] = test_font
- cc.font_timer_event()
+ codecontext.CodeContext.colors = test_colors
+ cc.config_timer_event()
eq(cc.textfont, save_font)
+ eq(cc.contextcolors, save_colors)
- # Activate code context, but no change to font.
+ # Activate code context, but no change to font or color.
cc.toggle_code_context_event()
cc.text['font'] = save_font
- cc.font_timer_event()
+ codecontext.CodeContext.colors = save_colors
+ cc.config_timer_event()
eq(cc.textfont, save_font)
+ eq(cc.contextcolors, save_colors)
eq(cc.label['font'], save_font)
+ eq(cc.label['background'], save_colors['background'])
+ eq(cc.label['foreground'], save_colors['foreground'])
# Active code context, change font.
cc.text['font'] = test_font
- cc.font_timer_event()
+ cc.config_timer_event()
eq(cc.textfont, test_font)
+ eq(cc.contextcolors, save_colors)
eq(cc.label['font'], test_font)
+ eq(cc.label['background'], save_colors['background'])
+ eq(cc.label['foreground'], save_colors['foreground'])
+ # Active code context, change color.
cc.text['font'] = save_font
- cc.font_timer_event()
+ codecontext.CodeContext.colors = test_colors
+ cc.config_timer_event()
+ eq(cc.textfont, save_font)
+ eq(cc.contextcolors, test_colors)
+ eq(cc.label['font'], save_font)
+ eq(cc.label['background'], test_colors['background'])
+ eq(cc.label['foreground'], test_colors['foreground'])
+ codecontext.CodeContext.colors = save_colors
+ cc.config_timer_event()
class HelperFunctionText(unittest.TestCase):
--- /dev/null
+IDLE: Re-enable color configuration for Code Context.
+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.