mirror of
https://github.com/charmbracelet/gum.git
synced 2024-10-26 07:10:39 +03:00
feat: huh gum write (#525)
This commit is contained in:
parent
2f0ea96504
commit
4d5d53169e
@ -2,15 +2,10 @@ package write
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strings"
|
"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/gum/internal/stdin"
|
||||||
|
"github.com/charmbracelet/huh"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Run provides a shell script interface for the text area bubble.
|
// 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", "")
|
o.Value = strings.ReplaceAll(in, "\r", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
a := textarea.New()
|
var value = o.Value
|
||||||
a.Focus()
|
|
||||||
|
|
||||||
a.Prompt = o.Prompt
|
theme := huh.ThemeCharm()
|
||||||
a.Placeholder = o.Placeholder
|
theme.Focused.Base = o.BaseStyle.ToLipgloss()
|
||||||
a.ShowLineNumbers = o.ShowLineNumbers
|
theme.Focused.TextInput.Cursor = o.CursorStyle.ToLipgloss()
|
||||||
a.CharLimit = o.CharLimit
|
theme.Focused.Title = o.HeaderStyle.ToLipgloss()
|
||||||
|
theme.Focused.TextInput.Placeholder = o.PlaceholderStyle.ToLipgloss()
|
||||||
|
theme.Focused.TextInput.Prompt = o.PromptStyle.ToLipgloss()
|
||||||
|
|
||||||
style := textarea.Style{
|
err := huh.NewForm(
|
||||||
Base: o.BaseStyle.ToLipgloss(),
|
huh.NewGroup(
|
||||||
Placeholder: o.PlaceholderStyle.ToLipgloss(),
|
huh.NewText().
|
||||||
CursorLine: o.CursorLineStyle.ToLipgloss(),
|
Title(o.Header).
|
||||||
CursorLineNumber: o.CursorLineNumberStyle.ToLipgloss(),
|
Placeholder(o.Placeholder).
|
||||||
EndOfBuffer: o.EndOfBufferStyle.ToLipgloss(),
|
CharLimit(o.CharLimit).
|
||||||
LineNumber: o.LineNumberStyle.ToLipgloss(),
|
ShowLineNumbers(o.ShowLineNumbers).
|
||||||
Prompt: o.PromptStyle.ToLipgloss(),
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to run write: %w", err)
|
return err
|
||||||
}
|
|
||||||
m := tm.(model)
|
|
||||||
if m.aborted {
|
|
||||||
return exit.ErrAborted
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(m.textarea.Value())
|
fmt.Println(value)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,14 @@ type Options struct {
|
|||||||
CharLimit int `help:"Maximum value length (0 for no limit)" default:"400"`
|
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"`
|
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_"`
|
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_"`
|
CursorStyle style.Styles `embed:"" prefix:"cursor." set:"defaultForeground=212" envprefix:"GUM_WRITE_CURSOR_"`
|
||||||
CursorLineStyle style.Styles `embed:"" prefix:"cursor-line." envprefix:"GUM_WRITE_CURSOR_LINE_"`
|
HeaderStyle style.Styles `embed:"" prefix:"header." set:"defaultForeground=240" envprefix:"GUM_WRITE_HEADER_"`
|
||||||
CursorStyle style.Styles `embed:"" prefix:"cursor." set:"defaultForeground=212" envprefix:"GUM_WRITE_CURSOR_"`
|
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_"`
|
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_"`
|
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_"`
|
CursorLineNumberStyle style.Styles `embed:"" prefix:"cursor-line-number." set:"defaultForeground=7" envprefix:"GUM_WRITE_CURSOR_LINE_NUMBER_"`
|
||||||
PlaceholderStyle style.Styles `embed:"" prefix:"placeholder." set:"defaultForeground=240" envprefix:"GUM_WRITE_PLACEHOLDER_"`
|
CursorLineStyle style.Styles `embed:"" prefix:"cursor-line." envprefix:"GUM_WRITE_CURSOR_LINE_"`
|
||||||
PromptStyle style.Styles `embed:"" prefix:"prompt." set:"defaultForeground=7" envprefix:"GUM_WRITE_PROMPT_"`
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user