diff --git a/choose/choose.go b/choose/choose.go index 4d09b5e..7c3228d 100644 --- a/choose/choose.go +++ b/choose/choose.go @@ -60,6 +60,12 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case timeout.TickTimeoutMsg: if msg.TimeoutValue <= 0 { m.quitting = true + // If the user hasn't selected any items in a multi-select. + // Then we select the item that they have pressed enter on. If they + // have selected items, then we simply return them. + if m.numSelected < 1 { + m.items[m.index].selected = true + } return m, tea.Quit } m.timeout = msg.TimeoutValue diff --git a/choose/options.go b/choose/options.go index c284633..7e02813 100644 --- a/choose/options.go +++ b/choose/options.go @@ -2,23 +2,23 @@ package choose import ( "github.com/charmbracelet/gum/style" - "github.com/charmbracelet/gum/timeout" + "time" ) // Options is the customization options for the choose command. type Options struct { Options []string `arg:"" optional:"" help:"Options to choose from."` - Limit int `help:"Maximum number of options to pick" default:"1" group:"Selection"` - NoLimit bool `help:"Pick unlimited number of options (ignores limit)" group:"Selection"` - Height int `help:"Height of the list" default:"10" env:"GUM_CHOOSE_HEIGHT"` - Cursor string `help:"Prefix to show on item that corresponds to the cursor position" default:"> " env:"GUM_CHOOSE_CURSOR"` - 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_"` - TimeoutOptions timeout.Options // including timeout command options [Timeout,...] + Limit int `help:"Maximum number of options to pick" default:"1" group:"Selection"` + NoLimit bool `help:"Pick unlimited number of options (ignores limit)" group:"Selection"` + Height int `help:"Height of the list" default:"10" env:"GUM_CHOOSE_HEIGHT"` + Cursor string `help:"Prefix to show on item that corresponds to the cursor position" default:"> " env:"GUM_CHOOSE_CURSOR"` + 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_"` + Timeout time.Duration `help:"Timeout until command exits" default:"0" env:"GUM_CONFIRM_TIMEOUT"` // including timeout command options [Timeout,...] } diff --git a/confirm/command.go b/confirm/command.go index 84f5a54..09b94e2 100644 --- a/confirm/command.go +++ b/confirm/command.go @@ -21,7 +21,7 @@ func (o Options) Run() error { confirmation: o.Default, defvalue: o.Default, timeout: o.Timeout, - hasTimeout: o.HasTimeout(), + hasTimeout: o.Timeout > 0, prompt: o.Prompt, selectedStyle: o.SelectedStyle.ToLipgloss(), unselectedStyle: o.UnselectedStyle.ToLipgloss(), diff --git a/confirm/options.go b/confirm/options.go index 1fe9fdc..ed0a944 100644 --- a/confirm/options.go +++ b/confirm/options.go @@ -2,7 +2,7 @@ package confirm import ( "github.com/charmbracelet/gum/style" - "github.com/charmbracelet/gum/timeout" + "time" ) // Options is the customization timeout for the confirm command. @@ -15,6 +15,6 @@ type Options struct { //nolint:staticcheck SelectedStyle style.Styles `embed:"" prefix:"selected." help:"The style of the selected action" set:"defaultBackground=212" set:"defaultForeground=230" set:"defaultPadding=0 3" set:"defaultMargin=1 1" envprefix:"GUM_CONFIRM_SELECTED_"` //nolint:staticcheck - UnselectedStyle style.Styles `embed:"" prefix:"unselected." help:"The style of the unselected action" set:"defaultBackground=235" set:"defaultForeground=254" set:"defaultPadding=0 3" set:"defaultMargin=1 1" envprefix:"GUM_CONFIRM_UNSELECTED_"` - timeout.Options // including timeout command options [Timeout,...] + UnselectedStyle style.Styles `embed:"" prefix:"unselected." help:"The style of the unselected action" set:"defaultBackground=235" set:"defaultForeground=254" set:"defaultPadding=0 3" set:"defaultMargin=1 1" envprefix:"GUM_CONFIRM_UNSELECTED_"` + Timeout time.Duration `help:"Timeout until command exits" default:"0" env:"GUM_CONFIRM_TIMEOUT"` } diff --git a/file/command.go b/file/command.go index 435168c..a4dd9f1 100644 --- a/file/command.go +++ b/file/command.go @@ -51,7 +51,7 @@ func (o Options) Run() error { selectedStyle: o.SelectedStyle.ToLipgloss().Inline(true), fileSizeStyle: o.FileSizeStyle.ToLipgloss().Inline(true), timeout: o.Timeout, - hasTimeout: o.HasTimeout(), + hasTimeout: o.Timeout > 0, aborted: false, } diff --git a/file/options.go b/file/options.go index 1e2a806..960bfec 100644 --- a/file/options.go +++ b/file/options.go @@ -2,7 +2,7 @@ package file import ( "github.com/charmbracelet/gum/style" - "github.com/charmbracelet/gum/timeout" + "time" ) // Options are the options for the file command. @@ -24,6 +24,6 @@ type Options struct { //nolint:staticcheck SelectedStyle style.Styles `embed:"" prefix:"selected." help:"The style to use for the selected item" set:"defaultBold=true" set:"defaultForeground=212" envprefix:"GUM_FILE_SELECTED_"` //nolint:staticcheck - FileSizeStyle style.Styles `embed:"" prefix:"file-size." help:"The style to use for file sizes" set:"defaultWidth=8" set:"defaultAlign=right" set:"defaultForeground=240" envprefix:"GUM_FILE_FILE_SIZE_"` - timeout.Options + FileSizeStyle style.Styles `embed:"" prefix:"file-size." help:"The style to use for file sizes" set:"defaultWidth=8" set:"defaultAlign=right" set:"defaultForeground=240" envprefix:"GUM_FILE_FILE_SIZE_"` + Timeout time.Duration `help:"Timeout until command exits" default:"0" env:"GUM_CONFIRM_TIMEOUT"` } diff --git a/filter/command.go b/filter/command.go index 05231fe..e11f9a7 100644 --- a/filter/command.go +++ b/filter/command.go @@ -81,7 +81,7 @@ func (o Options) Run() error { reverse: o.Reverse, fuzzy: o.Fuzzy, timeout: o.Timeout, - hasTimeout: o.HasTimeout(), + hasTimeout: o.Timeout > 0, }, options...) tm, err := p.Run() diff --git a/filter/options.go b/filter/options.go index 8980cba..085a112 100644 --- a/filter/options.go +++ b/filter/options.go @@ -2,29 +2,29 @@ package filter import ( "github.com/charmbracelet/gum/style" - "github.com/charmbracelet/gum/timeout" + "time" ) // Options is the customization options for the filter command. type Options struct { - Indicator string `help:"Character for selection" default:"•" env:"GUM_FILTER_INDICATOR"` - IndicatorStyle style.Styles `embed:"" prefix:"indicator." set:"defaultForeground=212" envprefix:"GUM_FILTER_INDICATOR_"` - Limit int `help:"Maximum number of options to pick" default:"1" group:"Selection"` - NoLimit bool `help:"Pick unlimited number of options (ignores limit)" group:"Selection"` - Strict bool `help:"Only returns if anything matched. Otherwise return Filter" negatable:"true" default:"true" group:"Selection"` - SelectedPrefix string `help:"Character to indicate selected items (hidden if limit is 1)" default:" ◉ " env:"GUM_FILTER_SELECTED_PREFIX"` - SelectedPrefixStyle style.Styles `embed:"" prefix:"selected-indicator." set:"defaultForeground=212" envprefix:"GUM_FILTER_SELECTED_PREFIX_"` - UnselectedPrefix string `help:"Character to indicate unselected items (hidden if limit is 1)" default:" ○ " env:"GUM_FILTER_UNSELECTED_PREFIX"` - UnselectedPrefixStyle style.Styles `embed:"" prefix:"unselected-prefix." set:"defaultForeground=240" envprefix:"GUM_FILTER_UNSELECTED_PREFIX_"` - TextStyle style.Styles `embed:"" prefix:"text." envprefix:"GUM_FILTER_TEXT_"` - MatchStyle style.Styles `embed:"" prefix:"match." set:"defaultForeground=212" envprefix:"GUM_FILTER_MATCH_"` - Placeholder string `help:"Placeholder value" default:"Filter..." env:"GUM_FILTER_PLACEHOLDER"` - Prompt string `help:"Prompt to display" default:"> " env:"GUM_FILTER_PROMPT"` - PromptStyle style.Styles `embed:"" prefix:"prompt." set:"defaultForeground=240" envprefix:"GUM_FILTER_PROMPT_"` - Width int `help:"Input width" default:"20" env:"GUM_FILTER_WIDTH"` - Height int `help:"Input height" default:"0" env:"GUM_FILTER_HEIGHT"` - Value string `help:"Initial filter value" default:"" env:"GUM_FILTER_VALUE"` - Reverse bool `help:"Display from the bottom of the screen" env:"GUM_FILTER_REVERSE"` - Fuzzy bool `help:"Enable fuzzy matching" default:"true" env:"GUM_FILTER_FUZZY" negatable:""` - timeout.Options + Indicator string `help:"Character for selection" default:"•" env:"GUM_FILTER_INDICATOR"` + IndicatorStyle style.Styles `embed:"" prefix:"indicator." set:"defaultForeground=212" envprefix:"GUM_FILTER_INDICATOR_"` + Limit int `help:"Maximum number of options to pick" default:"1" group:"Selection"` + NoLimit bool `help:"Pick unlimited number of options (ignores limit)" group:"Selection"` + Strict bool `help:"Only returns if anything matched. Otherwise return Filter" negatable:"true" default:"true" group:"Selection"` + SelectedPrefix string `help:"Character to indicate selected items (hidden if limit is 1)" default:" ◉ " env:"GUM_FILTER_SELECTED_PREFIX"` + SelectedPrefixStyle style.Styles `embed:"" prefix:"selected-indicator." set:"defaultForeground=212" envprefix:"GUM_FILTER_SELECTED_PREFIX_"` + UnselectedPrefix string `help:"Character to indicate unselected items (hidden if limit is 1)" default:" ○ " env:"GUM_FILTER_UNSELECTED_PREFIX"` + UnselectedPrefixStyle style.Styles `embed:"" prefix:"unselected-prefix." set:"defaultForeground=240" envprefix:"GUM_FILTER_UNSELECTED_PREFIX_"` + TextStyle style.Styles `embed:"" prefix:"text." envprefix:"GUM_FILTER_TEXT_"` + MatchStyle style.Styles `embed:"" prefix:"match." set:"defaultForeground=212" envprefix:"GUM_FILTER_MATCH_"` + Placeholder string `help:"Placeholder value" default:"Filter..." env:"GUM_FILTER_PLACEHOLDER"` + Prompt string `help:"Prompt to display" default:"> " env:"GUM_FILTER_PROMPT"` + PromptStyle style.Styles `embed:"" prefix:"prompt." set:"defaultForeground=240" envprefix:"GUM_FILTER_PROMPT_"` + Width int `help:"Input width" default:"20" env:"GUM_FILTER_WIDTH"` + Height int `help:"Input height" default:"0" env:"GUM_FILTER_HEIGHT"` + Value string `help:"Initial filter value" default:"" env:"GUM_FILTER_VALUE"` + Reverse bool `help:"Display from the bottom of the screen" env:"GUM_FILTER_REVERSE"` + Fuzzy bool `help:"Enable fuzzy matching" default:"true" env:"GUM_FILTER_FUZZY" negatable:""` + Timeout time.Duration `help:"Timeout until command exits" default:"0" env:"GUM_CONFIRM_TIMEOUT"` } diff --git a/input/command.go b/input/command.go index 956096f..a5554c3 100644 --- a/input/command.go +++ b/input/command.go @@ -42,7 +42,7 @@ func (o Options) Run() error { header: o.Header, headerStyle: o.HeaderStyle.ToLipgloss(), timeout: o.Timeout, - hasTimeout: o.HasTimeout(), + hasTimeout: o.Timeout > 0, }, tea.WithOutput(os.Stderr)) tm, err := p.Run() if err != nil { diff --git a/input/input.go b/input/input.go index 1c659b7..61f9e49 100644 --- a/input/input.go +++ b/input/input.go @@ -36,16 +36,12 @@ func (m model) View() string { if m.quitting { return "" } - var timeStr string - if m.hasTimeout { - timeStr = timeout.Str(m.timeout) - } if m.header != "" { header := m.headerStyle.Render(m.header) - return lipgloss.JoinVertical(lipgloss.Left, header, m.textinput.View()+" "+timeStr) + return lipgloss.JoinVertical(lipgloss.Left, header, m.textinput.View()) } - return timeStr + " " + m.textinput.View() + return m.textinput.View() } func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { diff --git a/input/options.go b/input/options.go index 2a759e3..a765dde 100644 --- a/input/options.go +++ b/input/options.go @@ -2,20 +2,20 @@ package input import ( "github.com/charmbracelet/gum/style" - "github.com/charmbracelet/gum/timeout" + "time" ) // Options are the customization options for the input. type Options struct { - Placeholder string `help:"Placeholder value" default:"Type something..." env:"GUM_INPUT_PLACEHOLDER"` - Prompt string `help:"Prompt to display" default:"> " env:"GUM_INPUT_PROMPT"` - PromptStyle style.Styles `embed:"" prefix:"prompt." envprefix:"GUM_INPUT_PROMPT_"` - CursorStyle style.Styles `embed:"" prefix:"cursor." set:"defaultForeground=212" envprefix:"GUM_INPUT_CURSOR_"` - Value string `help:"Initial value (can also be passed via stdin)" default:""` - CharLimit int `help:"Maximum value length (0 for no limit)" default:"400"` - Width int `help:"Input width" default:"40" env:"GUM_INPUT_WIDTH"` - Password bool `help:"Mask input characters" default:"false"` - Header string `help:"Header value" default:"" env:"GUM_INPUT_HEADER"` - HeaderStyle style.Styles `embed:"" prefix:"header." set:"defaultForeground=240" envprefix:"GUM_INPUT_HEADER_"` - timeout.Options + Placeholder string `help:"Placeholder value" default:"Type something..." env:"GUM_INPUT_PLACEHOLDER"` + Prompt string `help:"Prompt to display" default:"> " env:"GUM_INPUT_PROMPT"` + PromptStyle style.Styles `embed:"" prefix:"prompt." envprefix:"GUM_INPUT_PROMPT_"` + CursorStyle style.Styles `embed:"" prefix:"cursor." set:"defaultForeground=212" envprefix:"GUM_INPUT_CURSOR_"` + Value string `help:"Initial value (can also be passed via stdin)" default:""` + CharLimit int `help:"Maximum value length (0 for no limit)" default:"400"` + Width int `help:"Input width" default:"40" env:"GUM_INPUT_WIDTH"` + Password bool `help:"Mask input characters" default:"false"` + Header string `help:"Header value" default:"" env:"GUM_INPUT_HEADER"` + HeaderStyle style.Styles `embed:"" prefix:"header." set:"defaultForeground=240" envprefix:"GUM_INPUT_HEADER_"` + Timeout time.Duration `help:"Timeout until command exits" default:"0" env:"GUM_CONFIRM_TIMEOUT"` } diff --git a/pager/options.go b/pager/options.go index aabece6..ec863e0 100644 --- a/pager/options.go +++ b/pager/options.go @@ -2,17 +2,17 @@ package pager import ( "github.com/charmbracelet/gum/style" - "github.com/charmbracelet/gum/timeout" + "time" ) // Options are the options for the pager. type Options struct { //nolint:staticcheck - Style style.Styles `embed:"" help:"Style the pager" set:"defaultBorder=rounded" set:"defaultPadding=0 1" set:"defaultBorderForeground=212" envprefix:"GUM_PAGER_"` - HelpStyle style.Styles `embed:"" prefix:"help." help:"Style the help text" set:"defaultForeground=241" envprefix:"GUM_PAGER_HELP_"` - Content string `arg:"" optional:"" help:"Display content to scroll"` - ShowLineNumbers bool `help:"Show line numbers" default:"true"` - LineNumberStyle style.Styles `embed:"" prefix:"line-number." help:"Style the line numbers" set:"defaultForeground=237" envprefix:"GUM_PAGER_LINE_NUMBER_"` - SoftWrap bool `help:"Soft wrap lines" default:"false"` - timeout.Options + Style style.Styles `embed:"" help:"Style the pager" set:"defaultBorder=rounded" set:"defaultPadding=0 1" set:"defaultBorderForeground=212" envprefix:"GUM_PAGER_"` + HelpStyle style.Styles `embed:"" prefix:"help." help:"Style the help text" set:"defaultForeground=241" envprefix:"GUM_PAGER_HELP_"` + Content string `arg:"" optional:"" help:"Display content to scroll"` + ShowLineNumbers bool `help:"Show line numbers" default:"true"` + LineNumberStyle style.Styles `embed:"" prefix:"line-number." help:"Style the line numbers" set:"defaultForeground=237" envprefix:"GUM_PAGER_LINE_NUMBER_"` + SoftWrap bool `help:"Soft wrap lines" default:"false"` + Timeout time.Duration `help:"Timeout until command exits" default:"0" env:"GUM_CONFIRM_TIMEOUT"` } diff --git a/spin/command.go b/spin/command.go index a562162..f7f7ce1 100644 --- a/spin/command.go +++ b/spin/command.go @@ -24,7 +24,7 @@ func (o Options) Run() error { command: o.Command, align: o.Align, timeout: o.Timeout, - hasTimeout: o.HasTimeout(), + hasTimeout: o.Timeout > 0, } p := tea.NewProgram(m, tea.WithOutput(os.Stderr)) mm, err := p.Run() diff --git a/spin/options.go b/spin/options.go index 4fefce9..c161573 100644 --- a/spin/options.go +++ b/spin/options.go @@ -2,18 +2,18 @@ package spin import ( "github.com/charmbracelet/gum/style" - "github.com/charmbracelet/gum/timeout" + "time" ) // Options is the customization options for the spin command. type Options struct { Command []string `arg:"" help:"Command to run"` - ShowOutput bool `help:"Show output of command" default:"false" env:"GUM_SPIN_SHOW_OUTPUT"` - Spinner string `help:"Spinner type" short:"s" type:"spinner" enum:"line,dot,minidot,jump,pulse,points,globe,moon,monkey,meter,hamburger" default:"dot" env:"GUM_SPIN_SPINNER"` - SpinnerStyle style.Styles `embed:"" prefix:"spinner." set:"defaultForeground=212" envprefix:"GUM_SPIN_SPINNER_"` - Title string `help:"Text to display to user while spinning" default:"Loading..." env:"GUM_SPIN_TITLE"` - TitleStyle style.Styles `embed:"" prefix:"title." envprefix:"GUM_SPIN_TITLE_"` - Align string `help:"Alignment of spinner with regard to the title" short:"a" type:"align" enum:"left,right" default:"left" env:"GUM_SPIN_ALIGN"` - timeout.Options + ShowOutput bool `help:"Show output of command" default:"false" env:"GUM_SPIN_SHOW_OUTPUT"` + Spinner string `help:"Spinner type" short:"s" type:"spinner" enum:"line,dot,minidot,jump,pulse,points,globe,moon,monkey,meter,hamburger" default:"dot" env:"GUM_SPIN_SPINNER"` + SpinnerStyle style.Styles `embed:"" prefix:"spinner." set:"defaultForeground=212" envprefix:"GUM_SPIN_SPINNER_"` + Title string `help:"Text to display to user while spinning" default:"Loading..." env:"GUM_SPIN_TITLE"` + TitleStyle style.Styles `embed:"" prefix:"title." envprefix:"GUM_SPIN_TITLE_"` + Align string `help:"Alignment of spinner with regard to the title" short:"a" type:"align" enum:"left,right" default:"left" env:"GUM_SPIN_ALIGN"` + Timeout time.Duration `help:"Timeout until command exits" default:"0" env:"GUM_CONFIRM_TIMEOUT"` } diff --git a/timeout/options.go b/timeout/options.go index dfe7df9..9986835 100644 --- a/timeout/options.go +++ b/timeout/options.go @@ -7,16 +7,6 @@ import ( tea "github.com/charmbracelet/bubbletea" ) -// Options Common Timeout Option. -type Options struct { - Timeout time.Duration `help:"Timeout until command exits" default:"0" env:"GUM_CONFIRM_TIMEOUT"` -} - -// HasTimeout checks for a given timeout parameter. -func (o Options) HasTimeout() (hasTimeout bool) { - return o.Timeout > 0 -} - // Tick interval. const tickInterval = time.Second