Improve documentation and modernize type hints

This commit is contained in:
2026-04-01 21:06:34 -07:00
parent 5935140620
commit 32a8a1d4ad
6 changed files with 82 additions and 16 deletions

View File

@@ -166,6 +166,7 @@ rich-viewer/
├── cli.py # Typer CLI entry point ├── cli.py # Typer CLI entry point
├── detect.py # File type detection ├── detect.py # File type detection
├── render.py # Rendering logic ├── render.py # Rendering logic
├── pager.py # Pager integration
└── py.typed # PEP 561 marker └── py.typed # PEP 561 marker
``` ```

View File

@@ -1,4 +1,6 @@
"""rp — Rich print files beautifully in your terminal.""" """Project metadata for rp."""
from __future__ import annotations
__version__ = "0.2.0" __version__ = "0.2.0"
__author__ = "Yunxiao Xu" __author__ = "Yunxiao Xu"

View File

@@ -1,10 +1,10 @@
"""CLI entry point for rp — rich print files beautifully.""" """CLI entry point for rp."""
from __future__ import annotations from __future__ import annotations
import sys import sys
from pathlib import Path from pathlib import Path
from typing import Annotated, Optional from typing import Annotated
import typer import typer
from rich.console import Console from rich.console import Console
@@ -22,6 +22,11 @@ app = typer.Typer(
def version_callback(value: bool) -> None: def version_callback(value: bool) -> None:
"""Print version information and exit.
Args:
value: Flag value from typer callback.
"""
if value: if value:
console = Console() console = Console()
console.print(f"Rich Print (rp) {__version__}") console.print(f"Rich Print (rp) {__version__}")
@@ -33,11 +38,11 @@ def version_callback(value: bool) -> None:
@app.command() @app.command()
def main( def main(
file: Annotated[ file: Annotated[
Optional[Path], Path | None,
typer.Argument(help="File to rich-print. Use '-' or omit to read from stdin."), typer.Argument(help="File to rich-print. Use '-' or omit to read from stdin."),
] = None, ] = None,
file_type: Annotated[ file_type: Annotated[
Optional[str], str | None,
typer.Option( typer.Option(
"--type", "-t", help="Force file type (e.g. json, python, markdown)." "--type", "-t", help="Force file type (e.g. json, python, markdown)."
), ),
@@ -47,21 +52,21 @@ def main(
typer.Option("--theme", help="Pygments color theme."), typer.Option("--theme", help="Pygments color theme."),
] = "monokai", ] = "monokai",
line_numbers: Annotated[ line_numbers: Annotated[
Optional[bool], bool | None,
typer.Option( typer.Option(
"--line-numbers/--no-line-numbers", "--line-numbers/--no-line-numbers",
help="Show line numbers. Default: auto.", help="Show line numbers. Default: auto.",
), ),
] = None, ] = None,
pager: Annotated[ pager: Annotated[
Optional[bool], bool | None,
typer.Option( typer.Option(
"--pager/--no-pager", "--pager/--no-pager",
help="Use pager for output. Default: auto-detect.", help="Use pager for output. Default: auto-detect.",
), ),
] = None, ] = None,
version: Annotated[ version: Annotated[
Optional[bool], bool | None,
typer.Option( typer.Option(
"--version", "--version",
"-v", "-v",
@@ -71,7 +76,16 @@ def main(
), ),
] = None, ] = None,
) -> None: ) -> None:
"""Rich print files beautifully in your terminal.""" """Render a file or stdin input in the terminal.
Args:
file: File to rich-print. Use '-' or omit to read from stdin.
file_type: Force file type (e.g. json, python, markdown).
theme: Pygments color theme.
line_numbers: Show line numbers. Default: auto.
pager: Use pager for output. Default: auto-detect.
version: Show version and exit.
"""
console = Console() console = Console()
if file is None or str(file) == "-": if file is None or str(file) == "-":

View File

@@ -60,6 +60,23 @@ def detect_type(
content: str | None = None, content: str | None = None,
explicit_type: str | None = None, explicit_type: str | None = None,
) -> str: ) -> str:
"""Detect the file type for syntax highlighting.
Detection priority:
1. Explicit type if provided
2. Filename-based mapping (for example, Dockerfile)
3. Extension-based mapping
4. JSON if content starts with '{' or '[' and parses successfully
5. Fallback to 'text'
Args:
path: File path for filename and extension detection.
content: File content for JSON detection.
explicit_type: Override auto-detection with explicit type.
Returns:
Pygments lexer name for the detected file type.
"""
if explicit_type is not None: if explicit_type is not None:
return explicit_type return explicit_type

View File

@@ -9,6 +9,11 @@ from rich.pager import Pager, SystemPager
def _is_mouse_capable_less() -> bool: def _is_mouse_capable_less() -> bool:
"""Check whether the system has a usable ``less`` executable.
Returns:
True if ``less`` is installed and responds to ``--version``.
"""
less = shutil.which("less") less = shutil.which("less")
if less is None: if less is None:
return False return False
@@ -26,6 +31,14 @@ class MousePager(Pager):
"""Pager that prefers ``less --mouse`` and falls back to the system pager.""" """Pager that prefers ``less --mouse`` and falls back to the system pager."""
def show(self, content: str) -> None: def show(self, content: str) -> None:
"""Display content with mouse-scroll support when available.
Uses ``less --mouse`` when available; otherwise falls back to the system
pager.
Args:
content: Content to display in pager.
"""
if _is_mouse_capable_less(): if _is_mouse_capable_less():
try: try:
subprocess.run( subprocess.run(

View File

@@ -14,18 +14,37 @@ from rp.pager import MousePager
@dataclass @dataclass
class RenderOptions: class RenderOptions:
"""Rendering options for file display.
Attributes:
theme: Pygments color theme name.
line_numbers: Show line numbers. ``None`` enables them for code only.
pager: Use pager for output. ``None`` auto-detects terminal output.
"""
theme: str = "monokai" theme: str = "monokai"
line_numbers: bool | None = None line_numbers: bool | None = None
pager: bool | None = None pager: bool | None = None
_MARKDOWN_TYPES = {"markdown", "md"} _MARKDOWN_TYPES: set[str] = {"markdown", "md"}
_JSON_TYPES = {"json"} _JSON_TYPES: set[str] = {"json"}
def render( def render(
content: str, file_type: str, console: Console, options: RenderOptions content: str, file_type: str, console: Console, options: RenderOptions
) -> None: ) -> None:
"""Render content to the console with syntax highlighting.
Renders Markdown with Rich Markdown, JSON with Rich JSON with a Syntax
fallback, and all other types with Pygments Syntax highlighting.
Args:
content: File content to render.
file_type: Pygments lexer name.
console: Rich console to render to.
options: Rendering options (theme, line numbers, pager).
"""
line_numbers = options.line_numbers line_numbers = options.line_numbers
if line_numbers is None: if line_numbers is None:
line_numbers = file_type not in _MARKDOWN_TYPES and file_type not in _JSON_TYPES line_numbers = file_type not in _MARKDOWN_TYPES and file_type not in _JSON_TYPES