From 65087b31eaedd7531e14347e320209bbe70908d0 Mon Sep 17 00:00:00 2001 From: Dieter Eickstaedt Date: Mon, 21 Nov 2022 15:09:10 +0100 Subject: [PATCH] bugfix: proper handling of timeouts and default selections --- confirm/command.go | 29 ++++++++++++++--------------- confirm/confirm.go | 41 ++++++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/confirm/command.go b/confirm/command.go index c85e20b..60f9fea 100644 --- a/confirm/command.go +++ b/confirm/command.go @@ -19,32 +19,32 @@ func (o Options) Run() error { var ( options []string selectedOption selectionType + theDefault bool ) // set options options = append(options, o.Affirmative) - if o.Negative != "" { - options = append(options, o.Negative) - } - if o.Canceled != "" && o.WithCancel { - options = append(options, o.Canceled) - } + options = append(options, o.Negative) + options = append(options, o.Canceled) // what is default + theDefault = o.Default if !o.Default && o.Negative != "" { selectedOption = Negative } else { selectedOption = Confirmed + theDefault = true } m, err := tea.NewProgram(model{ - options: options, - selectedOption: selectedOption, - timeout: o.Timeout, - hasTimeout: o.Timeout > 0, - prompt: o.Prompt, - selectedStyle: o.SelectedStyle.ToLipgloss(), - unselectedStyle: o.UnselectedStyle.ToLipgloss(), - promptStyle: o.PromptStyle.ToLipgloss(), + options: options, + selectedOption: selectedOption, + timeout: o.Timeout, + hasTimeout: o.Timeout > 0, + prompt: o.Prompt, + defaultSelection: theDefault, + selectedStyle: o.SelectedStyle.ToLipgloss(), + unselectedStyle: o.UnselectedStyle.ToLipgloss(), + promptStyle: o.PromptStyle.ToLipgloss(), }, tea.WithOutput(os.Stderr)).Run() if err != nil { @@ -57,7 +57,6 @@ func (o Options) Run() error { case Negative: os.Exit(1) case Cancel: - os.Exit(CtrlC) } diff --git a/confirm/confirm.go b/confirm/confirm.go index 56f3e41..e32af4e 100644 --- a/confirm/confirm.go +++ b/confirm/confirm.go @@ -34,7 +34,8 @@ type model struct { hasTimeout bool timeout time.Duration - selectedOption selectionType + selectedOption selectionType + defaultSelection bool // styles promptStyle lipgloss.Style @@ -60,16 +61,26 @@ func (m model) Init() tea.Cmd { } func (m *model) NextOption() { - m.selectedOption++ - if (int)(m.selectedOption) >= len(m.options) { - m.selectedOption = 0 + for { + m.selectedOption++ + if (int)(m.selectedOption) >= len(m.options) { + m.selectedOption = 0 + } + if m.options[m.selectedOption] != "" { + break + } } } func (m *model) PrevOption() { - m.selectedOption-- - if (int)(m.selectedOption) < 0 { - m.selectedOption = selectionType(len(m.options) - 1) + for { + m.selectedOption-- + if (int)(m.selectedOption) < 0 { + m.selectedOption = selectionType(len(m.options) - 1) + } + if m.options[m.selectedOption] != "" { + break + } } } @@ -104,7 +115,11 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case tickMsg: if m.timeout <= 0 { m.quitting = true - m.selectedOption = Negative + if !m.defaultSelection && m.options[Negative] != "" { + m.selectedOption = Negative + } else { + m.selectedOption = Confirmed + } return m, tea.Quit } m.timeout -= tickInterval @@ -126,10 +141,18 @@ func (m model) View() string { var renderedOptions []string for i, value := range m.options { + if m.options[i] == "" { + continue + } + if m.hasTimeout { + if (m.defaultSelection && i == (int)(Confirmed)) || (!m.defaultSelection && i == (int)(Negative)) { + value = value + timeout + } + } if (int)(m.selectedOption) == i { renderedOptions = append(renderedOptions, m.selectedStyle.Render(value)) } else { - renderedOptions = append(renderedOptions, m.unselectedStyle.Render(value+timeout)) + renderedOptions = append(renderedOptions, m.unselectedStyle.Render(value)) } }