From 0f471bee65ca6294db4896f91c8ad0094eb5d833 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Mon, 18 May 2026 11:39:28 +0200 Subject: [PATCH] =?UTF-8?q?paginaci=C3=B3=20amb=20fletxes=20esquerra/dreta?= =?UTF-8?q?=20i=20bump=20a=201.0.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +++++--- repoman.py | 50 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index b7ae864..bd1a2d8 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,9 @@ Una vez dentro de la lista: | Tecla | Acción | |---|---| -| `↑` / `↓` / `j` / `k` | mover cursor | -| `PgUp` / `PgDn` | saltar 10 | -| `g` / `G` | inicio / final | +| `↑` / `↓` / `j` / `k` | mover cursor una fila | +| `←` / `→` / `h` / `l` / `PgUp` / `PgDn` | pasar de página | +| `g` / `Home` · `G` / `End` | inicio / final de la lista | | `Space` | marcar / desmarcar el repo bajo el cursor | | `a` | marcar todos los que aún no estén en local | | `n` | desmarcar todo | @@ -28,6 +28,8 @@ Una vez dentro de la lista: | `r` | refrescar (vuelve a consultar al servidor) | | `q` / `Ctrl-C` | salir | +La lista se pagina automáticamente según la altura del terminal, así que con miles de repos sigue respondiendo al instante. + Iconos de estado: - `○ remoto` — está en el servidor, no clonado localmente diff --git a/repoman.py b/repoman.py index dfc9bb9..1e34378 100644 --- a/repoman.py +++ b/repoman.py @@ -23,7 +23,7 @@ from rich.live import Live from rich.table import Table from rich.text import Text -__version__ = "1.0.1" +__version__ = "1.0.2" console = Console() @@ -257,11 +257,27 @@ def build_entries(remote_repos: list[RemoteRepo], local_index: dict[str, Path]) # --- render ----------------------------------------------------------------- +def compute_page(cursor: int, total: int) -> tuple[int, int, int, int, int]: + """Calcula (start, end, page_idx, total_pages, page_size) per a la finestra visible.""" + h = max(10, console.size.height) + # Marges: 1 títol + 1 separador títol + 1 cabecera + 2 vores + 1 llegenda + 1 status + 1 buffer + page_size = max(5, h - 8) + if total == 0: + return 0, 0, 0, 1, page_size + page = cursor // page_size + start = page * page_size + end = min(start + page_size, total) + total_pages = (total + page_size - 1) // page_size + return start, end, page, total_pages, page_size + + def render(entries: list[RepoEntry], cursor: int, base: Path, owner: str, status_msg: str = "") -> Group: + start, end, page_idx, total_pages, _ = compute_page(cursor, len(entries)) + page_label = f" — pàgina {page_idx + 1}/{total_pages}" if total_pages > 1 else "" table = Table( show_header=True, header_style="bold magenta", - title=f"[bold]repoman[/bold] — [cyan]{owner}[/cyan] → [bold]{base}[/bold]", + title=f"[bold]repoman[/bold] — [cyan]{owner}[/cyan] → [bold]{base}[/bold][dim]{page_label}[/dim]", title_style="white", expand=True, ) @@ -270,7 +286,8 @@ def render(entries: list[RepoEntry], cursor: int, base: Path, owner: str, status table.add_column("Repo", style="bold", no_wrap=True, overflow="ellipsis") table.add_column("Descripción", no_wrap=True, overflow="ellipsis", ratio=1) - for i, e in enumerate(entries): + for i in range(start, end): + e = entries[i] # Cursor caret = Text("▶", style="bold yellow") if i == cursor else Text(" ") @@ -301,13 +318,14 @@ def render(entries: list[RepoEntry], cursor: int, base: Path, owner: str, status table.add_row(caret, state, name, desc) legend = Text.assemble( - ("↑/↓ j/k", "bold cyan"), " mover ", - ("Space", "bold cyan"), " marcar/desmarcar ", - ("a", "bold cyan"), " marcar todos remotos ", - ("n", "bold cyan"), " ninguno ", - ("Enter", "bold green"), " clonar marcados ", - ("r", "bold cyan"), " refrescar ", - ("q", "bold cyan"), " salir", + ("↑/↓ j/k", "bold cyan"), " moure ", + ("←/→ h/l", "bold cyan"), " pàgina ", + ("Space", "bold cyan"), " marcar ", + ("a", "bold cyan"), " tots ", + ("n", "bold cyan"), " cap ", + ("Enter", "bold green"), " clona ", + ("r", "bold cyan"), " refresca ", + ("q", "bold cyan"), " surt", style="dim", ) status = Text(status_msg, style="dim italic") if status_msg else Text("") @@ -390,10 +408,14 @@ def tui(entries: list[RepoEntry], base: Path, cfg: Config, owner: str) -> None: cursor = (cursor - 1) % len(entries) elif key in (readchar.key.DOWN, "j"): cursor = (cursor + 1) % len(entries) - elif key in (readchar.key.PAGE_UP,): - cursor = max(0, cursor - 10) - elif key in (readchar.key.PAGE_DOWN,): - cursor = min(len(entries) - 1, cursor + 10) + elif key in (readchar.key.LEFT, readchar.key.PAGE_UP, "h"): + _, _, page_idx, total_pages, page_size = compute_page(cursor, len(entries)) + new_page = (page_idx - 1) % total_pages + cursor = min(new_page * page_size, len(entries) - 1) + elif key in (readchar.key.RIGHT, readchar.key.PAGE_DOWN, "l"): + _, _, page_idx, total_pages, page_size = compute_page(cursor, len(entries)) + new_page = (page_idx + 1) % total_pages + cursor = min(new_page * page_size, len(entries) - 1) elif key in (readchar.key.HOME, "g"): cursor = 0 elif key in (readchar.key.END, "G"):