From 7bc85c91bc7a726740dfc8c11d58d098ba25716a Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Thu, 25 Jan 2024 17:04:02 -0500 Subject: [PATCH] feat: use huh for gum input --- input/command.go | 71 ++++++++++++++++++-------------------------- input/input.go | 77 ------------------------------------------------ input/options.go | 6 ++-- 3 files changed, 32 insertions(+), 122 deletions(-) delete mode 100644 input/input.go diff --git a/input/command.go b/input/command.go index d37deb5d1..c30ba308b 100644 --- a/input/command.go +++ b/input/command.go @@ -2,60 +2,47 @@ package input import ( "fmt" - "os" - "github.com/charmbracelet/bubbles/textinput" - tea "github.com/charmbracelet/bubbletea" - - "github.com/charmbracelet/gum/cursor" - "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/stdin" + "github.com/charmbracelet/huh" + "github.com/charmbracelet/lipgloss" ) // Run provides a shell script interface for the text input bubble. // https://github.com/charmbracelet/bubbles/textinput func (o Options) Run() error { - i := textinput.New() - if o.Value != "" { - i.SetValue(o.Value) - } else if in, _ := stdin.Read(); in != "" { - i.SetValue(in) + if o.Value == "" { + o.Value, _ = stdin.Read() } - i.Focus() - i.Prompt = o.Prompt - i.Placeholder = o.Placeholder - i.Width = o.Width - i.PromptStyle = o.PromptStyle.ToLipgloss() - i.PlaceholderStyle = o.PlaceholderStyle.ToLipgloss() - i.Cursor.Style = o.CursorStyle.ToLipgloss() - i.Cursor.SetMode(cursor.Modes[o.CursorMode]) - i.CharLimit = o.CharLimit - - if o.Password { - i.EchoMode = textinput.EchoPassword - i.EchoCharacter = '•' - } - - p := tea.NewProgram(model{ - textinput: i, - aborted: false, - header: o.Header, - headerStyle: o.HeaderStyle.ToLipgloss(), - timeout: o.Timeout, - hasTimeout: o.Timeout > 0, - autoWidth: o.Width < 1, - }, tea.WithOutput(os.Stderr)) - tm, err := p.Run() + theme := huh.ThemeCharm() + theme.Focused.Base.Border(lipgloss.Border{}) + theme.Focused.Title = o.HeaderStyle.ToLipgloss() + theme.Focused.TextInput.Prompt = o.PromptStyle.ToLipgloss() + theme.Focused.TextInput.Placeholder = o.PlaceholderStyle.ToLipgloss() + theme.Focused.TextInput.Cursor = o.CursorStyle.ToLipgloss() + + err := huh.NewForm( + huh.NewGroup( + huh.NewInput(). + Password(o.Password). + Title(o.Header). + Prompt(o.Prompt). + CharLimit(o.CharLimit). + Placeholder(o.Placeholder). + Value(&o.Value), + ), + ). + WithWidth(o.Width). + WithShowHelp(false). + WithTheme(theme). + Run() if err != nil { - return fmt.Errorf("failed to run input: %w", err) + return err } - m := tm.(model) - if m.aborted { - return exit.ErrAborted + if o.Value != "" { + fmt.Println(o.Value) } - - fmt.Println(m.textinput.Value()) return nil } diff --git a/input/input.go b/input/input.go deleted file mode 100644 index 9db2306bc..000000000 --- a/input/input.go +++ /dev/null @@ -1,77 +0,0 @@ -// Package input provides a shell script interface for the text input bubble. -// https://github.com/charmbracelet/bubbles/tree/master/textinput -// -// It can be used to prompt the user for some input. The text the user entered -// will be sent to stdout. -// -// $ gum input --placeholder "What's your favorite gum?" > answer.text -package input - -import ( - "time" - - "github.com/charmbracelet/bubbles/textinput" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/gum/timeout" - "github.com/charmbracelet/lipgloss" -) - -type model struct { - autoWidth bool - header string - headerStyle lipgloss.Style - textinput textinput.Model - quitting bool - aborted bool - timeout time.Duration - hasTimeout bool -} - -func (m model) Init() tea.Cmd { - return tea.Batch( - textinput.Blink, - timeout.Init(m.timeout, nil), - ) -} -func (m model) View() string { - if m.quitting { - return "" - } - if m.header != "" { - header := m.headerStyle.Render(m.header) - return lipgloss.JoinVertical(lipgloss.Left, header, m.textinput.View()) - } - - return m.textinput.View() -} - -func (m model) Update(msg tea.Msg) (tea.Model, 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.autoWidth { - m.textinput.Width = msg.Width - lipgloss.Width(m.textinput.Prompt) - 1 - } - case tea.KeyMsg: - switch msg.String() { - case "ctrl+c", "esc": - m.quitting = true - m.aborted = true - return m, tea.Quit - case "enter": - m.quitting = true - return m, tea.Quit - } - } - - var cmd tea.Cmd - m.textinput, cmd = m.textinput.Update(msg) - return m, cmd -} diff --git a/input/options.go b/input/options.go index 7050059c4..cafe35bd9 100644 --- a/input/options.go +++ b/input/options.go @@ -10,15 +10,15 @@ import ( 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_"` + PromptStyle style.Styles `embed:"" prefix:"prompt." set:"defaultForeground=#F780E2" envprefix:"GUM_INPUT_PROMPT_"` PlaceholderStyle style.Styles `embed:"" prefix:"placeholder." set:"defaultForeground=240" envprefix:"GUM_INPUT_PLACEHOLDER_"` - CursorStyle style.Styles `embed:"" prefix:"cursor." set:"defaultForeground=212" envprefix:"GUM_INPUT_CURSOR_"` + CursorStyle style.Styles `embed:"" prefix:"cursor." set:"defaultForeground=#02BF87" envprefix:"GUM_INPUT_CURSOR_"` CursorMode string `prefix:"cursor." name:"mode" help:"Cursor mode" default:"blink" enum:"blink,hide,static" env:"GUM_INPUT_CURSOR_MODE"` 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 (0 for terminal 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_"` + HeaderStyle style.Styles `embed:"" prefix:"header." set:"defaultForeground=#7571F9" envprefix:"GUM_INPUT_HEADER_"` Timeout time.Duration `help:"Timeout until input aborts" default:"0" env:"GUM_INPUT_TIMEOUT"` }