Fix #2: fall back to uppercase N

This commit is contained in:
Philip Henning 2026-09-06 18:04:42 +02:00
parent 4615aed580
commit 73c18850c6
5 changed files with 28 additions and 6 deletions

View file

@ -66,7 +66,7 @@ including persistence behavior and manual recovery.
| `Ctrl+E` | Enter or leave Privileged Mode | | `Ctrl+E` | Enter or leave Privileged Mode |
| `b` | Review and restore the session Pre-edit Backup | | `b` | Review and restore the session Pre-edit Backup |
| `n` | Add a Host Entry | | `n` | Add a Host Entry |
| `Shift+N` | Add a Host Entry based on the selected Host Entry (requires an enhanced keyboard protocol) | | `Shift+N` | Add a Host Entry based on the selected Host Entry (`N` fallback without enhanced keyboard support; Caps Lock also triggers it) |
| `e` | Open the selected Host Entry in the Entry Editor | | `e` | Open the selected Host Entry in the Entry Editor |
| `d` | Delete the selected Host Entry | | `d` | Delete the selected Host Entry |
| `Space` | Activate or deactivate the selected Host Entry | | `Space` | Activate or deactivate the selected Host Entry |

View file

@ -63,8 +63,9 @@ separate from the Entry Editor used to change one Host Entry.
In Privileged Mode: In Privileged Mode:
- Press `n` to add a Host Entry. - Press `n` to add a Host Entry.
- Press `Shift+N` to add a Host Entry based on the selected Host Entry. This - Press `Shift+N` to add a Host Entry based on the selected Host Entry. In a
requires a terminal that supports the Kitty enhanced keyboard protocol. terminal without the Kitty enhanced keyboard protocol, uppercase `N` is the
fallback, so Caps Lock also triggers this action.
- Select a non-default Host Entry and press `e` to open the Entry Editor. - Select a non-default Host Entry and press `e` to open the Entry Editor.
- Press `d` and confirm to delete the selected Host Entry. - Press `d` and confirm to delete the selected Host Entry.
- Press `Space` to activate or deactivate the selected Host Entry. - Press `Space` to activate or deactivate the selected Host Entry.
@ -255,7 +256,7 @@ continually retrying it.
| Key | Action | | Key | Action |
| --- | --- | | --- | --- |
| `n` | Add a Host Entry | | `n` | Add a Host Entry |
| `Shift+N` | Add a Host Entry based on the selected Host Entry (requires an enhanced keyboard protocol) | | `Shift+N` | Add a Host Entry based on the selected Host Entry (`N` fallback without enhanced keyboard support; Caps Lock also triggers it) |
| `e` | Open the selected Host Entry in the Entry Editor | | `e` | Open the selected Host Entry in the Entry Editor |
| `d` | Delete the selected Host Entry | | `d` | Delete the selected Host Entry |
| `Space` | Activate or deactivate the selected Host Entry | | `Space` | Activate or deactivate the selected Host Entry |

View file

@ -51,7 +51,7 @@ class HelpModal(ModalScreen[None]):
yield Static("Privileged Mode", classes="help-section") yield Static("Privileged Mode", classes="help-section")
yield Static( yield Static(
"Ctrl+E Enter or leave Privileged Mode n Add Host Entry\n" "Ctrl+E Enter or leave Privileged Mode n Add Host Entry\n"
"Shift+N New from selected (enhanced terminal) b Review Pre-edit Backup", "Shift+N New from selected (N fallback) b Review Pre-edit Backup",
classes="help-copy", classes="help-copy",
) )
yield Button("Close", id="help-close", variant="primary") yield Button("Close", id="help-close", variant="primary")

View file

@ -10,7 +10,13 @@ from textual.binding import Binding
# Key bindings for the hosts manager application # Key bindings for the hosts manager application
HOSTS_MANAGER_BINDINGS = [ HOSTS_MANAGER_BINDINGS = [
Binding("n", "add_entry", "New entry", show=True, id="left:new_entry"), Binding("n", "add_entry", "New entry", show=True, id="left:new_entry"),
Binding("shift+n", "new_from_selected", "New from selected", show=False), Binding(
"shift+n,N",
"new_from_selected",
"New from selected",
show=False,
key_display="Shift+N",
),
Binding("d", "delete_entry", "Delete entry", show=True, id="left:delete_entry"), Binding("d", "delete_entry", "Delete entry", show=True, id="left:delete_entry"),
Binding("e", "edit_entry", "Edit entry", show=True, id="left:edit_entry"), Binding("e", "edit_entry", "Edit entry", show=True, id="left:edit_entry"),
Binding( Binding(

View file

@ -183,6 +183,21 @@ async def test_enhanced_shift_n_opens_new_from_selected_but_caps_lock_n_does_not
assert not isinstance(app.screen, AddEntryModal) assert not isinstance(app.screen, AddEntryModal)
@pytest.mark.asyncio
async def test_uppercase_n_is_a_fallback_when_the_terminal_lacks_enhanced_keys():
"""Legacy terminals use uppercase N for Shift+N and Caps Lock+N alike."""
app = app_with_filterable_entries()
app.edit_mode = True
async with app.run_test(size=(120, 40)) as pilot:
app.table_handler.populate_entries_table()
app.query_one("#entries-table").focus()
await pilot.press("N")
await pilot.pause()
assert isinstance(app.screen, AddEntryModal)
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_new_from_selected_requires_a_visible_host_entry(): async def test_new_from_selected_requires_a_visible_host_entry():
"""Shift+N does not reuse a stale selection when filters hide every entry.""" """Shift+N does not reuse a stale selection when filters hide every entry."""