From e15a450a2a605bcca328817b9bff2115d6d0299b Mon Sep 17 00:00:00 2001 From: ardnew Date: Wed, 28 Aug 2024 16:11:32 -0500 Subject: [PATCH 1/2] feat(option): add support for functional option arguments --- menu/model.go | 83 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 5 deletions(-) diff --git a/menu/model.go b/menu/model.go index e52acf7..335e4a1 100644 --- a/menu/model.go +++ b/menu/model.go @@ -49,8 +49,73 @@ type Model struct { help help.Model } +// Option is an optional [Model] configuration function. +type Option func(*Model) + +// WithShowPagination returns an [Option] +// whether the list shows pagination indictors. +func WithShowPagination(show bool) Option { + return func(mod *Model) { mod.list.SetShowPagination(show) } +} + +// WithShowTitle returns an [Option] +// whether to show the list title. +func WithShowTitle(show bool) Option { + return func(mod *Model) { mod.list.SetShowTitle(show) } +} + +// WithFilteringEnabled returns an [Option] +// whether the list allows filtering. +func WithFilteringEnabled(enabled bool) Option { + return func(mod *Model) { mod.list.SetFilteringEnabled(enabled) } +} + +// WithShowFilter returns an [Option] +// whether the list shows the active filter. +func WithShowFilter(show bool) Option { + return func(mod *Model) { mod.list.SetShowFilter(show) } +} + +// WithShowStatusBar returns an [Option] +// whether to show the list's status bar. +func WithShowStatusBar(show bool) Option { + return func(mod *Model) { mod.list.SetShowStatusBar(show) } +} + +// WithShowHelp returns an [Option] +// whether to always show help for active keybindings. +func WithShowHelp(show bool) Option { + return func(mod *Model) { mod.list.SetShowHelp(show) } +} + +// WithAdditionalFullHelpKeys returns an [Option] +// that replaces the lists's [list.Model.AdditionalFullHelpKeys]. +// +// The list's current slice is passed as argument to the given keys function. +// The keys function can then choose to return a new or modified slice. +func WithAdditionalFullHelpKeys(keys func([]key.Binding) []key.Binding) Option { + return func(mod *Model) { + return func() []key.Binding { + return keys(mod.list.AdditionalFullHelpKeys) + } + } +} + +// WithAdditionalShortHelpKeys returns an [Option] +// that replaces the lists's [list.Model.AdditionalShortHelpKeys]. +// +// The list's current slice is passed as argument to the given keys function. +// The keys function can then choose to return a new or modified slice. +func WithAdditionalShortHelpKeys(keys func([]key.Binding) []key.Binding) Option { + return func(mod *Model) { + return func() []key.Binding { + return keys(mod.list.AdditionalShortHelpKeys) + } + } +} + // New setups up a new menu model -func New(title string, choices []Choice, selected *Choice) Model { +func New(title string, choices []Choice, selected *Choice, options ...Option) Model { styles := MenuStyles{ ListTitleStyle: styles.ListTitleStyle, @@ -94,6 +159,10 @@ func New(title string, choices []Choice, selected *Choice) Model { model.SetChoices(choices, selected) + for _, opt := range options { + opt(&model) + } + return model } @@ -127,16 +196,20 @@ func (m Model) SetStyles(s MenuStyles) { } func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - + var cmd tea.Cmd switch msg := msg.(type) { case tea.WindowSizeMsg: m.SetSize(msg) case tea.KeyMsg: - return m.handleKeyMsg(msg, msg) + // Make sure we do not trap keybindings required for editing filters. + // While editing, all messages should be forwarded on to [list.Model]. + if !m.list.SettingFilter() { + if m, cmd = m.handleKeyMsg(msg, msg); cmd != nil { + return m, cmd + } + } } - // No selection made yet so update the list - var cmd tea.Cmd m.list, cmd = m.list.Update(msg) return m, cmd } From 1d6528a6a77e685e04021c89d7b254656de783f3 Mon Sep 17 00:00:00 2001 From: ardnew Date: Wed, 4 Sep 2024 14:40:44 -0500 Subject: [PATCH 2/2] fix syntax issues --- menu/model.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/menu/model.go b/menu/model.go index 335e4a1..7b79842 100644 --- a/menu/model.go +++ b/menu/model.go @@ -95,8 +95,9 @@ func WithShowHelp(show bool) Option { // The keys function can then choose to return a new or modified slice. func WithAdditionalFullHelpKeys(keys func([]key.Binding) []key.Binding) Option { return func(mod *Model) { - return func() []key.Binding { - return keys(mod.list.AdditionalFullHelpKeys) + prev := mod.list.AdditionalFullHelpKeys() + mod.list.AdditionalFullHelpKeys = func() []key.Binding { + return keys(prev) } } } @@ -108,8 +109,9 @@ func WithAdditionalFullHelpKeys(keys func([]key.Binding) []key.Binding) Option { // The keys function can then choose to return a new or modified slice. func WithAdditionalShortHelpKeys(keys func([]key.Binding) []key.Binding) Option { return func(mod *Model) { - return func() []key.Binding { - return keys(mod.list.AdditionalShortHelpKeys) + prev := mod.list.AdditionalShortHelpKeys() + mod.list.AdditionalShortHelpKeys = func() []key.Binding { + return keys(prev) } } } @@ -196,7 +198,6 @@ func (m Model) SetStyles(s MenuStyles) { } func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - var cmd tea.Cmd switch msg := msg.(type) { case tea.WindowSizeMsg: m.SetSize(msg) @@ -204,12 +205,13 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // Make sure we do not trap keybindings required for editing filters. // While editing, all messages should be forwarded on to [list.Model]. if !m.list.SettingFilter() { - if m, cmd = m.handleKeyMsg(msg, msg); cmd != nil { - return m, cmd + if mod, cmd := m.handleKeyMsg(msg, msg); cmd != nil { + return mod, cmd } } } // No selection made yet so update the list + var cmd tea.Cmd m.list, cmd = m.list.Update(msg) return m, cmd }