Henry Zhu
Henry Zhu

Reputation: 2618

Improve Pygments Syntax Highlighting Speed for Tkinter Text

I am using the pygments module for my text editor's syntax highlighting. Unfortunately it is very slow because it starts highlighting from the beginning every time a key is pressed. This delay is not significant when typing small programs, but when opening relatively large files and then editing them, the lag is CLEAR. I am trying to minimize this lag my starting the highlighting from the last word, but it I have trouble doing so. This is my highlight function. If you want any more information, I would be happy to add it on.

def highlight(self, argument):
    self.content = self.text.get("0.0", tk.END)

    if (self.previousContent != self.content):
        self.text.mark_set("range_start", "0.0")

        self.words = self.content.split(" ")
        self.lastWordLength = len(self.words[len(self.words) - 1])

        self.lastPos = self.text.index("end-1c")
        self.startRow = int(self.lastPos.split(".")[0])
        self.startCol = abs(int(self.lastPos.split(".")[1]) - self.lastWordLength)

        print(self.startRow, self.startCol) # Results in incorrect values

        data = self.text.get("0.0", tk.END)
        for token, content in lex(data, PythonLexer()):
            self.text.tag_configure("Token.Keyword", foreground="#CC7A00")
            self.text.tag_configure("Token.Keyword.Constant", foreground="#CC7A00")
            self.text.tag_configure("Token.Keyword.Declaration", foreground="#CC7A00")
            self.text.tag_configure("Token.Keyword.Namespace", foreground="#CC7A00")
            self.text.tag_configure("Token.Keyword.Pseudo", foreground="#CC7A00")
            self.text.tag_configure("Token.Keyword.Reserved", foreground="#CC7A00")
            self.text.tag_configure("Token.Keyword.Type", foreground="#CC7A00")

            self.text.tag_configure("Token.Name.Class", foreground="#003D99")
            self.text.tag_configure("Token.Name.Exception", foreground="#003D99")
            self.text.tag_configure("Token.Name.Function", foreground="#003D99")

            self.text.tag_configure("Token.Operator.Word", foreground="#CC7A00")

            self.text.tag_configure("Token.Comment", foreground="#B80000")

            self.text.tag_configure("Token.Literal.String", foreground="#248F24")

            self.text.mark_set("range_end", "range_start + %dc" % len(content))
            self.text.tag_add(str(token), "range_start", "range_end")
            self.text.mark_set("range_start", "range_end")

    self.previousContent = self.text.get("0.0", tk.END)

Upvotes: 2

Views: 1682

Answers (1)

Henry Zhu
Henry Zhu

Reputation: 2618

I solved the problem! Instead of going from the beginning to the end, I checked the line in which the user was typing, and only parsed the content within that line. This sped up the syntax highlighting a LOT.

def deafultHighlight(self, argument):
    self.content = self.text.get("1.0", tk.END)
    self.lines = self.content.split("\n")

    if (self.previousContent != self.content):
        self.text.mark_set("range_start", self.row + ".0")
        data = self.text.get(self.row + ".0", self.row + "." + str(len(self.lines[int(self.row) - 1])))

        for token, content in lex(data, PythonLexer()):
            self.text.mark_set("range_end", "range_start + %dc" % len(content))
            self.text.tag_add(str(token), "range_start", "range_end")
            self.text.mark_set("range_start", "range_end")

    self.previousContent = self.text.get("1.0", tk.END)

Upvotes: 3

Related Questions