mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
updated code browser to use new code highlight
This commit is contained in:
@@ -9,12 +9,13 @@ Run with:
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from rich.syntax import Syntax
|
|
||||||
from rich.traceback import Traceback
|
from rich.traceback import Traceback
|
||||||
|
|
||||||
from textual.app import App, ComposeResult
|
from textual.app import App, ComposeResult
|
||||||
from textual.containers import Container, VerticalScroll
|
from textual.containers import Container, VerticalScroll
|
||||||
|
from textual.highlight import highlight
|
||||||
from textual.reactive import reactive, var
|
from textual.reactive import reactive, var
|
||||||
from textual.widgets import DirectoryTree, Footer, Header, Static
|
from textual.widgets import DirectoryTree, Footer, Header, Static
|
||||||
|
|
||||||
@@ -68,13 +69,8 @@ class CodeBrowser(App):
|
|||||||
code_view.update("")
|
code_view.update("")
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
syntax = Syntax.from_path(
|
code = Path(path).read_text(encoding="utf-8")
|
||||||
path,
|
syntax = highlight(code, path=path)
|
||||||
line_numbers=True,
|
|
||||||
word_wrap=False,
|
|
||||||
indent_guides=True,
|
|
||||||
theme="github-dark" if self.current_theme.dark else "github-light",
|
|
||||||
)
|
|
||||||
except Exception:
|
except Exception:
|
||||||
code_view.update(Traceback(theme="github-dark", width=None))
|
code_view.update(Traceback(theme="github-dark", width=None))
|
||||||
self.sub_title = "ERROR"
|
self.sub_title = "ERROR"
|
||||||
|
|||||||
@@ -26,4 +26,6 @@ CodeBrowser.-show-tree #tree-view {
|
|||||||
}
|
}
|
||||||
#code {
|
#code {
|
||||||
width: auto;
|
width: auto;
|
||||||
|
padding: 0 1;
|
||||||
|
background: $surface;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from pygments.lexers import get_lexer_by_name
|
import os
|
||||||
|
|
||||||
|
from pygments.lexer import Lexer
|
||||||
|
from pygments.lexers import get_lexer_by_name, guess_lexer_for_filename
|
||||||
from pygments.token import Token
|
from pygments.token import Token
|
||||||
from pygments.util import ClassNotFound
|
from pygments.util import ClassNotFound
|
||||||
|
|
||||||
@@ -16,6 +19,8 @@ class HighlightTheme:
|
|||||||
Token.Comment: "$text 60%",
|
Token.Comment: "$text 60%",
|
||||||
Token.Error: "$error on $error-muted",
|
Token.Error: "$error on $error-muted",
|
||||||
Token.Generic.Error: "$error on $error-muted",
|
Token.Generic.Error: "$error on $error-muted",
|
||||||
|
Token.Generic.Heading: "$primary underline",
|
||||||
|
Token.Generic.Subheading: "$primary",
|
||||||
Token.Keyword: "$accent",
|
Token.Keyword: "$accent",
|
||||||
Token.Keyword.Constant: "bold $success 80%",
|
Token.Keyword.Constant: "bold $success 80%",
|
||||||
Token.Keyword.Namespace: "$error",
|
Token.Keyword.Namespace: "$error",
|
||||||
@@ -45,8 +50,9 @@ class HighlightTheme:
|
|||||||
|
|
||||||
def highlight(
|
def highlight(
|
||||||
code: str,
|
code: str,
|
||||||
language: str = "text",
|
|
||||||
*,
|
*,
|
||||||
|
language: str | None = None,
|
||||||
|
path: str | None = None,
|
||||||
theme: type[HighlightTheme] = HighlightTheme,
|
theme: type[HighlightTheme] = HighlightTheme,
|
||||||
tab_size: int = 8,
|
tab_size: int = 8,
|
||||||
) -> Content:
|
) -> Content:
|
||||||
@@ -61,6 +67,40 @@ def highlight(
|
|||||||
Returns:
|
Returns:
|
||||||
A Content instance which may be used in a widget.
|
A Content instance which may be used in a widget.
|
||||||
"""
|
"""
|
||||||
|
if language is None and path is None:
|
||||||
|
raise RuntimeError("One of 'language' or 'path' must be supplied.")
|
||||||
|
|
||||||
|
if language is None and path is not None:
|
||||||
|
if os.path.splitext(path)[-1] == ".tcss":
|
||||||
|
language = "scss"
|
||||||
|
|
||||||
|
if language is None and path is not None:
|
||||||
|
lexer: Lexer | None = None
|
||||||
|
lexer_name = "default"
|
||||||
|
if code:
|
||||||
|
try:
|
||||||
|
lexer = guess_lexer_for_filename(path, code)
|
||||||
|
except ClassNotFound:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not lexer:
|
||||||
|
try:
|
||||||
|
_, ext = os.path.splitext(path)
|
||||||
|
if ext:
|
||||||
|
extension = ext.lstrip(".").lower()
|
||||||
|
lexer = get_lexer_by_name(extension)
|
||||||
|
except ClassNotFound:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if lexer:
|
||||||
|
if lexer.aliases:
|
||||||
|
lexer_name = lexer.aliases[0]
|
||||||
|
else:
|
||||||
|
lexer_name = lexer.name
|
||||||
|
|
||||||
|
language = lexer_name
|
||||||
|
|
||||||
|
assert language is not None
|
||||||
code = "\n".join(code.splitlines())
|
code = "\n".join(code.splitlines())
|
||||||
try:
|
try:
|
||||||
lexer = get_lexer_by_name(
|
lexer = get_lexer_by_name(
|
||||||
|
|||||||
Reference in New Issue
Block a user