change: remap keys — Ctrl+P toggles preview, Ctrl+F opens the picker
0a0d5ea01ef500c81bb68e121c020697b770e4c2
humdrum <me@humdrum.me> · 2026-06-28 16:06
parent a0797b7f
change: remap keys — Ctrl+P toggles preview, Ctrl+F opens the picker Preview/edit toggle moves from Ctrl+R to Ctrl+P; the fuzzy picker moves from Ctrl+P to Ctrl+F (and its dirty-discard confirm prompt updates to Ctrl+F). Ctrl+R is now unbound. Tests and the dirty-confirm guard updated to match.
2 files changed
internal/app/app.go +4 −4
@@ -136,7 +136,7 @@ if msg.Type != tea.KeyCtrlQ {
a.quitArmed = false
}
// Disarm pending-discard unless the same action is being re-pressed.
- if !(msg.Type == tea.KeyCtrlP && a.pending == discardPicker) &&
+ if !(msg.Type == tea.KeyCtrlF && a.pending == discardPicker) &&
!(msg.Type == tea.KeyCtrlD && a.pending == discardDaily) &&
!(msg.Type == tea.KeyCtrlN && a.pending == discardNew) {
a.pending = discardNone
@@ -152,14 +152,14 @@ }
return a, tea.Quit
case tea.KeyCtrlS:
return a.save()
- case tea.KeyCtrlR:
+ case tea.KeyCtrlP:
return a.togglePreview()
case tea.KeyCtrlT:
return a.cycleTheme()
- case tea.KeyCtrlP:
+ case tea.KeyCtrlF:
if a.editor.Dirty && a.pending != discardPicker {
a.pending = discardPicker
- a.status = "Unsaved changes — Ctrl+P again to discard"
+ a.status = "Unsaved changes — Ctrl+F again to discard"
return a, nil
}
a.pending = discardNone
internal/app/app_test.go +21 −21
@@ -136,15 +136,15 @@ t.Errorf("Ctrl+S on unnamed buffer: mode = %d, want ModeSaveAs", a.mode)
}
}
-func TestCtrlRTogglesPreview(t *testing.T) {
+func TestCtrlPTogglesPreview(t *testing.T) {
a := newApp()
a.Update(tea.WindowSizeMsg{Width: 80, Height: 24})
a.editor.SetContent([]byte("# hello"))
- a.Update(tea.KeyMsg{Type: tea.KeyCtrlR})
+ a.Update(tea.KeyMsg{Type: tea.KeyCtrlP})
if a.mode != ModePreview {
t.Errorf("mode = %d, want ModePreview", a.mode)
}
- a.Update(tea.KeyMsg{Type: tea.KeyCtrlR})
+ a.Update(tea.KeyMsg{Type: tea.KeyCtrlP})
if a.mode != ModeEditor {
t.Errorf("mode = %d, want ModeEditor after second toggle", a.mode)
}
@@ -154,21 +154,21 @@ func TestEscReturnsToEditor(t *testing.T) {
a := newApp()
a.Update(tea.WindowSizeMsg{Width: 80, Height: 24})
a.editor.SetContent([]byte("x"))
- a.Update(tea.KeyMsg{Type: tea.KeyCtrlR})
+ a.Update(tea.KeyMsg{Type: tea.KeyCtrlP})
a.Update(tea.KeyMsg{Type: tea.KeyEsc})
if a.mode != ModeEditor {
t.Errorf("Esc should return to editor, mode = %d", a.mode)
}
}
-func TestCtrlPOpensPicker(t *testing.T) {
+func TestCtrlFOpensPicker(t *testing.T) {
dir := t.TempDir()
os.WriteFile(filepath.Join(dir, "note.md"), []byte("x"), 0o644)
cfg := config.Default()
cfg.VaultDir = dir
a := New(cfg)
a.Update(tea.WindowSizeMsg{Width: 80, Height: 24})
- a.Update(tea.KeyMsg{Type: tea.KeyCtrlP})
+ a.Update(tea.KeyMsg{Type: tea.KeyCtrlF})
if a.mode != ModePicker {
t.Errorf("mode = %d, want ModePicker", a.mode)
}
@@ -237,7 +237,7 @@ t.Errorf("daily file should exist: %v", err)
}
}
-func TestCtrlPDirtyNeedsConfirm(t *testing.T) {
+func TestCtrlFDirtyNeedsConfirm(t *testing.T) {
dir := t.TempDir()
os.WriteFile(filepath.Join(dir, "note.md"), []byte("x"), 0o644)
cfg := config.Default()
@@ -246,22 +246,22 @@ a := New(cfg)
a.Update(tea.WindowSizeMsg{Width: 80, Height: 24})
// Make dirty
a.editor.HandleKey(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'z'}})
- // First Ctrl+P — should arm, not open picker
- a.Update(tea.KeyMsg{Type: tea.KeyCtrlP})
+ // First Ctrl+F — should arm, not open picker
+ a.Update(tea.KeyMsg{Type: tea.KeyCtrlF})
if a.mode != ModeEditor {
- t.Errorf("first Ctrl+P on dirty editor: mode = %d, want ModeEditor", a.mode)
+ t.Errorf("first Ctrl+F on dirty editor: mode = %d, want ModeEditor", a.mode)
}
if !strings.Contains(a.status, "discard") {
- t.Errorf("first Ctrl+P on dirty editor: status = %q, want it to contain 'discard'", a.status)
+ t.Errorf("first Ctrl+F on dirty editor: status = %q, want it to contain 'discard'", a.status)
}
- // Second Ctrl+P — should open picker
- a.Update(tea.KeyMsg{Type: tea.KeyCtrlP})
+ // Second Ctrl+F — should open picker
+ a.Update(tea.KeyMsg{Type: tea.KeyCtrlF})
if a.mode != ModePicker {
- t.Errorf("second Ctrl+P: mode = %d, want ModePicker", a.mode)
+ t.Errorf("second Ctrl+F: mode = %d, want ModePicker", a.mode)
}
}
-func TestCtrlPDirtyDisarmedByOtherKey(t *testing.T) {
+func TestCtrlFDirtyDisarmedByOtherKey(t *testing.T) {
dir := t.TempDir()
os.WriteFile(filepath.Join(dir, "note.md"), []byte("x"), 0o644)
cfg := config.Default()
@@ -270,14 +270,14 @@ a := New(cfg)
a.Update(tea.WindowSizeMsg{Width: 80, Height: 24})
// Make dirty
a.editor.HandleKey(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'z'}})
- // First Ctrl+P — arms
- a.Update(tea.KeyMsg{Type: tea.KeyCtrlP})
+ // First Ctrl+F — arms
+ a.Update(tea.KeyMsg{Type: tea.KeyCtrlF})
// Press a different key — disarms pending
a.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'a'}})
- // Second Ctrl+P — should re-arm (not open) because pending was cleared
- a.Update(tea.KeyMsg{Type: tea.KeyCtrlP})
+ // Second Ctrl+F — should re-arm (not open) because pending was cleared
+ a.Update(tea.KeyMsg{Type: tea.KeyCtrlF})
if a.mode != ModeEditor {
- t.Errorf("Ctrl+P after disarm should re-arm, not open picker: mode = %d", a.mode)
+ t.Errorf("Ctrl+F after disarm should re-arm, not open picker: mode = %d", a.mode)
}
}
@@ -336,7 +336,7 @@ cfg := config.Default()
cfg.VaultDir = dir
a := New(cfg)
a.Update(tea.WindowSizeMsg{Width: 80, Height: 24})
- a.Update(tea.KeyMsg{Type: tea.KeyCtrlP}) // open picker
+ a.Update(tea.KeyMsg{Type: tea.KeyCtrlF}) // open picker (Ctrl+F)
if a.mode != ModePicker {
t.Fatalf("expected picker mode")
}