diff --git a/meshterm/ui/atlas_screen.py b/meshterm/ui/atlas_screen.py index e02c58a..3c7883b 100644 --- a/meshterm/ui/atlas_screen.py +++ b/meshterm/ui/atlas_screen.py @@ -184,7 +184,7 @@ class AtlasScreen(Screen): def footer_hint(self) -> str: # type: ignore[override] """Camera and find hints; the find query takes the row over while active.""" if self._filter: - return f"find: {self._filter}▏ · Enter select · Bksp erase · Esc clear" + return f"find: {self._filter}▏ · Enter select · ⌫ erase · Esc clear" return "↑↓←→ pan · PgUp/PgDn zoom · Tab walk · Enter info · type to find · Esc" def handle(self, action: str, data: str = "") -> None: diff --git a/meshterm/ui/channels.py b/meshterm/ui/channels.py index 38b3799..bdce0c1 100644 --- a/meshterm/ui/channels.py +++ b/meshterm/ui/channels.py @@ -739,7 +739,7 @@ async def _show_share( Text(""), Text(url, style="accent"), ) - await ctx.ui.view(body, title=f"Share {name}", footer_hint="Esc back") + await ctx.ui.view(body, title=f"Share {name}", footer_hint="Esc close") async def _show_key(ctx: "AppContext", slot: ChannelSlot) -> None: @@ -775,7 +775,7 @@ async def _show_key(ctx: "AppContext", slot: ChannelSlot) -> None: blocks.append(Text()) blocks.append(Text(label, style="muted")) blocks.append(value) - await ctx.ui.view(Group(*blocks), title=f"Key — {slot.name}", footer_hint="Esc back") + await ctx.ui.view(Group(*blocks), title=f"Key — {slot.name}", footer_hint="Esc close") async def _open_chat(ctx: "AppContext", slot: ChannelSlot) -> None: diff --git a/meshterm/ui/chat.py b/meshterm/ui/chat.py index 6f924e8..d62417a 100644 --- a/meshterm/ui/chat.py +++ b/meshterm/ui/chat.py @@ -167,7 +167,7 @@ class ChatScreen(Screen): """Key hint, reflecting whether a message is picked for reply (channels only).""" if not self._is_channel: if any(m.outbound and m.acked is False for m in self._messages): - return "Enter send · Ctrl-R retry failed · ↑↓/PgUp scroll · ^End latest · Esc back" + return "Enter send · ^R retry failed · ↑↓/PgUp scroll · ^End latest · Esc back" return "Enter send · ↑↓/PgUp scroll · ^End latest · Esc back" if self._selected is not None: return "Enter reply (@mention) · ↑↓ pick · ^End/Esc cancel" @@ -736,7 +736,7 @@ class ChatScreen(Screen): message.acked = False self._status = f"retry failed: {exc}" else: - self._status = "" if message.acked else "still no ack — Ctrl-R to retry" + self._status = "" if message.acked else "still no ack — ^R to retry" finally: self._sending = False self._stick = True diff --git a/meshterm/ui/config_editor.py b/meshterm/ui/config_editor.py index b0d6caa..897cec4 100644 --- a/meshterm/ui/config_editor.py +++ b/meshterm/ui/config_editor.py @@ -816,7 +816,7 @@ async def _show_contact_card(ctx: "AppContext", snapshot: dict) -> None: Text(""), Text(url, style="accent"), ) - await ctx.ui.view(body, title=f"Share {name}", footer_hint="Esc back") + await ctx.ui.view(body, title=f"Share {name}", footer_hint="Esc close") async def _reboot(ctx: "AppContext", device: "Device", snapshot: dict) -> bool: diff --git a/meshterm/ui/courier_screen.py b/meshterm/ui/courier_screen.py index a0af3d0..2dc641e 100644 --- a/meshterm/ui/courier_screen.py +++ b/meshterm/ui/courier_screen.py @@ -290,7 +290,7 @@ async def _pick_schedule(ctx: "AppContext", name: str): ] picked = await session.select( f"When should {name} get it?", items, filterable=False, - footer_hint="↑↓ move · Enter choose · Esc cancel", + footer_hint="↑↓ move · Enter select · Esc cancel", ) if picked == "custom": while True: diff --git a/meshterm/ui/map_screen.py b/meshterm/ui/map_screen.py index 7cb098b..aa5fc74 100644 --- a/meshterm/ui/map_screen.py +++ b/meshterm/ui/map_screen.py @@ -125,9 +125,9 @@ class MapScreen(Screen): editing keys, so the typed text is always visible somewhere fixed. """ if self._filter: - base = f"find: {self._filter}▏ · Enter frame · Bksp erase · Esc clear" + base = f"find: {self._filter}▏ · Enter frame · ⌫ erase · Esc clear" else: - base = "↑↓←→ pan · ⇧ fine · PgUp/PgDn zoom · Home reset · type to find · Esc" + base = "↑↓←→ pan · ⇧ fine · PgUp/PgDn zoom · Home reset · type to find · Esc back" if self._pending: return f"{base} · [muted]loading {len(self._pending)} tiles…[/muted]" if not self._source.available: diff --git a/meshterm/ui/menu.py b/meshterm/ui/menu.py index 1aa9ea6..346cc01 100644 --- a/meshterm/ui/menu.py +++ b/meshterm/ui/menu.py @@ -422,7 +422,7 @@ async def _menu_loop(ctx: AppContext, session: TuiSession) -> None: buttons, title="Quit MeshTerm", default=len(buttons) - 1, # highlight Quit - footer_hint="Esc cancel · Enter quit", + footer_hint="Enter quit · Esc cancel", prompt_style="warn", button_style="selected", button_idle_style="muted", diff --git a/meshterm/ui/path_composer.py b/meshterm/ui/path_composer.py index cbbeace..7f46db2 100644 --- a/meshterm/ui/path_composer.py +++ b/meshterm/ui/path_composer.py @@ -98,7 +98,7 @@ class PathComposerScreen(Screen): :data:`~meshterm.ui.tui.screen.CANCEL`. """ - footer_hint = "↑↓ · Enter add · type to filter · ⌫ remove · Esc" + footer_hint = "↑↓ move · Enter add · type to filter · ⌫ remove · Esc cancel" def __init__( self, diff --git a/meshterm/ui/trace_screen.py b/meshterm/ui/trace_screen.py index 0e8b151..1358a6b 100644 --- a/meshterm/ui/trace_screen.py +++ b/meshterm/ui/trace_screen.py @@ -1255,7 +1255,7 @@ async def _open_session(ctx: "AppContext", target: Optional[str]) -> int: items, prompt="Forced hops are addressed by this many leading key bytes.", default=width_bytes, - footer_hint="↑↓ · Enter set · Esc keep", + footer_hint="↑↓ move · Enter set · Esc keep", filterable=False, wrap=False, ) @@ -1292,7 +1292,7 @@ async def _open_session(ctx: "AppContext", target: Optional[str]) -> int: items, prompt=f"One Trace action runs this many traces, {pace:g} s apart.", default=sample_count, - footer_hint="↑↓ · Enter set · Esc keep", + footer_hint="↑↓ move · Enter set · Esc keep", filterable=False, wrap=False, ) diff --git a/meshterm/ui/tui/prompt.py b/meshterm/ui/tui/prompt.py index aff7654..ec4f78e 100644 --- a/meshterm/ui/tui/prompt.py +++ b/meshterm/ui/tui/prompt.py @@ -332,7 +332,7 @@ class ConfirmScreen(Screen): title: str, *, default: bool = True, - footer_hint: str = "←→/Y/N choose · Enter accept · Esc cancel", + footer_hint: str = "←→/Y/N choose · Enter select · Esc cancel", ) -> None: """Build a confirm prompt. diff --git a/meshterm/ui/tui/screen.py b/meshterm/ui/tui/screen.py index fc5a0d4..47c7e37 100644 --- a/meshterm/ui/tui/screen.py +++ b/meshterm/ui/tui/screen.py @@ -268,7 +268,7 @@ class ScrollScreen(Screen): renderable: RenderableType, *, title: str = "", - footer_hint: str = "↑↓ PgUp/PgDn scroll · Esc back", + footer_hint: str = "↑↓ PgUp/PgDn scroll · Esc close", floating: bool = True, ) -> None: """Wrap a renderable in a dismissable, scrollable screen. diff --git a/meshterm/ui/tui/session.py b/meshterm/ui/tui/session.py index f2e5088..32058a6 100644 --- a/meshterm/ui/tui/session.py +++ b/meshterm/ui/tui/session.py @@ -550,7 +550,7 @@ class TuiSession: screen = ScrollScreen( renderable, title=title, - footer_hint=footer_hint or "↑↓ PgUp/PgDn scroll · Esc back", + footer_hint=footer_hint or "↑↓ PgUp/PgDn scroll · Esc close", ) await self.run_screen(screen) diff --git a/meshterm/ui/tx_screen.py b/meshterm/ui/tx_screen.py index 0b4ac84..88ccae2 100644 --- a/meshterm/ui/tx_screen.py +++ b/meshterm/ui/tx_screen.py @@ -675,7 +675,7 @@ async def open_tx_optimize( items, prompt="The TX window the sweep explores:", default=(screen.tx_min, screen.tx_max), - footer_hint="↑↓ · Enter set · Esc keep", + footer_hint="↑↓ move · Enter set · Esc keep", filterable=False, wrap=False, ) @@ -714,7 +714,7 @@ async def open_tx_optimize( items, prompt="The coarse sweep measures the window at this spacing, then refines.", default=screen.step, - footer_hint="↑↓ · Enter set · Esc keep", + footer_hint="↑↓ move · Enter set · Esc keep", filterable=False, wrap=False, ) @@ -739,7 +739,7 @@ async def open_tx_optimize( items, prompt=f"Each TX level is measured with this many traces, {pace:g} s apart.", default=screen.samples, - footer_hint="↑↓ · Enter set · Esc keep", + footer_hint="↑↓ move · Enter set · Esc keep", filterable=False, wrap=False, ) @@ -804,7 +804,7 @@ async def open_tx_optimize( [("Cancel", "cancel"), ("Apply", "apply")], title="Apply winner", default=1, - footer_hint="Esc cancel · Enter apply", + footer_hint="Enter apply · Esc cancel", ) if choice != "apply": return diff --git a/tests/test_chat.py b/tests/test_chat.py index aeee0c6..93702f0 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -668,8 +668,9 @@ def test_chat_screen_shows_delivery_glyphs() -> None: # static hourglass; resolved ones show ✅ / ❌. assert "✅" in joined and "❌" in joined assert Spinner.BRAILLE[0] in joined and "⏳" not in joined - # A failed message advertises the retry shortcut in the footer hint. - assert "Ctrl-R" in screen.footer_hint + # A failed message advertises the retry shortcut in the footer hint (the app-wide + # compact ^-notation for Ctrl chords). + assert "^R" in screen.footer_hint def test_wrapped_body_hangs_under_the_first_line() -> None: