mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Merge pull request #6167 from Textualize/guess-lexer
better lexer guessing
This commit is contained in:
@@ -52,7 +52,7 @@ class HighlightTheme:
|
||||
}
|
||||
|
||||
|
||||
def guess_language(code: str, path: str) -> str:
|
||||
def guess_language(code: str, path: str | None) -> str:
|
||||
"""Guess the language based on the code and path.
|
||||
The result may be used in the [highlight][textual.highlight.highlight] function.
|
||||
|
||||
@@ -64,19 +64,28 @@ def guess_language(code: str, path: str) -> str:
|
||||
The language, suitable for use with Pygments.
|
||||
"""
|
||||
|
||||
if path is not None and os.path.splitext(path)[-1] == ".tcss":
|
||||
if path and os.path.splitext(path)[-1] == ".tcss":
|
||||
# A special case for TCSS files which aren't known outside of Textual
|
||||
return "scss"
|
||||
|
||||
lexer: Lexer | None = None
|
||||
lexer_name = "default"
|
||||
if code:
|
||||
try:
|
||||
lexer = guess_lexer_for_filename(path, code)
|
||||
except ClassNotFound:
|
||||
pass
|
||||
if path:
|
||||
try:
|
||||
lexer = guess_lexer_for_filename(path, code)
|
||||
except ClassNotFound:
|
||||
pass
|
||||
|
||||
if not lexer:
|
||||
if lexer is None:
|
||||
from pygments.lexers import guess_lexer
|
||||
|
||||
try:
|
||||
lexer = guess_lexer(code)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not lexer and path:
|
||||
try:
|
||||
_, ext = os.path.splitext(path)
|
||||
if ext:
|
||||
@@ -113,9 +122,7 @@ def highlight(
|
||||
Returns:
|
||||
A Content instance which may be used in a widget.
|
||||
"""
|
||||
if language is None:
|
||||
if path is None:
|
||||
raise RuntimeError("One of 'language' or 'path' must be supplied.")
|
||||
if not language:
|
||||
language = guess_language(code, path)
|
||||
|
||||
assert language is not None
|
||||
|
||||
@@ -870,12 +870,13 @@ class MarkdownFence(MarkdownBlock):
|
||||
self.lexer = token.info
|
||||
self._highlighted_code = self.highlight(self.code, self.lexer)
|
||||
|
||||
@property
|
||||
def allow_horizontal_scroll(self) -> bool:
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def highlight(cls, code: str, language: str) -> Content:
|
||||
return highlight(code, language=language)
|
||||
return highlight(code, language=language or None)
|
||||
|
||||
def _copy_context(self, block: MarkdownBlock) -> None:
|
||||
if isinstance(block, MarkdownFence):
|
||||
|
||||
@@ -19,9 +19,13 @@ def test_highlight() -> None:
|
||||
@pytest.mark.parametrize(
|
||||
"code,path,language",
|
||||
[
|
||||
("", "", "default"),
|
||||
("# Don't matter", "foo.tcss", "scss"),
|
||||
("import this", "foo.py", "python"),
|
||||
("<xml>", "foo.xml", "xml"),
|
||||
("{}", "data.json", "json"),
|
||||
("#! python", "", "python"),
|
||||
("", "foo.py", "python"),
|
||||
],
|
||||
)
|
||||
def test_guess_language(code: str, path: str, language: str) -> None:
|
||||
|
||||
Reference in New Issue
Block a user