Skip to content

Commit 51ae7c1

Browse files
authored
Merge pull request #6167 from Textualize/guess-lexer
better lexer guessing
2 parents de66343 + a0f0ec5 commit 51ae7c1

File tree

3 files changed

+23
-11
lines changed

3 files changed

+23
-11
lines changed

src/textual/highlight.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class HighlightTheme:
5252
}
5353

5454

55-
def guess_language(code: str, path: str) -> str:
55+
def guess_language(code: str, path: str | None) -> str:
5656
"""Guess the language based on the code and path.
5757
The result may be used in the [highlight][textual.highlight.highlight] function.
5858
@@ -64,19 +64,28 @@ def guess_language(code: str, path: str) -> str:
6464
The language, suitable for use with Pygments.
6565
"""
6666

67-
if path is not None and os.path.splitext(path)[-1] == ".tcss":
67+
if path and os.path.splitext(path)[-1] == ".tcss":
6868
# A special case for TCSS files which aren't known outside of Textual
6969
return "scss"
7070

7171
lexer: Lexer | None = None
7272
lexer_name = "default"
7373
if code:
74-
try:
75-
lexer = guess_lexer_for_filename(path, code)
76-
except ClassNotFound:
77-
pass
74+
if path:
75+
try:
76+
lexer = guess_lexer_for_filename(path, code)
77+
except ClassNotFound:
78+
pass
79+
80+
if lexer is None:
81+
from pygments.lexers import guess_lexer
82+
83+
try:
84+
lexer = guess_lexer(code)
85+
except Exception:
86+
pass
7887

79-
if not lexer:
88+
if not lexer and path:
8089
try:
8190
_, ext = os.path.splitext(path)
8291
if ext:
@@ -113,9 +122,7 @@ def highlight(
113122
Returns:
114123
A Content instance which may be used in a widget.
115124
"""
116-
if language is None:
117-
if path is None:
118-
raise RuntimeError("One of 'language' or 'path' must be supplied.")
125+
if not language:
119126
language = guess_language(code, path)
120127

121128
assert language is not None

src/textual/widgets/_markdown.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,12 +870,13 @@ def __init__(self, markdown: Markdown, token: Token, code: str) -> None:
870870
self.lexer = token.info
871871
self._highlighted_code = self.highlight(self.code, self.lexer)
872872

873+
@property
873874
def allow_horizontal_scroll(self) -> bool:
874875
return True
875876

876877
@classmethod
877878
def highlight(cls, code: str, language: str) -> Content:
878-
return highlight(code, language=language)
879+
return highlight(code, language=language or None)
879880

880881
def _copy_context(self, block: MarkdownBlock) -> None:
881882
if isinstance(block, MarkdownFence):

tests/test_highlight.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ def test_highlight() -> None:
1919
@pytest.mark.parametrize(
2020
"code,path,language",
2121
[
22+
("", "", "default"),
23+
("# Don't matter", "foo.tcss", "scss"),
2224
("import this", "foo.py", "python"),
2325
("<xml>", "foo.xml", "xml"),
2426
("{}", "data.json", "json"),
27+
("#! python", "", "python"),
28+
("", "foo.py", "python"),
2529
],
2630
)
2731
def test_guess_language(code: str, path: str, language: str) -> None:

0 commit comments

Comments
 (0)