def __init__(self, master=None, **kwargs): # get default settings from user's IDLE configuration currentTheme = idleConf.CurrentTheme() textcf = dict(padx=5, wrap='word', undo='True', foreground=idleConf.GetHighlight(currentTheme, 'normal', fgBg='fg'), background=idleConf.GetHighlight(currentTheme, 'normal', fgBg='bg'), highlightcolor=idleConf.GetHighlight(currentTheme, 'hilite', fgBg='fg'), highlightbackground=idleConf.GetHighlight(currentTheme, 'hilite', fgBg='bg'), insertbackground=idleConf.GetHighlight(currentTheme, 'cursor', fgBg='fg'), width=idleConf.GetOption('main', 'EditorWindow', 'width'), height=idleConf.GetOption('main', 'EditorWindow', 'height')) fontWeight = 'normal' if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'): fontWeight = 'bold' textcf['font'] = (idleConf.GetOption('main', 'EditorWindow', 'font'), idleConf.GetOption('main', 'EditorWindow', 'font-size'), fontWeight) # override defaults with any user-specified settings textcf.update(kwargs) ScrolledText.__init__(self, master, **textcf)
def init(self, flist): self.flist = flist # reset pyclbr pyclbr._modules.clear() # create top # NOTE: later we will be passed in container, rather than creating it self.top = top = flist.new_container(own_window=True) self.top.add_component(self) top.top.bind("<Escape>", self.close) if self._htest: # place dialog below parent if running htest top.top.geometry( "+%d+%d" % (flist.root.winfo_rootx(), flist.root.winfo_rooty() + 200)) top.top.focus_set() # create scrolled canvas theme = idleConf.CurrentTheme() background = idleConf.GetHighlight(theme, 'normal')['background'] sc = ScrolledCanvas(top.w, bg=background, highlightthickness=0, takefocus=1) sc.frame.pack(expand=1, fill="both") item = self.rootnode() self.node = node = TreeNode(sc.canvas, None, item) node.update() node.expand()
def LoadThemeCfg(self): self.themeIsBuiltin.set(idleConf.GetOption('main', 'Theme', 'default', type='bool', default=1)) currentOption = idleConf.CurrentTheme() if self.themeIsBuiltin.get(): itemList = idleConf.GetSectionList('default', 'highlight') itemList.sort() self.optMenuThemeBuiltin.SetMenu(itemList, currentOption) itemList = idleConf.GetSectionList('user', 'highlight') itemList.sort() if not itemList: self.radioThemeCustom.config(state=DISABLED) self.customTheme.set('- no custom themes -') else: self.optMenuThemeCustom.SetMenu(itemList, itemList[0]) else: itemList = idleConf.GetSectionList('user', 'highlight') itemList.sort() self.optMenuThemeCustom.SetMenu(itemList, currentOption) itemList = idleConf.GetSectionList('default', 'highlight') itemList.sort() self.optMenuThemeBuiltin.SetMenu(itemList, itemList[0]) self.SetThemeType() themeNames = self.themeElements.keys() themeNames.sort(key=lambda x: self.themeElements[x][1]) self.optMenuHighlightTarget.SetMenu(themeNames, themeNames[0]) self.PaintThemeSample() self.SetHighlightTarget()
def __init__(self, master=None, **kwargs): """ Constructor. Get default settings from user's IDLE configuration. """ currentTheme = idleConf.CurrentTheme() textcf = { 'padx': 5, 'wrap': 'word', 'undo': 'True', 'foreground': idleConf.GetHighlight( currentTheme, 'normal', fgBg='fg'), 'background': idleConf.GetHighlight( currentTheme, 'normal', fgBg='bg'), 'highlightcolor': idleConf.GetHighlight( currentTheme, 'hilite', fgBg='fg'), 'highlightbackground': idleConf.GetHighlight( currentTheme, 'hilite', fgBg='bg'), 'insertbackground': idleConf.GetHighlight( currentTheme, 'cursor', fgBg='fg'), 'width': idleConf.GetOption('main', 'EditorWindow', 'width'), 'height': idleConf.GetOption('main', 'EditorWindow', 'height'), } fontWeight = 'normal' if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'): fontWeight = 'bold' textcf['font'] = (idleConf.GetOption('main', 'EditorWindow', 'font'), idleConf.GetOption('main', 'EditorWindow', 'font-size'), fontWeight) # override defaults with any user-specified settings textcf.update(kwargs) ScrolledText.__init__(self, master, **textcf)
def init(self, flist): self.flist = flist # reset pyclbr pyclbr._modules.clear() # create top self.top = top = ListedToplevel(flist.root) top.protocol("WM_DELETE_WINDOW", self.close) top.bind("<Escape>", self.close) if self._htest: # place dialog below parent if running htest top.geometry( "+%d+%d" % (flist.root.winfo_rootx(), flist.root.winfo_rooty() + 200)) self.settitle() top.focus_set() # create scrolled canvas theme = idleConf.CurrentTheme() background = idleConf.GetHighlight(theme, 'normal')['background'] sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1) sc.frame.pack(expand=1, fill="both") item = self.rootnode() self.node = node = TreeNode(sc.canvas, None, item) node.update() node.expand()
def show_find_marks(self): # Get the highlight colors for 'hit' # Do this here (and not in __init__) for color config changes to take # effect immediately currentTheme = idleConf.CurrentTheme() mark_fg = idleConf.GetHighlight(currentTheme, 'hit', fgBg='fg') mark_bg = idleConf.GetHighlight(currentTheme, 'hit', fgBg='bg') self.text.tag_configure("findmark", foreground=mark_fg, background=mark_bg)
def LoadTagDefs(self): theme = idleConf.CurrentTheme() self.tagdefs = { "COMMENT": idleConf.GetHighlight(theme, "comment"), "KEYWORD": idleConf.GetHighlight(theme, "keyword"), "BUILTIN": idleConf.GetHighlight(theme, "builtin"), "STRING": idleConf.GetHighlight(theme, "string"), "DEFINITION": idleConf.GetHighlight(theme, "definition"), "SYNC": {'background':None,'foreground':None}, "TODO": {'background':None,'foreground':None}, "ERROR": idleConf.GetHighlight(theme, "error"), # The following is used by ReplaceDialog: "hit": idleConf.GetHighlight(theme, "hit"), } if DEBUG: print 'tagdefs',self.tagdefs
def color_config(text): # Called from htest, Editor, and Turtle Demo. '''Set color opitons of Text widget. Should be called whenever ColorDelegator is called. ''' # Not automatic because ColorDelegator does not know 'text'. theme = idleConf.CurrentTheme() normal_colors = idleConf.GetHighlight(theme, 'normal') cursor_color = idleConf.GetHighlight(theme, 'cursor', fgBg='fg') select_colors = idleConf.GetHighlight(theme, 'hilite') text.config( foreground=normal_colors['foreground'], background=normal_colors['background'], insertbackground=cursor_color, selectforeground=select_colors['foreground'], selectbackground=select_colors['background'], ) if TkVersion >= 8.5: text.config(inactiveselectbackground=select_colors['background'])
def drawtext(self): textx = self.x + 20 - 1 texty = self.y - 4 labeltext = self.item.GetLabelText() if labeltext: id = self.canvas.create_text(textx, texty, anchor="nw", text=labeltext) self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) x0, y0, x1, y1 = self.canvas.bbox(id) textx = max(x1, 200) + 10 text = self.item.GetText() or "<no text>" try: self.entry except AttributeError: pass else: self.edit_finish() try: self.label except AttributeError: # padding carefully selected (on Windows) to match Entry widget: self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2) theme = idleConf.CurrentTheme() if self.selected: self.label.configure(idleConf.GetHighlight(theme, 'hilite')) else: self.label.configure(idleConf.GetHighlight(theme, 'normal')) id = self.canvas.create_window(textx, texty, anchor="nw", window=self.label) self.label.bind("<1>", self.select_or_edit) self.label.bind("<Double-1>", self.flip) self.text_id = id
class ParenMatch: """Highlight matching parentheses There are three supported style of paren matching, based loosely on the Emacs options. The style is select based on the HILITE_STYLE attribute; it can be changed used the set_style method. The supported styles are: default -- When a right paren is typed, highlight the matching left paren for 1/2 sec. expression -- When a right paren is typed, highlight the entire expression from the left paren to the right paren. TODO: - extend IDLE with configuration dialog to change options - implement rest of Emacs highlight styles (see below) - print mismatch warning in IDLE status window Note: In Emacs, there are several styles of highlight where the matching paren is highlighted whenever the cursor is immediately to the right of a right paren. I don't know how to do that in Tk, so I haven't bothered. """ menudefs = [('edit', [ ("Show surrounding parens", "<<flash-paren>>"), ])] STYLE = idleConf.GetOption('extensions', 'ParenMatch', 'style', default='expression') FLASH_DELAY = idleConf.GetOption('extensions', 'ParenMatch', 'flash-delay', type='int', default=500) HILITE_CONFIG = idleConf.GetHighlight(idleConf.CurrentTheme(), 'hilite') BELL = idleConf.GetOption('extensions', 'ParenMatch', 'bell', type='bool', default=1) RESTORE_VIRTUAL_EVENT_NAME = "<<parenmatch-check-restore>>" # We want the restore event be called before the usual return and # backspace events. RESTORE_SEQUENCES = ("<KeyPress>", "<ButtonPress>", "<Key-Return>", "<Key-BackSpace>") def __init__(self, editwin): self.editwin = editwin self.text = editwin.text # Bind the check-restore event to the function restore_event, # so that we can then use activate_restore (which calls event_add) # and deactivate_restore (which calls event_delete). editwin.text.bind(self.RESTORE_VIRTUAL_EVENT_NAME, self.restore_event) self.counter = 0 self.is_restore_active = 0 self.set_style(self.STYLE) def activate_restore(self): if not self.is_restore_active: for seq in self.RESTORE_SEQUENCES: self.text.event_add(self.RESTORE_VIRTUAL_EVENT_NAME, seq) self.is_restore_active = True def deactivate_restore(self): if self.is_restore_active: for seq in self.RESTORE_SEQUENCES: self.text.event_delete(self.RESTORE_VIRTUAL_EVENT_NAME, seq) self.is_restore_active = False def set_style(self, style): self.STYLE = style if style == "default": self.create_tag = self.create_tag_default self.set_timeout = self.set_timeout_last elif style == "expression": self.create_tag = self.create_tag_expression self.set_timeout = self.set_timeout_none def flash_paren_event(self, event): indices = HyperParser(self.editwin, "insert").get_surrounding_brackets() if indices is None: self.warn_mismatched() return self.activate_restore() self.create_tag(indices) self.set_timeout_last() def paren_closed_event(self, event): # If it was a shortcut and not really a closing paren, quit. closer = self.text.get("insert-1c") if closer not in _openers: return hp = HyperParser(self.editwin, "insert-1c") if not hp.is_in_code(): return indices = hp.get_surrounding_brackets(_openers[closer], True) if indices is None: self.warn_mismatched() return self.activate_restore() self.create_tag(indices) self.set_timeout() def restore_event(self, event=None): self.text.tag_delete("paren") self.deactivate_restore() self.counter += 1 # disable the last timer, if there is one. def handle_restore_timer(self, timer_count): if timer_count == self.counter: self.restore_event() def warn_mismatched(self): if self.BELL: self.text.bell() # any one of the create_tag_XXX methods can be used depending on # the style def create_tag_default(self, indices): """Highlight the single paren that matches""" self.text.tag_add("paren", indices[0]) self.text.tag_config("paren", self.HILITE_CONFIG) def create_tag_expression(self, indices): """Highlight the entire expression""" if self.text.get(indices[1]) in (')', ']', '}'): rightindex = indices[1] + "+1c" else: rightindex = indices[1] self.text.tag_add("paren", indices[0], rightindex) self.text.tag_config("paren", self.HILITE_CONFIG) # any one of the set_timeout_XXX methods can be used depending on # the style def set_timeout_none(self): """Highlight will remain until user input turns it off or the insert has moved""" # After CHECK_DELAY, call a function which disables the "paren" tag # if the event is for the most recent timer and the insert has changed, # or schedules another call for itself. self.counter += 1 def callme(callme, self=self, c=self.counter, index=self.text.index("insert")): if index != self.text.index("insert"): self.handle_restore_timer(c) else: self.editwin.text_frame.after(CHECK_DELAY, callme, callme) self.editwin.text_frame.after(CHECK_DELAY, callme, callme) def set_timeout_last(self): """The last highlight created will be removed after .5 sec""" # associate a counter with an event; only disable the "paren" # tag if the event is for the most recent timer. self.counter += 1 self.editwin.text_frame.after(self.FLASH_DELAY, lambda self=self, c=self.counter: \ self.handle_restore_timer(c))
def __init__(self, flist=None, filename=None, key=None, root=None): if EditorWindow.help_url is None: dochome = os.path.join(sys.prefix, 'Doc', 'index.html') if sys.platform.count('linux'): pyver = 'python-docs-' + '%s.%s.%s' % sys.version_info[:3] if os.path.isdir('/var/www/html/python/'): dochome = '/var/www/html/python/index.html' else: basepath = '/usr/share/doc/' dochome = os.path.join(basepath, pyver, 'Doc', 'index.html') elif sys.platform[:3] == 'win': chmfile = os.path.join(sys.prefix, 'Doc', 'Python%s.chm' % _sphinx_version()) if os.path.isfile(chmfile): dochome = chmfile elif macosxSupport.runningAsOSXApp(): dochome = os.path.join(sys.prefix, 'Resources/English.lproj/Documentation/index.html') dochome = os.path.normpath(dochome) if os.path.isfile(dochome): EditorWindow.help_url = dochome if sys.platform == 'darwin': EditorWindow.help_url = 'file://' + EditorWindow.help_url else: EditorWindow.help_url = 'http://docs.python.org/%d.%d' % sys.version_info[:2] currentTheme = idleConf.CurrentTheme() self.flist = flist root = root or flist.root self.root = root try: sys.ps1 except AttributeError: sys.ps1 = '>>> ' self.menubar = Menu(root) self.top = top = WindowList.ListedToplevel(root, menu=self.menubar) if flist: self.tkinter_vars = flist.vars self.top.instance_dict = flist.inversedict else: self.tkinter_vars = {} self.top.instance_dict = {} self.recent_files_path = os.path.join(idleConf.GetUserCfgDir(), 'recent-files.lst') self.text_frame = text_frame = Frame(top) self.vbar = vbar = Scrollbar(text_frame, name='vbar') self.width = idleConf.GetOption('main', 'EditorWindow', 'width') text_options = {'name': 'text', 'padx': 5, 'wrap': 'none', 'width': self.width, 'height': idleConf.GetOption('main', 'EditorWindow', 'height') } if TkVersion >= 8.5: text_options['tabstyle'] = 'wordprocessor' self.text = text = MultiCallCreator(Text)(text_frame, **text_options) self.top.focused_widget = self.text self.createmenubar() self.apply_bindings() self.top.protocol('WM_DELETE_WINDOW', self.close) self.top.bind('<<close-window>>', self.close_event) if macosxSupport.runningAsOSXApp(): text.bind('<<close-window>>', self.close_event) text.bind('<Control-Button-1>', self.right_menu_event) else: text.bind('<3>', self.right_menu_event) text.bind('<<cut>>', self.cut) text.bind('<<copy>>', self.copy) text.bind('<<paste>>', self.paste) text.bind('<<center-insert>>', self.center_insert_event) text.bind('<<help>>', self.help_dialog) text.bind('<<python-docs>>', self.python_docs) text.bind('<<about-idle>>', self.about_dialog) text.bind('<<open-config-dialog>>', self.config_dialog) text.bind('<<open-module>>', self.open_module) text.bind('<<do-nothing>>', lambda event: 'break') text.bind('<<select-all>>', self.select_all) text.bind('<<remove-selection>>', self.remove_selection) text.bind('<<find>>', self.find_event) text.bind('<<find-again>>', self.find_again_event) text.bind('<<find-in-files>>', self.find_in_files_event) text.bind('<<find-selection>>', self.find_selection_event) text.bind('<<replace>>', self.replace_event) text.bind('<<goto-line>>', self.goto_line_event) text.bind('<<smart-backspace>>', self.smart_backspace_event) text.bind('<<newline-and-indent>>', self.newline_and_indent_event) text.bind('<<smart-indent>>', self.smart_indent_event) text.bind('<<indent-region>>', self.indent_region_event) text.bind('<<dedent-region>>', self.dedent_region_event) text.bind('<<comment-region>>', self.comment_region_event) text.bind('<<uncomment-region>>', self.uncomment_region_event) text.bind('<<tabify-region>>', self.tabify_region_event) text.bind('<<untabify-region>>', self.untabify_region_event) text.bind('<<toggle-tabs>>', self.toggle_tabs_event) text.bind('<<change-indentwidth>>', self.change_indentwidth_event) text.bind('<Left>', self.move_at_edge_if_selection(0)) text.bind('<Right>', self.move_at_edge_if_selection(1)) text.bind('<<del-word-left>>', self.del_word_left) text.bind('<<del-word-right>>', self.del_word_right) text.bind('<<beginning-of-line>>', self.home_callback) if flist: flist.inversedict[self] = key if key: flist.dict[key] = self text.bind('<<open-new-window>>', self.new_callback) text.bind('<<close-all-windows>>', self.flist.close_all_callback) text.bind('<<open-class-browser>>', self.open_class_browser) text.bind('<<open-path-browser>>', self.open_path_browser) self.set_status_bar() vbar['command'] = text.yview vbar.pack(side=RIGHT, fill=Y) text['yscrollcommand'] = vbar.set fontWeight = 'normal' if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'): fontWeight = 'bold' text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'), idleConf.GetOption('main', 'EditorWindow', 'font-size'), fontWeight)) text_frame.pack(side=LEFT, fill=BOTH, expand=1) text.pack(side=TOP, fill=BOTH, expand=1) text.focus_set() usespaces = idleConf.GetOption('main', 'Indent', 'use-spaces', type='bool') self.usetabs = not usespaces self.tabwidth = 8 self.indentwidth = self.tabwidth self.set_notabs_indentwidth() self.context_use_ps1 = False self.num_context_lines = (50, 500, 5000000) self.per = per = self.Percolator(text) self.undo = undo = self.UndoDelegator() per.insertfilter(undo) text.undo_block_start = undo.undo_block_start text.undo_block_stop = undo.undo_block_stop undo.set_saved_change_hook(self.saved_change_hook) self.io = io = self.IOBinding(self) io.set_filename_change_hook(self.filename_change_hook) self.recent_files_menu = Menu(self.menubar) self.menudict['file'].insert_cascade(3, label='Recent Files', underline=0, menu=self.recent_files_menu) self.update_recent_files_list() self.color = None if filename: if os.path.exists(filename) and not os.path.isdir(filename): io.loadfile(filename) else: io.set_filename(filename) self.ResetColorizer() self.saved_change_hook() self.set_indentation_params(self.ispythonsource(filename)) self.load_extensions() menu = self.menudict.get('windows') if menu: end = menu.index('end') if end is None: end = -1 if end >= 0: menu.add_separator() end = end + 1 self.wmenu_end = end WindowList.register_callback(self.postwindowsmenu) self.askyesno = tkMessageBox.askyesno self.askinteger = tkSimpleDialog.askinteger self.showerror = tkMessageBox.showerror return
class ParenMatch: """Highlight matching parentheses There are three supported style of paren matching, based loosely on the Emacs options. The style is select based on the HILITE_STYLE attribute; it can be changed used the set_style method. The supported styles are: default -- When a right paren is typed, highlight the matching left paren for 1/2 sec. expression -- When a right paren is typed, highlight the entire expression from the left paren to the right paren. TODO: - extend IDLE with configuration dialog to change options - implement rest of Emacs highlight styles (see below) - print mismatch warning in IDLE status window Note: In Emacs, there are several styles of highlight where the matching paren is highlighted whenever the cursor is immediately to the right of a right paren. I don't know how to do that in Tk, so I haven't bothered. """ menudefs = [('edit', [('Show surrounding parens', '<<flash-paren>>')])] STYLE = idleConf.GetOption('extensions', 'ParenMatch', 'style', default='expression') FLASH_DELAY = idleConf.GetOption('extensions', 'ParenMatch', 'flash-delay', type='int', default=500) HILITE_CONFIG = idleConf.GetHighlight(idleConf.CurrentTheme(), 'hilite') BELL = idleConf.GetOption('extensions', 'ParenMatch', 'bell', type='bool', default=1) RESTORE_VIRTUAL_EVENT_NAME = '<<parenmatch-check-restore>>' RESTORE_SEQUENCES = ('<KeyPress>', '<ButtonPress>', '<Key-Return>', '<Key-BackSpace>') def __init__(self, editwin): self.editwin = editwin self.text = editwin.text editwin.text.bind(self.RESTORE_VIRTUAL_EVENT_NAME, self.restore_event) self.counter = 0 self.is_restore_active = 0 self.set_style(self.STYLE) def activate_restore(self): if not self.is_restore_active: for seq in self.RESTORE_SEQUENCES: self.text.event_add(self.RESTORE_VIRTUAL_EVENT_NAME, seq) self.is_restore_active = True def deactivate_restore(self): if self.is_restore_active: for seq in self.RESTORE_SEQUENCES: self.text.event_delete(self.RESTORE_VIRTUAL_EVENT_NAME, seq) self.is_restore_active = False def set_style(self, style): self.STYLE = style if style == 'default': self.create_tag = self.create_tag_default self.set_timeout = self.set_timeout_last elif style == 'expression': self.create_tag = self.create_tag_expression self.set_timeout = self.set_timeout_none def flash_paren_event(self, event): indices = HyperParser(self.editwin, 'insert').get_surrounding_brackets() if indices is None: self.warn_mismatched() return else: self.activate_restore() self.create_tag(indices) self.set_timeout_last() return def paren_closed_event(self, event): closer = self.text.get('insert-1c') if closer not in _openers: return else: hp = HyperParser(self.editwin, 'insert-1c') if not hp.is_in_code(): return indices = hp.get_surrounding_brackets(_openers[closer], True) if indices is None: self.warn_mismatched() return self.activate_restore() self.create_tag(indices) self.set_timeout() return def restore_event(self, event=None): self.text.tag_delete('paren') self.deactivate_restore() self.counter += 1 def handle_restore_timer(self, timer_count): if timer_count == self.counter: self.restore_event() def warn_mismatched(self): if self.BELL: self.text.bell() def create_tag_default(self, indices): """Highlight the single paren that matches""" self.text.tag_add('paren', indices[0]) self.text.tag_config('paren', self.HILITE_CONFIG) def create_tag_expression(self, indices): """Highlight the entire expression""" if self.text.get(indices[1]) in (')', ']', '}'): rightindex = indices[1] + '+1c' else: rightindex = indices[1] self.text.tag_add('paren', indices[0], rightindex) self.text.tag_config('paren', self.HILITE_CONFIG) def set_timeout_none(self): """Highlight will remain until user input turns it off or the insert has moved""" self.counter += 1 def callme(callme, self=self, c=self.counter, index=self.text.index('insert')): if index != self.text.index('insert'): self.handle_restore_timer(c) else: self.editwin.text_frame.after(CHECK_DELAY, callme, callme) self.editwin.text_frame.after(CHECK_DELAY, callme, callme) def set_timeout_last(self): """The last highlight created will be removed after .5 sec""" self.counter += 1 self.editwin.text_frame.after( self.FLASH_DELAY, lambda self=self, c=self.counter: self.handle_restore_timer(c))
class ParenMatch: menudefs = [('edit', [('Show surrounding parens', '<<flash-paren>>')])] STYLE = idleConf.GetOption('extensions', 'ParenMatch', 'style', default='expression') FLASH_DELAY = idleConf.GetOption('extensions', 'ParenMatch', 'flash-delay', type='int', default=500) HILITE_CONFIG = idleConf.GetHighlight(idleConf.CurrentTheme(), 'hilite') BELL = idleConf.GetOption('extensions', 'ParenMatch', 'bell', type='bool', default=1) RESTORE_VIRTUAL_EVENT_NAME = '<<parenmatch-check-restore>>' RESTORE_SEQUENCES = ('<KeyPress>', '<ButtonPress>', '<Key-Return>', '<Key-BackSpace>') def __init__(self, editwin): self.editwin = editwin self.text = editwin.text editwin.text.bind(self.RESTORE_VIRTUAL_EVENT_NAME, self.restore_event) self.counter = 0 self.is_restore_active = 0 self.set_style(self.STYLE) def activate_restore(self): if not self.is_restore_active: for seq in self.RESTORE_SEQUENCES: self.text.event_add(self.RESTORE_VIRTUAL_EVENT_NAME, seq) self.is_restore_active = True def deactivate_restore(self): if self.is_restore_active: for seq in self.RESTORE_SEQUENCES: self.text.event_delete(self.RESTORE_VIRTUAL_EVENT_NAME, seq) self.is_restore_active = False def set_style(self, style): self.STYLE = style if style == 'default': self.create_tag = self.create_tag_default self.set_timeout = self.set_timeout_last elif style == 'expression': self.create_tag = self.create_tag_expression self.set_timeout = self.set_timeout_none def flash_paren_event(self, event): indices = HyperParser(self.editwin, 'insert').get_surrounding_brackets() if indices is None: self.warn_mismatched() return else: self.activate_restore() self.create_tag(indices) self.set_timeout_last() return def paren_closed_event(self, event): closer = self.text.get('insert-1c') if closer not in _openers: return else: hp = HyperParser(self.editwin, 'insert-1c') if not hp.is_in_code(): return indices = hp.get_surrounding_brackets(_openers[closer], True) if indices is None: self.warn_mismatched() return self.activate_restore() self.create_tag(indices) self.set_timeout() return def restore_event(self, event=None): self.text.tag_delete('paren') self.deactivate_restore() self.counter += 1 def handle_restore_timer(self, timer_count): if timer_count == self.counter: self.restore_event() def warn_mismatched(self): if self.BELL: self.text.bell() def create_tag_default(self, indices): self.text.tag_add('paren', indices[0]) self.text.tag_config('paren', self.HILITE_CONFIG) def create_tag_expression(self, indices): if self.text.get(indices[1]) in (')', ']', '}'): rightindex = indices[1] + '+1c' else: rightindex = indices[1] self.text.tag_add('paren', indices[0], rightindex) self.text.tag_config('paren', self.HILITE_CONFIG) def set_timeout_none(self): self.counter += 1 def callme(callme, self=self, c=self.counter, index=self.text.index('insert')): if index != self.text.index('insert'): self.handle_restore_timer(c) else: self.editwin.text_frame.after(CHECK_DELAY, callme, callme) self.editwin.text_frame.after(CHECK_DELAY, callme, callme) def set_timeout_last(self): self.counter += 1 self.editwin.text_frame.after( self.FLASH_DELAY, lambda self=self, c=self.counter: self.handle_restore_timer(c))
def LoadTagDefs(self): theme = idleConf.CurrentTheme() font = idleConf.GetOption('main', 'EditorWindow', 'font') self.tagdefs = { "COMMENT": idleConf.GetHighlight(theme, "comment"), "KEYWORD": idleConf.GetHighlight(theme, "keyword"), "BUILTIN": idleConf.GetHighlight(theme, "builtin"), "STRING": idleConf.GetHighlight(theme, "string"), "DEFINITION": idleConf.GetHighlight(theme, "definition"), "SYNC": { 'background': None, 'foreground': None }, "TODO": { 'background': None, 'foreground': None }, "ERROR": idleConf.GetHighlight(theme, "error"), # The following is used by ReplaceDialog: "hit": idleConf.GetHighlight(theme, "hit"), } if DEBUG: print 'tagdefs', self.tagdefs try: lang = getattr(__import__('languages' + self.ext), self.ext[1:]) if hasattr(lang, 'append_tags'): for key, value in lang.append_tags.items(): self.tagdefs[key] = value except (ImportError, AttributeError): pass def _style(string): list_ = [] for c in string: if c == 'b': list_.append('bold') elif c == 'i': list_.append('italic') elif c == 'u': list_.append('underline') elif c == 's': list_.append('overstrike') return (font, 10, ' '.join(list_)) try: alttag = getattr(__import__('languages.' + theme), theme) if hasattr(alttag, 'append_tags'): for key, value in alttag.append_tags.items(): if 'font' in value: if isinstance(value['font'], str): value['font'] = _style(value['font']) else: value['font'] = (font, 10, '') self.tagdefs[key] = value for xtag, atag in ALTERNATE_TAGS.items(): if xtag not in self.tagdefs: if atag is None: self.tagdefs[xtag] = { 'foreground': None, 'background': None } else: self.tagdefs[xtag] = dict(self.tagdefs[atag]) if hasattr(alttag, 'read_twice'): self.read_twice = alttag.read_twice except (ImportError, AttributeError) as e: pass