Skip to content

Commit 5126f4b

Browse files
committed
pager
1 parent 56f5cde commit 5126f4b

5 files changed

Lines changed: 77 additions & 34 deletions

File tree

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ rich "Hello [b]World[b]!" --rule --rule-style "red" --rule-char "="
9696

9797
![syntax1](https://raw.githubusercontent.com/Textualize/rich-cli/main/imgs/rules1.png)
9898

99+
## Pager
100+
101+
Add `--pager` to display the content with a built in pager application.
102+
103+
Scroll the pager with cursor keys, page up/down, home, end. Alternatively use the scrollbar which will be visible to the right of the terminal.
104+
99105
## Network
100106

101107
The `rich` command can read files from the internet you give it a URL starting with `http://` or `https://`.

poetry.lock

Lines changed: 24 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[tool.poetry]
22
name = "rich-cli"
33
homepage = "https://github.com/Textualize/rich-cli"
4-
version = "1.2.2"
4+
version = "1.3.0"
55
description = "Command Line Interface to Rich"
66
authors = ["Will McGugan <willmcgugan@gmail.com>"]
77
license = "MIT"
@@ -22,10 +22,11 @@ classifiers = [
2222

2323

2424
[tool.poetry.dependencies]
25-
python = "^3.6.2"
25+
python = "^3.7"
2626
rich = "^11.0.0"
2727
click = "^8.0.0"
2828
requests = "^2.0.0"
29+
textual = "^0.1.15"
2930

3031
[tool.poetry.dev-dependencies]
3132
black = "21.12b0"

src/rich_cli/__main__.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from typing import TYPE_CHECKING, List, NoReturn, Optional, Tuple
33

44
import click
5-
from pygments.lexers.special import TextLexer
65
from pygments.util import ClassNotFound
76
from rich.console import Console, RenderableType
87
from rich.markup import escape
@@ -37,7 +36,7 @@
3736
"toml": "toml",
3837
}
3938

40-
VERSION = "1.2.2"
39+
VERSION = "1.3.0"
4140

4241

4342
def on_error(message: str, error: Optional[Exception] = None, code=-1) -> NoReturn:
@@ -98,10 +97,11 @@ def read_resource(path: str, lexer: Optional[str]) -> Tuple[str, Optional[str]]:
9897
if not lexer:
9998
from pygments.lexers import guess_lexer_for_filename
10099

101-
lexer = guess_lexer_for_filename(path, text).name
100+
try:
101+
lexer = guess_lexer_for_filename(path, text).name
102+
except ClassNotFound:
103+
return (text, "text")
102104
return (text, lexer)
103-
except ClassNotFound:
104-
return (text, TextLexer())
105105
except Exception as error:
106106
on_error(f"unable to read {escape(path)}", error)
107107

@@ -363,6 +363,7 @@ class OptionHighlighter(RegexHighlighter):
363363
default="",
364364
help="Write HTML to [b]PATH[/b].",
365365
)
366+
@click.option("--pager", is_flag=True, help="Display in an interactive pager.")
366367
def main(
367368
resource: str,
368369
print: bool = False,
@@ -399,6 +400,7 @@ def main(
399400
hyperlinks: bool = False,
400401
force_terminal: bool = False,
401402
export_html: Optional[str] = None,
403+
pager: bool = False,
402404
):
403405
"""Rich toolbox for console output."""
404406
console = Console(
@@ -548,12 +550,18 @@ def main(
548550
elif center:
549551
justify = "center"
550552

551-
console.print(
552-
renderable,
553-
width=None if max_width <= 0 else max_width,
554-
justify=justify,
555-
soft_wrap=soft,
556-
)
553+
if pager:
554+
from .pager import PagerApp
555+
556+
PagerApp.run(title=resource, content=renderable)
557+
558+
else:
559+
console.print(
560+
renderable,
561+
width=None if max_width <= 0 else max_width,
562+
justify=justify,
563+
soft_wrap=soft,
564+
)
557565

558566
if export_html:
559567
try:

src/rich_cli/pager.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from textual import events
2+
from textual.app import App
3+
from textual.widgets import ScrollView
4+
5+
6+
class PagerApp(App):
7+
"""App to scroll renderable"""
8+
9+
def __init__(
10+
self,
11+
*args,
12+
content=None,
13+
**kwargs,
14+
) -> None:
15+
self.content = content
16+
super().__init__(*args, **kwargs)
17+
18+
async def on_load(self, event: events.Load) -> None:
19+
await self.bind("q", "quit", "Quit")
20+
21+
async def on_mount(self, event: events.Mount) -> None:
22+
self.body = body = ScrollView()
23+
await self.view.dock(body)
24+
await body.focus()
25+
await body.update(self.content)

0 commit comments

Comments
 (0)