summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDieter Eickstaedt <eickstaedt@deicon.de>2023-06-30 15:28:46 +0200
committerGitHub <noreply@github.com>2023-06-30 09:28:46 -0400
commitd1ad453ce61aeb1181e5cf86ceb28c888ab92ff2 (patch)
tree16a27c5a8638f4d2eb3578be50e168abb17de738
parentf73341a56c0540b7202ae83397f6ba7db4cd8f58 (diff)
feat: Timeout for Choose Command (#384)
-rw-r--r--choose/choose.go29
-rw-r--r--choose/command.go2
-rw-r--r--choose/options.go38
3 files changed, 49 insertions, 20 deletions
diff --git a/choose/choose.go b/choose/choose.go
index a694a7a..b32030b 100644
--- a/choose/choose.go
+++ b/choose/choose.go
@@ -12,6 +12,9 @@ package choose
import (
"strings"
+ "time"
+
+ "github.com/charmbracelet/gum/timeout"
"github.com/charmbracelet/bubbles/paginator"
tea "github.com/charmbracelet/bubbletea"
@@ -39,6 +42,8 @@ type model struct {
headerStyle lipgloss.Style
itemStyle lipgloss.Style
selectedItemStyle lipgloss.Style
+ hasTimeout bool
+ timeout time.Duration
}
type item struct {
@@ -47,13 +52,27 @@ type item struct {
order int
}
-func (m model) Init() tea.Cmd { return nil }
+func (m model) Init() tea.Cmd {
+ return timeout.Init(m.timeout, nil)
+}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
return m, nil
-
+ 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
+ return m, timeout.Tick(msg.TimeoutValue, msg.Data)
case tea.KeyMsg:
start, end := m.paginator.GetSliceBounds(len(m.items))
switch keypress := msg.String(); keypress {
@@ -151,6 +170,7 @@ func (m model) View() string {
}
var s strings.Builder
+ var timeoutStr string
start, end := m.paginator.GetSliceBounds(len(m.items))
for i, item := range m.items[start:end] {
@@ -161,7 +181,10 @@ func (m model) View() string {
}
if item.selected {
- s.WriteString(m.selectedItemStyle.Render(m.selectedPrefix + item.text))
+ if m.hasTimeout {
+ timeoutStr = timeout.Str(m.timeout)
+ }
+ s.WriteString(m.selectedItemStyle.Render(m.selectedPrefix + item.text + timeoutStr))
} else if i == m.index%m.height {
s.WriteString(m.cursorStyle.Render(m.cursorPrefix + item.text))
} else {
diff --git a/choose/command.go b/choose/command.go
index 3c93221..7407147 100644
--- a/choose/command.go
+++ b/choose/command.go
@@ -112,6 +112,8 @@ func (o Options) Run() error {
itemStyle: o.ItemStyle.ToLipgloss(),
selectedItemStyle: o.SelectedItemStyle.ToLipgloss(),
numSelected: currentSelected,
+ hasTimeout: o.Timeout > 0,
+ timeout: o.Timeout,
}, tea.WithOutput(os.Stderr)).Run()
if err != nil {
diff --git a/choose/options.go b/choose/options.go
index 064718c..52e3a50 100644
--- a/choose/options.go
+++ b/choose/options.go
@@ -1,23 +1,27 @@
package choose
-import "github.com/charmbracelet/gum/style"
+import (
+ "time"
+
+ "github.com/charmbracelet/gum/style"
+)
// 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"`
- Ordered bool `help:"Maintain the order of the selected options" env:"GUM_CHOOSE_ORDERED"`
- 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"`
- Header string `help:"Header value" default:"" env:"GUM_CHOOSE_HEADER"`
- 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_"`
- HeaderStyle style.Styles `embed:"" prefix:"header." set:"defaultForeground=240" envprefix:"GUM_CHOOSE_HEADER_"`
- ItemStyle style.Styles `embed:"" prefix:"item." hidden:"" envprefix:"GUM_CHOOSE_ITEM_"`
- SelectedItemStyle style.Styles `embed:"" prefix:"selected." set:"defaultForeground=212" envprefix:"GUM_CHOOSE_SELECTED_"`
+ 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"`
+ Ordered bool `help:"Maintain the order of the selected options" env:"GUM_CHOOSE_ORDERED"`
+ 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"`
+ Header string `help:"Header value" default:"" env:"GUM_CHOOSE_HEADER"`
+ 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_"`
+ HeaderStyle style.Styles `embed:"" prefix:"header." set:"defaultForeground=240" envprefix:"GUM_CHOOSE_HEADER_"`
+ 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 choose returns selected element" default:"0" env:"GUM_CCHOOSE_TIMEOUT"` // including timeout command options [Timeout,...]
}