paginació amb fletxes esquerra/dreta i bump a 1.0.2
This commit is contained in:
@@ -18,9 +18,9 @@ Una vez dentro de la lista:
|
|||||||
|
|
||||||
| Tecla | Acción |
|
| Tecla | Acción |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `↑` / `↓` / `j` / `k` | mover cursor |
|
| `↑` / `↓` / `j` / `k` | mover cursor una fila |
|
||||||
| `PgUp` / `PgDn` | saltar 10 |
|
| `←` / `→` / `h` / `l` / `PgUp` / `PgDn` | pasar de página |
|
||||||
| `g` / `G` | inicio / final |
|
| `g` / `Home` · `G` / `End` | inicio / final de la lista |
|
||||||
| `Space` | marcar / desmarcar el repo bajo el cursor |
|
| `Space` | marcar / desmarcar el repo bajo el cursor |
|
||||||
| `a` | marcar todos los que aún no estén en local |
|
| `a` | marcar todos los que aún no estén en local |
|
||||||
| `n` | desmarcar todo |
|
| `n` | desmarcar todo |
|
||||||
@@ -28,6 +28,8 @@ Una vez dentro de la lista:
|
|||||||
| `r` | refrescar (vuelve a consultar al servidor) |
|
| `r` | refrescar (vuelve a consultar al servidor) |
|
||||||
| `q` / `Ctrl-C` | salir |
|
| `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:
|
Iconos de estado:
|
||||||
|
|
||||||
- `○ remoto` — está en el servidor, no clonado localmente
|
- `○ remoto` — está en el servidor, no clonado localmente
|
||||||
|
|||||||
+36
-14
@@ -23,7 +23,7 @@ from rich.live import Live
|
|||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
from rich.text import Text
|
from rich.text import Text
|
||||||
|
|
||||||
__version__ = "1.0.1"
|
__version__ = "1.0.2"
|
||||||
|
|
||||||
console = Console()
|
console = Console()
|
||||||
|
|
||||||
@@ -257,11 +257,27 @@ def build_entries(remote_repos: list[RemoteRepo], local_index: dict[str, Path])
|
|||||||
|
|
||||||
# --- render -----------------------------------------------------------------
|
# --- 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:
|
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(
|
table = Table(
|
||||||
show_header=True,
|
show_header=True,
|
||||||
header_style="bold magenta",
|
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",
|
title_style="white",
|
||||||
expand=True,
|
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("Repo", style="bold", no_wrap=True, overflow="ellipsis")
|
||||||
table.add_column("Descripción", no_wrap=True, overflow="ellipsis", ratio=1)
|
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
|
# Cursor
|
||||||
caret = Text("▶", style="bold yellow") if i == cursor else Text(" ")
|
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)
|
table.add_row(caret, state, name, desc)
|
||||||
|
|
||||||
legend = Text.assemble(
|
legend = Text.assemble(
|
||||||
("↑/↓ j/k", "bold cyan"), " mover ",
|
("↑/↓ j/k", "bold cyan"), " moure ",
|
||||||
("Space", "bold cyan"), " marcar/desmarcar ",
|
("←/→ h/l", "bold cyan"), " pàgina ",
|
||||||
("a", "bold cyan"), " marcar todos remotos ",
|
("Space", "bold cyan"), " marcar ",
|
||||||
("n", "bold cyan"), " ninguno ",
|
("a", "bold cyan"), " tots ",
|
||||||
("Enter", "bold green"), " clonar marcados ",
|
("n", "bold cyan"), " cap ",
|
||||||
("r", "bold cyan"), " refrescar ",
|
("Enter", "bold green"), " clona ",
|
||||||
("q", "bold cyan"), " salir",
|
("r", "bold cyan"), " refresca ",
|
||||||
|
("q", "bold cyan"), " surt",
|
||||||
style="dim",
|
style="dim",
|
||||||
)
|
)
|
||||||
status = Text(status_msg, style="dim italic") if status_msg else Text("")
|
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)
|
cursor = (cursor - 1) % len(entries)
|
||||||
elif key in (readchar.key.DOWN, "j"):
|
elif key in (readchar.key.DOWN, "j"):
|
||||||
cursor = (cursor + 1) % len(entries)
|
cursor = (cursor + 1) % len(entries)
|
||||||
elif key in (readchar.key.PAGE_UP,):
|
elif key in (readchar.key.LEFT, readchar.key.PAGE_UP, "h"):
|
||||||
cursor = max(0, cursor - 10)
|
_, _, page_idx, total_pages, page_size = compute_page(cursor, len(entries))
|
||||||
elif key in (readchar.key.PAGE_DOWN,):
|
new_page = (page_idx - 1) % total_pages
|
||||||
cursor = min(len(entries) - 1, cursor + 10)
|
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"):
|
elif key in (readchar.key.HOME, "g"):
|
||||||
cursor = 0
|
cursor = 0
|
||||||
elif key in (readchar.key.END, "G"):
|
elif key in (readchar.key.END, "G"):
|
||||||
|
|||||||
Reference in New Issue
Block a user