From 4a560b19534839674fd92bcbad0aa4ee7158b926 Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Thu, 28 Mar 2024 16:29:08 -0400 Subject: [PATCH] feat: huh for gum input (#524) --- input/command.go | 63 +++++++++++++++++++-------------------- input/input.go | 77 ------------------------------------------------ 2 files changed, 31 insertions(+), 109 deletions(-) delete mode 100644 input/input.go diff --git a/input/command.go b/input/command.go index d37deb5..60a9743 100644 --- a/input/command.go +++ b/input/command.go @@ -2,13 +2,11 @@ package input import ( "fmt" - "os" "github.com/charmbracelet/bubbles/textinput" - tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/huh" + "github.com/charmbracelet/lipgloss" - "github.com/charmbracelet/gum/cursor" - "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/stdin" ) @@ -22,40 +20,41 @@ func (o Options) Run() error { i.SetValue(in) } - 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 + theme := huh.ThemeCharm() + theme.Focused.Base = lipgloss.NewStyle() + theme.Focused.TextInput.Cursor = o.CursorStyle.ToLipgloss() + theme.Focused.TextInput.Placeholder = o.PlaceholderStyle.ToLipgloss() + theme.Focused.TextInput.Prompt = o.PromptStyle.ToLipgloss() + theme.Focused.Title = o.HeaderStyle.ToLipgloss() + + var value string + var echoMode huh.EchoMode if o.Password { - i.EchoMode = textinput.EchoPassword - i.EchoCharacter = '•' + echoMode = huh.EchoModePassword + } else { + echoMode = huh.EchoModeNormal } - 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() + err := huh.NewForm( + huh.NewGroup( + huh.NewInput(). + Prompt(o.Prompt). + Placeholder(o.Placeholder). + CharLimit(o.CharLimit). + EchoMode(echoMode). + Title(o.Header). + Value(&value), + ), + ). + WithShowHelp(false). + WithTheme(theme). + Run() + if err != nil { - return fmt.Errorf("failed to run input: %w", err) - } - m := tm.(model) - - if m.aborted { - return exit.ErrAborted + return err } - fmt.Println(m.textinput.Value()) + fmt.Println(value) return nil } diff --git a/input/input.go b/input/input.go deleted file mode 100644 index 9db2306..0000000 --- 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 -}