make keybinds configurable and consolidate

This commit is contained in:
2026-07-28 14:55:38 +02:00
parent bb8e91039f
commit 948f3e1a79
12 changed files with 1469 additions and 158 deletions

View File

@@ -56,6 +56,10 @@ directory = "/tmp/gh-threads-cache"
[editing]
mode = "standard"
[keybindings.navigation]
down = ["ctrl+j"]
up = ["ctrl+k"]
`
if err := os.WriteFile(path, []byte(content), 0o600); err != nil {
t.Fatal(err)
@@ -76,11 +80,63 @@ mode = "standard"
strings.Join(got.Threads.StatusOrder, ",") != "resolved,unresolved,outdated" ||
got.Threads.WithinStatus != "timestamp" || got.Cache.Enabled ||
got.Cache.MaxAge.Duration != 48*time.Hour || got.Cache.Directory != "/tmp/gh-threads-cache" ||
got.Editing.Mode != "standard" {
got.Editing.Mode != "standard" ||
strings.Join(got.KeyBindings.Navigation.Down, ",") != "ctrl+j" ||
strings.Join(got.KeyBindings.Navigation.Up, ",") != "ctrl+k" {
t.Fatalf("config = %#v", got)
}
}
func TestValidateConfigRejectsEmptyKeyBinding(t *testing.T) {
config := defaultConfig()
config.KeyBindings.Navigation.Down = nil
err := validateConfig(config)
if err == nil || !strings.Contains(err.Error(), "keybindings.navigation.down") {
t.Fatalf("empty binding error = %v", err)
}
}
func TestValidateConfigRejectsKeyConflictsInTheSameContext(t *testing.T) {
tests := []struct {
name string
change func(*Config)
context string
actions []string
}{
{
name: "thread navigation and reply",
change: func(config *Config) {
config.KeyBindings.Threads.Reply = []string{"j"}
},
context: "review threads",
actions: []string{"down", "reply"},
},
{
name: "vim motion and cancel",
change: func(config *Config) {
config.KeyBindings.Input.Cancel = []string{"b"}
},
context: "Vim Normal mode",
actions: []string{"cancel", "word_backward"},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
config := defaultConfig()
test.change(&config)
err := validateConfig(config)
if err == nil || !strings.Contains(err.Error(), test.context) {
t.Fatalf("conflict error = %v", err)
}
for _, action := range test.actions {
if !strings.Contains(err.Error(), action) {
t.Fatalf("conflict error does not name %q: %v", action, err)
}
}
})
}
}
func TestLoadConfigRejectsUnknownSettings(t *testing.T) {
path := filepath.Join(t.TempDir(), "config.toml")
if err := os.WriteFile(path, []byte("refesh_interval = \"10s\"\n"), 0o600); err != nil {