From 73e5a76f1228b355046cd13c6193105c5c569c0e Mon Sep 17 00:00:00 2001 From: Dieter Eickstaedt Date: Thu, 29 Jun 2023 22:53:38 +0200 Subject: [PATCH] feat: Adding timeout option to Filter command --- filter/command.go | 20 +++++++++++------- filter/filter.go | 18 +++++++++++++++- filter/options.go | 53 ++++++++++++++++++++++++++--------------------- 3 files changed, 59 insertions(+), 32 deletions(-) diff --git a/filter/command.go b/filter/command.go index 492c904..9cb614a 100644 --- a/filter/command.go +++ b/filter/command.go @@ -90,6 +90,8 @@ func (o Options) Run() error { limit: o.Limit, reverse: o.Reverse, fuzzy: o.Fuzzy, + timeout: o.Timeout, + hasTimeout: o.Timeout > 0, sort: o.Sort, }, options...) @@ -108,13 +110,7 @@ func (o Options) Run() error { // than 1 or if flag --no-limit is passed, hence there is // no need to further checks if len(m.selected) > 0 { - for k := range m.selected { - if isTTY { - fmt.Println(k) - } else { - fmt.Println(ansi.Strip(k)) - } - } + o.checkSelected(m, isTTY) } else if len(m.matches) > m.cursor && m.cursor >= 0 { if isTTY { fmt.Println(m.matches[m.cursor].Str) @@ -129,6 +125,16 @@ func (o Options) Run() error { return nil } +func (o Options) checkSelected(m model, isTTY bool) { + for k := range m.selected { + if isTTY { + fmt.Println(k) + } else { + fmt.Println(ansi.Strip(k)) + } + } +} + // BeforeReset hook. Used to unclutter style flags. func (o Options) BeforeReset(ctx *kong.Context) error { style.HideFlags(ctx) diff --git a/filter/filter.go b/filter/filter.go index 22f4fdf..38c25f9 100644 --- a/filter/filter.go +++ b/filter/filter.go @@ -12,6 +12,9 @@ package filter import ( "strings" + "time" + + "github.com/charmbracelet/gum/timeout" "github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/bubbles/viewport" @@ -46,9 +49,13 @@ type model struct { reverse bool fuzzy bool sort bool + timeout time.Duration + hasTimeout bool } -func (m model) Init() tea.Cmd { return nil } +func (m model) Init() tea.Cmd { + return timeout.Init(m.timeout, nil) +} func (m model) View() string { if m.quitting { return "" @@ -149,6 +156,15 @@ func (m model) View() string { func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmd tea.Cmd switch msg := msg.(type) { + case timeout.TickTimeoutMsg: + if msg.TimeoutValue <= 0 { + m.quitting = true + m.aborted = true + return m, tea.Quit + } + m.timeout = msg.TimeoutValue + return m, timeout.Tick(msg.TimeoutValue, msg.Data) + case tea.WindowSizeMsg: if m.height == 0 || m.height > msg.Height { m.viewport.Height = msg.Height - lipgloss.Height(m.textinput.View()) diff --git a/filter/options.go b/filter/options.go index b578d29..366d757 100644 --- a/filter/options.go +++ b/filter/options.go @@ -1,30 +1,35 @@ package filter -import "github.com/charmbracelet/gum/style" +import ( + "time" + + "github.com/charmbracelet/gum/style" +) // 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_"` - HeaderStyle style.Styles `embed:"" prefix:"header." set:"defaultForeground=240" envprefix:"GUM_FILTER_HEADER_"` - Header string `help:"Header value" default:"" env:"GUM_FILTER_HEADER"` - TextStyle style.Styles `embed:"" prefix:"text." envprefix:"GUM_FILTER_TEXT_"` - CursorTextStyle style.Styles `embed:"" prefix:"cursor-text." envprefix:"GUM_FILTER_CURSOR_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:""` - Sort bool `help:"Sort the results" default:"true" env:"GUM_FILTER_SORT" negatable:""` + 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_"` + HeaderStyle style.Styles `embed:"" prefix:"header." set:"defaultForeground=240" envprefix:"GUM_FILTER_HEADER_"` + Header string `help:"Header value" default:"" env:"GUM_FILTER_HEADER"` + TextStyle style.Styles `embed:"" prefix:"text." envprefix:"GUM_FILTER_TEXT_"` + CursorTextStyle style.Styles `embed:"" prefix:"cursor-text." envprefix:"GUM_FILTER_CURSOR_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:""` + Sort bool `help:"Sort the results" default:"true" env:"GUM_FILTER_SORT" negatable:""` + Timeout time.Duration `help:"Timeout until filter command aborts" default:"0" env:"GUM_FILTER_TIMEOUT"` }