refactor(hermes_cli): sessions_cmd_browse _clip helper, hoisted invariants
This commit is contained in:
@@ -28,6 +28,10 @@ def _label(s: dict) -> str:
|
||||
return (s.get("title") or "").strip() or (s.get("preview") or "").strip() or s["id"]
|
||||
|
||||
|
||||
def _clip(text: str, n: int) -> str:
|
||||
return text if len(text) <= n else text[: n - 3] + "..."
|
||||
|
||||
|
||||
def _msgs_str(s: dict) -> str:
|
||||
msgs = s.get("message_count")
|
||||
return str(msgs) if isinstance(msgs, int) else "-"
|
||||
@@ -72,8 +76,7 @@ class _CursesBrowser:
|
||||
self.filtered = list(sessions)
|
||||
|
||||
def _pair(self, n, fallback=0):
|
||||
c = self.curses
|
||||
return c.color_pair(n) if c.has_colors() else fallback
|
||||
return self.curses.color_pair(n) if self.curses.has_colors() else fallback
|
||||
|
||||
def _status_attr(self, status):
|
||||
pair = {"complete": 1, "interrupted": 2, "error": 5, "empty": 4}.get(status or "")
|
||||
@@ -113,16 +116,15 @@ class _CursesBrowser:
|
||||
self.scroll = self.cursor
|
||||
elif self.cursor >= self.scroll + visible_rows:
|
||||
self.scroll = self.cursor - visible_rows + 1
|
||||
tag_x = 3 + max(20, (max_x - 3) - _FIXED_COLS) + 2
|
||||
for draw_i, i in enumerate(range(self.scroll, min(len(filtered), self.scroll + visible_rows))):
|
||||
y = draw_i + 3
|
||||
if y >= max_y - 1:
|
||||
break
|
||||
s = filtered[i]
|
||||
selected = i == self.cursor
|
||||
s, selected = filtered[i], i == self.cursor
|
||||
row = (" → " if selected else " ") + _format_row(s, max_x - 3)
|
||||
try:
|
||||
stdscr.addnstr(y, 0, row, max_x - 1, c.A_BOLD | self._pair(1) if selected else c.A_NORMAL)
|
||||
tag_x = 3 + max(20, (max_x - 3) - _FIXED_COLS) + 2
|
||||
if not selected and tag_x + 5 < max_x - 1: # recolor the status tag in place
|
||||
status = s.get("_status")
|
||||
stdscr.addnstr(y, tag_x, f"{_session_status_tag(status):<5}", 5, self._status_attr(status))
|
||||
@@ -130,10 +132,8 @@ class _CursesBrowser:
|
||||
pass
|
||||
footer_attr = self._pair(4, c.A_DIM)
|
||||
if self.confirm_delete is not None:
|
||||
label = _label(self.confirm_delete)
|
||||
if len(label) > 40:
|
||||
label = label[:37] + "..."
|
||||
footer, footer_attr = f" Delete session '{label}'? [y/N]", c.A_BOLD | self._pair(5)
|
||||
footer = f" Delete session '{_clip(_label(self.confirm_delete), 40)}'? [y/N]"
|
||||
footer_attr = c.A_BOLD | self._pair(5)
|
||||
elif self.flash:
|
||||
footer = f" {self.flash}"
|
||||
self.flash = ""
|
||||
@@ -193,9 +193,8 @@ class _CursesBrowser:
|
||||
c.start_color()
|
||||
c.use_default_colors()
|
||||
# 1 selected, 2 header, 3 search, 4 dim, 5 error/delete
|
||||
for n, color in enumerate(
|
||||
(c.COLOR_GREEN, c.COLOR_YELLOW, c.COLOR_CYAN, 8 if c.COLORS > 8 else c.COLOR_WHITE, c.COLOR_RED), 1
|
||||
):
|
||||
palette = (c.COLOR_GREEN, c.COLOR_YELLOW, c.COLOR_CYAN, 8 if c.COLORS > 8 else c.COLOR_WHITE, c.COLOR_RED)
|
||||
for n, color in enumerate(palette, 1):
|
||||
c.init_pair(n, color, -1)
|
||||
while True:
|
||||
stdscr.clear()
|
||||
@@ -218,13 +217,9 @@ def _fallback_picker(sessions: list) -> Optional[str]:
|
||||
"""Numbered list (Windows without curses, etc.). Same columns, no delete."""
|
||||
print("\n Browse sessions (enter number to resume, q to cancel)\n")
|
||||
for i, s in enumerate(sessions):
|
||||
label = _label(s)
|
||||
if len(label) > 50:
|
||||
label = label[:47] + "..."
|
||||
print(
|
||||
f" {i + 1:>3}. {label:<50} {_session_status_tag(s.get('_status')):<5} "
|
||||
f"{_msgs_str(s):>5} {_relative_time(s.get('last_active')):<10} "
|
||||
f"{s.get('source', '')[:6]}"
|
||||
f" {i + 1:>3}. {_clip(_label(s), 50):<50} {_session_status_tag(s.get('_status')):<5} "
|
||||
f"{_msgs_str(s):>5} {_relative_time(s.get('last_active')):<10} {s.get('source', '')[:6]}"
|
||||
)
|
||||
while True:
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user