1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
"""Scrollable help page backed by a bundled markdown file."""
from __future__ import annotations
from importlib.resources import files
from unicurses import ( # type: ignore[import-untyped]
KEY_DOWN,
KEY_RESIZE,
KEY_UP,
)
from pygittools.tui.draw import draw_line
from pygittools.tui.types import PageAction, PageContext, PageResult
def _load_help_lines() -> list[str]:
text = files("pygittools").joinpath("help.md").read_text(encoding="utf-8")
return text.splitlines()
class HelpPage:
title = "help"
def __init__(self) -> None:
self._lines = _load_help_lines()
self._offset = 0
def on_enter(self, ctx: PageContext) -> None:
del ctx
def status_text(self) -> str:
total = len(self._lines)
if total == 0:
return "Help"
visible_end = min(self._offset + 1, total)
return f"Help {visible_end}/{total} — J/K or arrows to scroll, Q or Esc to go back"
def draw(self, stdscr: int, height: int, width: int) -> None:
del stdscr
if height <= 0:
return
max_offset = max(0, len(self._lines) - height)
self._offset = min(self._offset, max_offset)
for row in range(height):
line_index = self._offset + row
if line_index >= len(self._lines):
break
draw_line(row, 0, self._lines[line_index], width)
def handle_key(self, key: int) -> PageResult:
if key in (ord("q"), ord("Q"), 27):
return PageResult(action=PageAction.POP)
if key == KEY_RESIZE:
return PageResult()
if key in (KEY_UP, ord("k"), ord("K")):
self._offset = max(0, self._offset - 1)
return PageResult()
if key in (KEY_DOWN, ord("j"), ord("J")):
self._offset += 1
return PageResult()
return PageResult()
def help_page() -> HelpPage:
return HelpPage()