From 6abc94c87af80b2cfaeed3a39848c1e7adbc5f61 Mon Sep 17 00:00:00 2001 From: Vaniel Date: Mon, 8 Aug 2022 15:55:08 -0300 Subject: [PATCH] feat(choose): add --selected option to choose command --- choose/command.go | 43 ++++++++++++++++++++++++++++++++++++++----- choose/options.go | 1 + 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/choose/command.go b/choose/command.go index 847b746..deb3743 100644 --- a/choose/command.go +++ b/choose/command.go @@ -32,11 +32,6 @@ func (o Options) Run() error { o.Options = strings.Split(strings.TrimSpace(input), "\n") } - var items = make([]item, len(o.Options)) - for i, option := range o.Options { - items[i] = item{text: option, selected: false} - } - // We don't need to display prefixes if we are only picking one option. // Simply displaying the cursor is enough. if o.Limit == 1 && !o.NoLimit { @@ -51,6 +46,24 @@ func (o Options) Run() error { o.Limit = len(o.Options) } + // Keep track of the selected items. + currentSelected := 0 + // Parse the selected items. + selectedItems := parseSelectedItems(o.Selected) + // Check if selected items should be used. + hasSelectedItems := o.Limit > 1 && len(selectedItems) > 0 + + var items = make([]item, len(o.Options)) + for i, option := range o.Options { + // Check if the option should be selected. + isSelected := hasSelectedItems && currentSelected < o.Limit && arrayContains(selectedItems, option) + // If the option is selected then increment the current selected count. + if isSelected { + currentSelected++ + } + items[i] = item{text: option, selected: isSelected} + } + // Use the pagination model to display the current and total number of // pages. pager := paginator.New() @@ -78,6 +91,7 @@ func (o Options) Run() error { cursorStyle: o.CursorStyle.ToLipgloss(), itemStyle: o.ItemStyle.ToLipgloss(), selectedItemStyle: o.SelectedItemStyle.ToLipgloss(), + numSelected: currentSelected, }, tea.WithOutput(os.Stderr)).StartReturningModel() if err != nil { @@ -108,3 +122,22 @@ func (o Options) BeforeReset(ctx *kong.Context) error { style.HideFlags(ctx) return nil } + +// Parse the options that should start selected. +func parseSelectedItems(selected string) []string { + selectedItems := strings.Split(strings.TrimSpace(selected), ",") + for i, selected := range selectedItems { + selectedItems[i] = strings.TrimSpace(selected) + } + return selectedItems +} + +// Check if an array contains a value. +func arrayContains(strArray []string, value string) bool { + for _, str := range strArray { + if str == value { + return true + } + } + return false +} diff --git a/choose/options.go b/choose/options.go index b936047..6c77d4a 100644 --- a/choose/options.go +++ b/choose/options.go @@ -13,6 +13,7 @@ type Options struct { CursorPrefix string `help:"Prefix to show on the cursor item (hidden if limit is 1)" default:"[•] " env:"GUM_CHOOSE_CURSOR_PREFIX"` SelectedPrefix string `help:"Prefix to show on selected items (hidden if limit is 1)" default:"[✕] " env:"GUM_CHOOSE_SELECTED_PREFIX"` UnselectedPrefix string `help:"Prefix to show on unselected items (hidden if limit is 1)" default:"[ ] " env:"GUM_CHOOSE_UNSELECTED_PREFIX"` + Selected string `help:"Options that should start as selected" default:"" env:"GUM_CHOOSE_SELECTED"` CursorStyle style.Styles `embed:"" prefix:"cursor." set:"defaultForeground=212" envprefix:"GUM_CHOOSE_CURSOR_"` ItemStyle style.Styles `embed:"" prefix:"item." hidden:"" envprefix:"GUM_CHOOSE_ITEM_"` SelectedItemStyle style.Styles `embed:"" prefix:"selected." set:"defaultForeground=212" envprefix:"GUM_CHOOSE_SELECTED_"`