Use of configure results in error
strangefreeworld opened this issue · 15 comments
When I do something like:
def open_file(filename): lexer = pygments.lexers.get_lexer_for_filename(filename) code_view.configure(lexer=lexer)
I get the following error:
File "/home/user/.cache/pypoetry/virtualenvs/qdnote-xQFX2N3W-py3.10/lib/python3.10/site-packages/chlorophyll/codeview.py", line 217, in configure
self._set_lexer(lexer)
File "/home/user/.cache/pypoetry/virtualenvs/qdnote-xQFX2N3W-py3.10/lib/python3.10/site-packages/chlorophyll/codeview.py", line 204, in _set_lexer
self.highlight_all()
File "/home/user/.cache/pypoetry/virtualenvs/qdnote-xQFX2N3W-py3.10/lib/python3.10/site-packages/chlorophyll/codeview.py", line 165, in highlight_all
for token, text in lex(lines, self._lexer()):
TypeError: 'PythonLexer' object is not callable
Have you tried using codeview. _set_lexer(lexer)
?
Sorry, the type annotation for lexer
is wrong. It expects a lexer class, not an actual instance.
Have you tried using
codeview. _set_lexer(lexer)
?
Btw, don't use _set_lexer
it's not a public method.
Yes I figured out it is looking for a class, not an instance. I can work around that; if possible, I would suggest you document that somewhere. Given how I am trying to use the class, it would be nice if there was an interface that could give me the class based on the file extension, something similar to pygments' get_lexer_for_filename
.
A suggestion to @Moosems (I apologize if this is harsh): if you had looked at the actual stack trace I had provided, you would see that _set_lexer is being called.
If I find a solution I like I may create a PR.
Can you provide a minimum reproducible example? I have. a program that utilizes chlorophyll and changes the lexer and have never encountered this issue.
Pass a lexer that you get from the results of https://pygments.org/docs/api/#pygments.lexers.get_lexer_for_filename. It passes an instantiated object rather than a class instance. If you do that, you get error that I mentioned earlier in my initial post (which by the way calls _set_lexer). I posted a simple code sample in my initial report, you should be able to create a minimum example from that (you just need a codeview instance).
Actually, in a sane world, that argument should accept a lexer instance.
I agree with this 100%.
Ah that's why. It requires the class itself. There are ways to get them from an instantiated object.
Obviously you could use type(lexer_instance)
, but you shouldn't have to.
Quick PR that runs lexer = type(lexer)
in set lexer?
No. Rather a quick PR that runs
self._lexer = lexer() if isclass(lexer) else lexer
And then remove then parens from the highlight methods from the line containing lex(..., self._lexer())
Also much faster to use one lexer than instantiate one for every highlight.