'Idlelib tkinter syntax highlighting reset/update/removal

I am making an IDE that uses the idlelib percolator and colordelegator for syntax highlighting. In my special text widgets init function it runs:

import idlelib.colorizer as ic
import idlelib.percolator as ip
        self.cdg = ic.ColorDelegator()
        self.cdg.prog = re.compile(r"\b(?P<MYGROUP>tkinter)\b|" + ic.make_pat(), re.S)
        self.cdg.idprog = re.compile(r"\s+(\w+)", re.S)
        self.cdg.tagdefs["MYGROUP"] = {"foreground": tag_mygroup, "background": "#FFFFFF"}
        self.cdg.tagdefs["COMMENT"] = {"foreground": tag_comment, "background": "#FFFFFF"}
        self.cdg.tagdefs["KEYWORD"] = {"foreground": tag_keyword, "background": "#FFFFFF"}
        self.cdg.tagdefs["BUILTIN"] = {"foreground": tag_builtin, "background": "#FFFFFF"}
        self.cdg.tagdefs["STRING"] = {"foreground": tag_string, "background": "#FFFFFF"}
        self.cdg.tagdefs["DEFINITION"] = {"foreground": tag_definition, "background": "#FFFFFF"}
        self.cdg.tagdefs["CLASS"] = {"foreground": tag_class, "background": "#FFFFFF"}
        ip.Percolator(self.text).insertfilter(self.cdg)

This gives the text widget syntax highlighting as it is supposed to. I want to allow the user to change the color codes in the settings file and then reset/update or remove and then reapply the syntax highlighting with the new colors. The problem is that when I try to remove the highlighting with ip.Percolator(self.text).removefilter(self.cdg) it gives the error:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/tkinter/__init__.py", line 1892, in __call__
    return self.func(*args)
  File "/Users/joshyacky/Documents/PyApps/Working/JDE/JDE.py", line 129, in reset_syntax_colors
    main_text_box.reset_colors()
  File "/Users/joshyacky/Documents/PyApps/Working/JDE/custom_widgets.py", line 95, in reset_colors
    ip.Percolator(self.text).removefilter(self.cdg)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/idlelib/percolator.py", line 10, in __init__
    self.redir = WidgetRedirector(text)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/idlelib/redirector.py", line 44, in __init__
    tk.call("rename", w, self.orig)
_tkinter.TclError: can't rename to ".!ultra_text.!text_orig": command already exists

Any ideas on how to remove or update the syntax highlighting?



Solution 1:[1]

I suggest looking at how IDLE updates colors. When one clicks or selects [Ok] on the settings dialog, window.ResetColorizer is called on each editor window. That is defined in idlelib/editor.py at line 797. That in turn calls _rmcolorizer and _addcolorizer, defined on preceding lines. (The rest of the function is IDLE specific.) _rmcolorizer first calls the existing ColorDelegator().removecolors before per.removefilter. _addcolorizer thereafter creates a new ColorDelegator() before calling per.insertfilter. I don't know if all this is absolutely needed, but it works.

You are using nearly undocumented private code. It is not supported for 3rd party uses. However, I am open to suggestions, such as better doc for these modules, that would (also) aid their use for IDLE.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Terry Jan Reedy