pyapp-kit / superqt

Missing widgets and components for Qt-python
https://pyapp-kit.github.io/superqt/
BSD 3-Clause "New" or "Revised" License
210 stars 37 forks source link

Fix KeyError in CodeSyntaxHighlight #258

Open hanjinliu opened 2 weeks ago

hanjinliu commented 2 weeks ago

I noticed that CodeSyntaxHighlight sometimes fails to highlight the texts. This PR fixes the KeyError just by replacing the __getitem__ with get. I encountered this bug when I tried to highlight my pre-commit-config.yaml file, so I cannot tell when this happens.

from superqt.utils import CodeSyntaxHighlight
from qtpy import QtWidgets as QtW

w = QtW.QPlainTextEdit()
highlight = CodeSyntaxHighlight(w.document(), "yaml", "default")
w.setPlainText("ci:\n  autoupdate_schedule: monthly")

Output:

KeyError                                  Traceback (most recent call last)
File ~\Desktop\code\python\superqt\src\superqt\utils\_code_syntax_highlight.py:73, in CodeSyntaxHighlight.highlightBlock(self, text)
     68 def highlightBlock(self, text):
     69     # dirty, dirty hack
     70     # The core problem is that pygemnts by default use string streams,
     71     # that will not handle QTextCharFormat, so we need use `data` property to
     72     # work around this.
---> 73     highlight(text, self.lexer, self.formatter)
     74     for i in range(len(text)):
     75         self.setFormat(i, 1, self.formatter.data[i])

File ~\mambaforge\envs\mt\Lib\site-packages\pygments\__init__.py:82, in highlight(code, lexer, formatter, outfile)
     77 def highlight(code, lexer, formatter, outfile=None):
     78     """
     79     This is the most high-level highlighting function. It combines `lex` and
     80     `format` in one function.
     81     """
---> 82     return format(lex(code, lexer), formatter, outfile)

File ~\mambaforge\envs\mt\Lib\site-packages\pygments\__init__.py:64, in format(tokens, formatter, outfile)
     62 if not outfile:
     63     realoutfile = getattr(formatter, 'encoding', None) and BytesIO() or StringIO()
---> 64     formatter.format(tokens, realoutfile)
     65     return realoutfile.getvalue()
     66 else:

File ~\Desktop\code\python\superqt\src\superqt\utils\_code_syntax_highlight.py:52, in QFormatter.format(self, tokensource, outfile)
     49 self.data = []
     51 for token, value in tokensource:
---> 52     self.data.extend([self._style[token]] * len(value))

KeyError: Token.Literal.Scalar.Plain
Czaki commented 2 weeks ago

For me, it looks like a bug in pigments.