diff --git a/cmd/keys.go b/cmd/keys.go index aa5a705..3a31314 100644 --- a/cmd/keys.go +++ b/cmd/keys.go @@ -11,8 +11,9 @@ import ( func newKeysCmd() *cobra.Command { var ( - filter string - asJSON bool + filter string + section string + asJSON bool ) keysCmd := &cobra.Command{ @@ -20,7 +21,8 @@ func newKeysCmd() *cobra.Command { Short: "Print keybindings", Long: "Print the built-in keybinding reference without starting the TUI.", RunE: func(cmd *cobra.Command, args []string) error { - sections := filterKeybindingSections(keybindings.Sections(), filter) + sections := filterKeybindingSectionsByID(keybindings.Sections(), section) + sections = filterKeybindingSections(sections, filter) if asJSON { enc := json.NewEncoder(cmd.OutOrStdout()) enc.SetIndent("", " ") @@ -32,10 +34,24 @@ func newKeysCmd() *cobra.Command { } keysCmd.Flags().StringVar(&filter, "filter", "", "Only show sections, keys, or actions matching this text") + keysCmd.Flags().StringVar(§ion, "section", "", "Only show the section with this id") keysCmd.Flags().BoolVar(&asJSON, "json", false, "Print keybindings as JSON") return keysCmd } +func filterKeybindingSectionsByID(sections []keybindings.Section, section string) []keybindings.Section { + query := strings.TrimSpace(strings.ToLower(section)) + if query == "" { + return sections + } + for _, item := range sections { + if strings.ToLower(item.ID) == query { + return []keybindings.Section{item} + } + } + return []keybindings.Section{} +} + func filterKeybindingSections(sections []keybindings.Section, filter string) []keybindings.Section { query := strings.TrimSpace(strings.ToLower(filter)) if query == "" { diff --git a/cmd/keys_test.go b/cmd/keys_test.go index 13a7091..cf63c3f 100644 --- a/cmd/keys_test.go +++ b/cmd/keys_test.go @@ -35,6 +35,48 @@ func TestKeysCommandFiltersBindings(t *testing.T) { assert.NotContains(t, out.String(), "File Tree\n") } +func TestKeysCommandFiltersBySection(t *testing.T) { + cmd := newKeysCmd() + cmd.SetArgs([]string{"--section", "filetree"}) + var out bytes.Buffer + cmd.SetOut(&out) + + err := cmd.Execute() + + require.NoError(t, err) + assert.Contains(t, out.String(), "File Tree") + assert.NotContains(t, out.String(), "Global\n") +} + +func TestKeysCommandFiltersBySectionJSON(t *testing.T) { + cmd := newKeysCmd() + cmd.SetArgs([]string{"--section", "global", "--json"}) + var out bytes.Buffer + cmd.SetOut(&out) + + err := cmd.Execute() + + require.NoError(t, err) + var sections []keybindings.Section + require.NoError(t, json.Unmarshal(out.Bytes(), §ions)) + require.Len(t, sections, 1) + assert.Equal(t, "global", sections[0].ID) +} + +func TestKeysCommandUnknownSectionReturnsEmptyJSON(t *testing.T) { + cmd := newKeysCmd() + cmd.SetArgs([]string{"--section", "missing", "--json"}) + var out bytes.Buffer + cmd.SetOut(&out) + + err := cmd.Execute() + + require.NoError(t, err) + var sections []keybindings.Section + require.NoError(t, json.Unmarshal(out.Bytes(), §ions)) + assert.Empty(t, sections) +} + func TestKeysCommandPrintsJSON(t *testing.T) { cmd := newKeysCmd() cmd.SetArgs([]string{"--filter", "global", "--json"})