diff --git a/src/rp/pager.py b/src/rp/pager.py new file mode 100644 index 0000000..3cd1142 --- /dev/null +++ b/src/rp/pager.py @@ -0,0 +1,40 @@ +"""Custom pager with mouse scroll support.""" + +from __future__ import annotations + +import shutil +import subprocess + +from rich.pager import Pager, SystemPager + + +def _is_mouse_capable_less() -> bool: + less = shutil.which("less") + if less is None: + return False + try: + result = subprocess.run( + [less, "--version"], capture_output=True, text=True, timeout=5 + ) + version_str = result.stdout or result.stderr or "" + return "GNU" in version_str or "less" in version_str.lower() + except (subprocess.TimeoutExpired, OSError): + return False + + +class MousePager(Pager): + """Pager that prefers ``less --mouse`` and falls back to the system pager.""" + + def show(self, content: str) -> None: + if _is_mouse_capable_less(): + try: + subprocess.run( + ["less", "-R", "--mouse"], + input=content, + text=True, + check=True, + ) + return + except (subprocess.CalledProcessError, FileNotFoundError): + pass + SystemPager().show(content) diff --git a/src/rp/render.py b/src/rp/render.py index 09e9aa8..aa4a83d 100644 --- a/src/rp/render.py +++ b/src/rp/render.py @@ -9,6 +9,8 @@ from rich.json import JSON as RichJSON from rich.markdown import Markdown from rich.syntax import Syntax +from rp.pager import MousePager + @dataclass class RenderOptions: @@ -54,7 +56,7 @@ def render( ) if use_pager: - with console.pager(styles=True): + with console.pager(pager=MousePager(), styles=True): console.print(renderable) else: console.print(renderable)