From bf2d13df663671aee17d461155f8b4307b35c206 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Thu, 23 Apr 2020 12:06:08 -0400 Subject: [PATCH] Rename `input` to `textinput` + DefaultModel is now NewModel --- examples/{inputs => textinputs}/main.go | 28 +++++++++++++-------- pager/pager.go | 2 +- input/input.go => textinput/textinput.go | 31 +++++++++++++++++------- 3 files changed, 41 insertions(+), 20 deletions(-) rename examples/{inputs => textinputs}/main.go (82%) rename input/input.go => textinput/textinput.go (83%) diff --git a/examples/inputs/main.go b/examples/textinputs/main.go similarity index 82% rename from examples/inputs/main.go rename to examples/textinputs/main.go index 9010ab0..37becac 100644 --- a/examples/inputs/main.go +++ b/examples/textinputs/main.go @@ -5,7 +5,7 @@ import ( "os" "github.com/charmbracelet/tea" - "github.com/charmbracelet/teaparty/input" + input "github.com/charmbracelet/teaparty/textinput" te "github.com/muesli/termenv" ) @@ -39,17 +39,17 @@ type Model struct { } func initialize() (tea.Model, tea.Cmd) { - name := input.DefaultModel() + name := input.NewModel() name.Placeholder = "Name" name.Focus() name.Prompt = focusedPrompt name.TextColor = focusedText - nickName := input.DefaultModel() + nickName := input.NewModel() nickName.Placeholder = "Nickname" nickName.Prompt = blurredPrompt - email := input.DefaultModel() + email := input.NewModel() email.Placeholder = "Email" email.Prompt = blurredPrompt @@ -134,22 +134,30 @@ func update(msg tea.Msg, model tea.Model) (tea.Model, tea.Cmd) { return m, nil default: - m.nameInput, _ = input.Update(msg, m.nameInput) - m.nickNameInput, _ = input.Update(msg, m.nickNameInput) - m.emailInput, _ = input.Update(msg, m.emailInput) + // Handle character input + m = updateInputs(msg, m) return m, nil } default: - m.nameInput, _ = input.Update(msg, m.nameInput) - m.nickNameInput, _ = input.Update(msg, m.nickNameInput) - m.emailInput, _ = input.Update(msg, m.emailInput) + // Handle blinks + m = updateInputs(msg, m) return m, nil } } +func updateInputs(msg tea.Msg, m Model) Model { + m.nameInput, _ = input.Update(msg, m.nameInput) + m.nickNameInput, _ = input.Update(msg, m.nickNameInput) + m.emailInput, _ = input.Update(msg, m.emailInput) + return m +} + func subscriptions(model tea.Model) tea.Subs { return tea.Subs{ + // It's a little hacky, but we're using the subscription from one + // input element to handle the blinking for all elements. It doesn't + // have to be this way, we're just feeling a bit lazy at the moment. "blink": func(model tea.Model) tea.Msg { m, _ := model.(Model) return input.Blink(m.nameInput) diff --git a/pager/pager.go b/pager/pager.go index 6cf8b94..79a8222 100644 --- a/pager/pager.go +++ b/pager/pager.go @@ -149,7 +149,7 @@ func Update(msg tea.Msg, m Model) (Model, tea.Cmd) { func View(model tea.Model) string { m, ok := model.(Model) if !ok { - return "" + return "could not perform assertion on model" } switch m.Type { case Dots: diff --git a/input/input.go b/textinput/textinput.go similarity index 83% rename from input/input.go rename to textinput/textinput.go index 23acbba..fd92eb5 100644 --- a/input/input.go +++ b/textinput/textinput.go @@ -1,4 +1,4 @@ -package input +package textinput import ( "errors" @@ -9,12 +9,16 @@ import ( ) var ( - // Helper for returning colors + // color is a helper for returning colors color func(s string) termenv.Color = termenv.ColorProfile().Color ) +// ErrMsg indicates there's been an error. We don't handle errors in the this +// package; we're expecting errors to be handle in the program that implements +// this text input. type ErrMsg error +// Model is the Tea model for this text input element type Model struct { Err error Prompt string @@ -73,9 +77,11 @@ func (m *Model) colorPlaceholder(s string) string { String() } +// CursorBlinkMsg is sent when the cursor should alternate it's blinking state type CursorBlinkMsg struct{} -func DefaultModel() Model { +// NewModel creates a new model with default settings +func NewModel() Model { return Model{ Prompt: "> ", Value: "", @@ -84,6 +90,7 @@ func DefaultModel() Model { TextColor: "", PlaceholderColor: "240", CursorColor: "", + CharLimit: 0, focus: false, blink: true, @@ -91,6 +98,7 @@ func DefaultModel() Model { } } +// Update is the Tea update loop func Update(msg tea.Msg, m Model) (Model, tea.Cmd) { if !m.focus { m.blink = true @@ -123,7 +131,7 @@ func Update(msg tea.Msg, m Model) (Model, tea.Cmd) { fallthrough case tea.KeyCtrlB: // ^B, back one charcter fallthrough - case tea.KeyCtrlA: // ^A, beginning + case tea.KeyCtrlA: // ^A, go to beginning m.pos = 0 return m, nil case tea.KeyCtrlD: // ^D, delete char under cursor @@ -131,7 +139,7 @@ func Update(msg tea.Msg, m Model) (Model, tea.Cmd) { m.Value = m.Value[:m.pos] + m.Value[m.pos+1:] } return m, nil - case tea.KeyCtrlE: // ^E, end + case tea.KeyCtrlE: // ^E, go to end m.pos = len(m.Value) return m, nil case tea.KeyCtrlK: // ^K, kill text after cursor @@ -165,8 +173,12 @@ func Update(msg tea.Msg, m Model) (Model, tea.Cmd) { } } +// View renders the textinput in its current state func View(model tea.Model) string { - m, _ := model.(Model) + m, ok := model.(Model) + if !ok { + return "could not perform assertion on model" + } // Placeholder text if m.Value == "" && m.Placeholder != "" { @@ -184,6 +196,7 @@ func View(model tea.Model) string { return m.Prompt + v } +// placeholderView func placeholderView(m Model) string { var ( v string @@ -206,19 +219,19 @@ func placeholderView(m Model) string { return m.Prompt + v } -// Style the cursor +// cursorView style the cursor func cursorView(s string, m Model) string { if m.blink { return s } - return termenv.String(s). Foreground(color(m.CursorColor)). Reverse(). String() } -// Subscription +// Blink is the subscription that lets us know when to alternate the blinking +// of the cursor. func Blink(model tea.Model) tea.Msg { m, ok := model.(Model) if !ok {