mirror of
https://github.com/charmbracelet/gum
synced 2024-05-18 22:26:42 +02:00
feat: huh for gum input (#524)
This commit is contained in:
parent
3a717104a9
commit
4a560b1953
|
@ -2,13 +2,11 @@ package input
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/textinput"
|
"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"
|
"github.com/charmbracelet/gum/internal/stdin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,40 +20,41 @@ func (o Options) Run() error {
|
||||||
i.SetValue(in)
|
i.SetValue(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
i.Focus()
|
theme := huh.ThemeCharm()
|
||||||
i.Prompt = o.Prompt
|
theme.Focused.Base = lipgloss.NewStyle()
|
||||||
i.Placeholder = o.Placeholder
|
theme.Focused.TextInput.Cursor = o.CursorStyle.ToLipgloss()
|
||||||
i.Width = o.Width
|
theme.Focused.TextInput.Placeholder = o.PlaceholderStyle.ToLipgloss()
|
||||||
i.PromptStyle = o.PromptStyle.ToLipgloss()
|
theme.Focused.TextInput.Prompt = o.PromptStyle.ToLipgloss()
|
||||||
i.PlaceholderStyle = o.PlaceholderStyle.ToLipgloss()
|
theme.Focused.Title = o.HeaderStyle.ToLipgloss()
|
||||||
i.Cursor.Style = o.CursorStyle.ToLipgloss()
|
|
||||||
i.Cursor.SetMode(cursor.Modes[o.CursorMode])
|
var value string
|
||||||
i.CharLimit = o.CharLimit
|
var echoMode huh.EchoMode
|
||||||
|
|
||||||
if o.Password {
|
if o.Password {
|
||||||
i.EchoMode = textinput.EchoPassword
|
echoMode = huh.EchoModePassword
|
||||||
i.EchoCharacter = '•'
|
} else {
|
||||||
|
echoMode = huh.EchoModeNormal
|
||||||
}
|
}
|
||||||
|
|
||||||
p := tea.NewProgram(model{
|
err := huh.NewForm(
|
||||||
textinput: i,
|
huh.NewGroup(
|
||||||
aborted: false,
|
huh.NewInput().
|
||||||
header: o.Header,
|
Prompt(o.Prompt).
|
||||||
headerStyle: o.HeaderStyle.ToLipgloss(),
|
Placeholder(o.Placeholder).
|
||||||
timeout: o.Timeout,
|
CharLimit(o.CharLimit).
|
||||||
hasTimeout: o.Timeout > 0,
|
EchoMode(echoMode).
|
||||||
autoWidth: o.Width < 1,
|
Title(o.Header).
|
||||||
}, tea.WithOutput(os.Stderr))
|
Value(&value),
|
||||||
tm, err := p.Run()
|
),
|
||||||
|
).
|
||||||
|
WithShowHelp(false).
|
||||||
|
WithTheme(theme).
|
||||||
|
Run()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to run input: %w", err)
|
return err
|
||||||
}
|
|
||||||
m := tm.(model)
|
|
||||||
|
|
||||||
if m.aborted {
|
|
||||||
return exit.ErrAborted
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(m.textinput.Value())
|
fmt.Println(value)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
Loading…
Reference in a new issue