1919
2020BLOCKOPENERS = {"class" , "def" , "elif" , "else" , "except" , "finally" , "for" ,
2121 "if" , "try" , "while" , "with" , "async" }
22- UPDATEINTERVAL = 100 # millisec
23- CONFIGUPDATEINTERVAL = 1000 # millisec
2422
2523
2624def get_spaces_firstword (codeline , c = re .compile (r"^(\s*)(\w*)" )):
@@ -44,13 +42,13 @@ def get_line_info(codeline):
4442
4543class CodeContext :
4644 "Display block context above the edit window."
45+ UPDATEINTERVAL = 100 # millisec
4746
4847 def __init__ (self , editwin ):
4948 """Initialize settings for context block.
5049
5150 editwin is the Editor window for the context block.
5251 self.text is the editor window text widget.
53- self.textfont is the editor window font.
5452
5553 self.context displays the code context text above the editor text.
5654 Initially None, it is toggled via <<toggle-code-context>>.
@@ -65,29 +63,26 @@ def __init__(self, editwin):
6563 """
6664 self .editwin = editwin
6765 self .text = editwin .text
68- self .textfont = self .text ["font" ]
69- self .contextcolors = CodeContext .colors
7066 self .context = None
7167 self .topvisible = 1
7268 self .info = [(0 , - 1 , "" , False )]
73- # Start two update cycles, one for context lines, one for font changes.
74- self .t1 = self .text .after (UPDATEINTERVAL , self .timer_event )
75- self .t2 = self .text .after (CONFIGUPDATEINTERVAL , self .config_timer_event )
69+ self .t1 = None
7670
7771 @classmethod
7872 def reload (cls ):
7973 "Load class variables from config."
8074 cls .context_depth = idleConf .GetOption ("extensions" , "CodeContext" ,
81- "maxlines" , type = "int" , default = 15 )
82- cls . colors = idleConf . GetHighlight ( idleConf . CurrentTheme (), 'context' )
75+ "maxlines" , type = "int" ,
76+ default = 15 )
8377
8478 def __del__ (self ):
8579 "Cancel scheduled events."
86- try :
87- self .text .after_cancel (self .t1 )
88- self .text .after_cancel (self .t2 )
89- except :
90- pass
80+ if self .t1 is not None :
81+ try :
82+ self .text .after_cancel (self .t1 )
83+ except tkinter .TclError :
84+ pass
85+ self .t1 = None
9186
9287 def toggle_code_context_event (self , event = None ):
9388 """Toggle code context display.
@@ -96,7 +91,7 @@ def toggle_code_context_event(self, event=None):
9691 window text (toggle on). If it does exist, destroy it (toggle off).
9792 Return 'break' to complete the processing of the binding.
9893 """
99- if not self .context :
94+ if self .context is None :
10095 # Calculate the border width and horizontal padding required to
10196 # align the context with the text in the main Text widget.
10297 #
@@ -111,21 +106,23 @@ def toggle_code_context_event(self, event=None):
111106 padx += widget .tk .getint (widget .cget ('padx' ))
112107 border += widget .tk .getint (widget .cget ('border' ))
113108 self .context = tkinter .Text (
114- self .editwin .top , font = self .textfont ,
115- bg = self .contextcolors ['background' ],
116- fg = self .contextcolors ['foreground' ],
117- height = 1 ,
118- width = 1 , # Don't request more than we get.
119- padx = padx , border = border , relief = SUNKEN , state = 'disabled' )
109+ self .editwin .top , font = self .text ['font' ],
110+ height = 1 ,
111+ width = 1 , # Don't request more than we get.
112+ padx = padx , border = border , relief = SUNKEN , state = 'disabled' )
113+ self .update_highlight_colors ()
120114 self .context .bind ('<ButtonRelease-1>' , self .jumptoline )
121115 # Pack the context widget before and above the text_frame widget,
122116 # thus ensuring that it will appear directly above text_frame.
123117 self .context .pack (side = TOP , fill = X , expand = False ,
124- before = self .editwin .text_frame )
118+ before = self .editwin .text_frame )
125119 menu_status = 'Hide'
120+ self .t1 = self .text .after (self .UPDATEINTERVAL , self .timer_event )
126121 else :
127122 self .context .destroy ()
128123 self .context = None
124+ self .text .after_cancel (self .t1 )
125+ self .t1 = None
129126 menu_status = 'Show'
130127 self .editwin .update_menu_label (menu = 'options' , index = '* Code Context' ,
131128 label = f'{ menu_status } Code Context' )
@@ -169,7 +166,7 @@ def update_code_context(self):
169166 be retrieved and the context area will be updated with the code,
170167 up to the number of maxlines.
171168 """
172- new_topvisible = int ( self .text . index ("@0,0" ). split ( '.' )[ 0 ] )
169+ new_topvisible = self .editwin . getlineno ("@0,0" )
173170 if self .topvisible == new_topvisible : # Haven't scrolled.
174171 return
175172 if self .topvisible < new_topvisible : # Scroll down.
@@ -217,21 +214,19 @@ def jumptoline(self, event=None):
217214
218215 def timer_event (self ):
219216 "Event on editor text widget triggered every UPDATEINTERVAL ms."
220- if self .context :
217+ if self .context is not None :
221218 self .update_code_context ()
222- self .t1 = self .text .after (UPDATEINTERVAL , self .timer_event )
223-
224- def config_timer_event (self ):
225- "Event on editor text widget triggered every CONFIGUPDATEINTERVAL ms."
226- newtextfont = self .text ["font" ]
227- if (self .context and (newtextfont != self .textfont or
228- CodeContext .colors != self .contextcolors )):
229- self .textfont = newtextfont
230- self .contextcolors = CodeContext .colors
231- self .context ["font" ] = self .textfont
232- self .context ['background' ] = self .contextcolors ['background' ]
233- self .context ['foreground' ] = self .contextcolors ['foreground' ]
234- self .t2 = self .text .after (CONFIGUPDATEINTERVAL , self .config_timer_event )
219+ self .t1 = self .text .after (self .UPDATEINTERVAL , self .timer_event )
220+
221+ def update_font (self , font ):
222+ if self .context is not None :
223+ self .context ['font' ] = font
224+
225+ def update_highlight_colors (self ):
226+ if self .context is not None :
227+ colors = idleConf .GetHighlight (idleConf .CurrentTheme (), 'context' )
228+ self .context ['background' ] = colors ['background' ]
229+ self .context ['foreground' ] = colors ['foreground' ]
235230
236231
237232CodeContext .reload ()
0 commit comments