feat: huh gum write (#525)

This commit is contained in:
Maas Lalani 2024-03-29 07:19:03 -04:00 committed by GitHub
parent 2f0ea96504
commit 4d5d53169e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 31 additions and 112 deletions

View file

@ -2,15 +2,10 @@ package write
import (
"fmt"
"os"
"strings"
"github.com/charmbracelet/bubbles/textarea"
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"
)
// Run provides a shell script interface for the text area bubble.
@ -21,48 +16,33 @@ func (o Options) Run() error {
o.Value = strings.ReplaceAll(in, "\r", "")
}
a := textarea.New()
a.Focus()
var value = o.Value
a.Prompt = o.Prompt
a.Placeholder = o.Placeholder
a.ShowLineNumbers = o.ShowLineNumbers
a.CharLimit = o.CharLimit
theme := huh.ThemeCharm()
theme.Focused.Base = o.BaseStyle.ToLipgloss()
theme.Focused.TextInput.Cursor = o.CursorStyle.ToLipgloss()
theme.Focused.Title = o.HeaderStyle.ToLipgloss()
theme.Focused.TextInput.Placeholder = o.PlaceholderStyle.ToLipgloss()
theme.Focused.TextInput.Prompt = o.PromptStyle.ToLipgloss()
style := textarea.Style{
Base: o.BaseStyle.ToLipgloss(),
Placeholder: o.PlaceholderStyle.ToLipgloss(),
CursorLine: o.CursorLineStyle.ToLipgloss(),
CursorLineNumber: o.CursorLineNumberStyle.ToLipgloss(),
EndOfBuffer: o.EndOfBufferStyle.ToLipgloss(),
LineNumber: o.LineNumberStyle.ToLipgloss(),
Prompt: o.PromptStyle.ToLipgloss(),
}
err := huh.NewForm(
huh.NewGroup(
huh.NewText().
Title(o.Header).
Placeholder(o.Placeholder).
CharLimit(o.CharLimit).
ShowLineNumbers(o.ShowLineNumbers).
Value(&value),
),
).
WithWidth(o.Width).
WithHeight(o.Height).
WithShowHelp(false).Run()
a.BlurredStyle = style
a.FocusedStyle = style
a.Cursor.Style = o.CursorStyle.ToLipgloss()
a.Cursor.SetMode(cursor.Modes[o.CursorMode])
a.SetWidth(o.Width)
a.SetHeight(o.Height)
a.SetValue(o.Value)
p := tea.NewProgram(model{
textarea: a,
header: o.Header,
headerStyle: o.HeaderStyle.ToLipgloss(),
autoWidth: o.Width < 1,
}, tea.WithOutput(os.Stderr))
tm, err := p.Run()
if err != nil {
return fmt.Errorf("failed to run write: %w", err)
}
m := tm.(model)
if m.aborted {
return exit.ErrAborted
return err
}
fmt.Println(m.textarea.Value())
fmt.Println(value)
return nil
}

View file

@ -15,13 +15,14 @@ type Options struct {
CharLimit int `help:"Maximum value length (0 for no limit)" default:"400"`
CursorMode string `prefix:"cursor." name:"mode" help:"Cursor mode" default:"blink" enum:"blink,hide,static" env:"GUM_WRITE_CURSOR_MODE"`
BaseStyle style.Styles `embed:"" prefix:"base." envprefix:"GUM_WRITE_BASE_"`
CursorLineNumberStyle style.Styles `embed:"" prefix:"cursor-line-number." set:"defaultForeground=7" envprefix:"GUM_WRITE_CURSOR_LINE_NUMBER_"`
CursorLineStyle style.Styles `embed:"" prefix:"cursor-line." envprefix:"GUM_WRITE_CURSOR_LINE_"`
CursorStyle style.Styles `embed:"" prefix:"cursor." set:"defaultForeground=212" envprefix:"GUM_WRITE_CURSOR_"`
BaseStyle style.Styles `embed:"" prefix:"base." envprefix:"GUM_WRITE_BASE_"`
CursorStyle style.Styles `embed:"" prefix:"cursor." set:"defaultForeground=212" envprefix:"GUM_WRITE_CURSOR_"`
HeaderStyle style.Styles `embed:"" prefix:"header." set:"defaultForeground=240" envprefix:"GUM_WRITE_HEADER_"`
PlaceholderStyle style.Styles `embed:"" prefix:"placeholder." set:"defaultForeground=240" envprefix:"GUM_WRITE_PLACEHOLDER_"`
PromptStyle style.Styles `embed:"" prefix:"prompt." set:"defaultForeground=7" envprefix:"GUM_WRITE_PROMPT_"`
EndOfBufferStyle style.Styles `embed:"" prefix:"end-of-buffer." set:"defaultForeground=0" envprefix:"GUM_WRITE_END_OF_BUFFER_"`
LineNumberStyle style.Styles `embed:"" prefix:"line-number." set:"defaultForeground=7" envprefix:"GUM_WRITE_LINE_NUMBER_"`
HeaderStyle style.Styles `embed:"" prefix:"header." set:"defaultForeground=240" envprefix:"GUM_WRITE_HEADER_"`
PlaceholderStyle style.Styles `embed:"" prefix:"placeholder." set:"defaultForeground=240" envprefix:"GUM_WRITE_PLACEHOLDER_"`
PromptStyle style.Styles `embed:"" prefix:"prompt." set:"defaultForeground=7" envprefix:"GUM_WRITE_PROMPT_"`
CursorLineNumberStyle style.Styles `embed:"" prefix:"cursor-line-number." set:"defaultForeground=7" envprefix:"GUM_WRITE_CURSOR_LINE_NUMBER_"`
CursorLineStyle style.Styles `embed:"" prefix:"cursor-line." envprefix:"GUM_WRITE_CURSOR_LINE_"`
}

View file

@ -1,62 +0,0 @@
// Package write provides a shell script interface for the text area bubble.
// https://github.com/charmbracelet/bubbles/tree/master/textarea
//
// It can be used to ask the user to write some long form of text (multi-line)
// input. The text the user entered will be sent to stdout.
// Text entry is completed with CTRL+D and aborted with CTRL+C or Escape.
//
// $ gum write > output.text
package write
import (
"github.com/charmbracelet/bubbles/textarea"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
type model struct {
autoWidth bool
aborted bool
header string
headerStyle lipgloss.Style
quitting bool
textarea textarea.Model
}
func (m model) Init() tea.Cmd { return textarea.Blink }
func (m model) View() string {
if m.quitting {
return ""
}
// Display the header above the text area if it is not empty.
if m.header != "" {
header := m.headerStyle.Render(m.header)
return lipgloss.JoinVertical(lipgloss.Left, header, m.textarea.View())
}
return m.textarea.View()
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
if m.autoWidth {
m.textarea.SetWidth(msg.Width)
}
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c":
m.aborted = true
m.quitting = true
return m, tea.Quit
case "ctrl+d", "esc":
m.quitting = true
return m, tea.Quit
}
}
var cmd tea.Cmd
m.textarea, cmd = m.textarea.Update(msg)
return m, cmd
}