Reset blink timer when moving the cursor

This commit is contained in:
Christian Rocha 2020-10-24 17:18:43 -04:00
parent 7d1c04164e
commit 1b530b293c
No known key found for this signature in database
GPG Key ID: D6CC7A16E5878018

View File

@ -13,6 +13,9 @@ import (
const defaultBlinkSpeed = time.Millisecond * 530 const defaultBlinkSpeed = time.Millisecond * 530
// EchoMode sets the input behavior of the text input field.
type EchoMode int
const ( const (
// EchoNormal displays text as is. This is the default behavior. // EchoNormal displays text as is. This is the default behavior.
EchoNormal EchoMode = iota EchoNormal EchoMode = iota
@ -28,31 +31,27 @@ const (
// EchoOnEdit // EchoOnEdit
) )
// EchoMode sets the input behavior of the text input field. // color is a helper for returning colors.
type EchoMode int var color func(s string) termenv.Color = termenv.ColorProfile().Color
var ( // blinkMsg is used to blink the cursor.
// color is a helper for returning colors. type blinkMsg struct{}
color func(s string) termenv.Color = termenv.ColorProfile().Color
)
// Model is the Bubble Tea model for this text input element. // Model is the Bubble Tea model for this text input element.
type Model struct { type Model struct {
Err error Err error
Prompt string // General settings
Placeholder string Prompt string
Placeholder string
Cursor string Cursor string
BlinkSpeed time.Duration BlinkSpeed time.Duration
TextColor string TextColor string
BackgroundColor string BackgroundColor string
PlaceholderColor string PlaceholderColor string
CursorColor string CursorColor string
EchoMode EchoMode
EchoMode EchoMode EchoCharacter rune
EchoCharacter rune
// CharLimit is the maximum amount of characters this input element will // CharLimit is the maximum amount of characters this input element will
// accept. If 0 or less, there's no limit. // accept. If 0 or less, there's no limit.
@ -80,6 +79,9 @@ type Model struct {
// overflowing. // overflowing.
offset int offset int
offsetRight int offsetRight int
// Used to manage cursor blink
blinkTimer *time.Timer
} }
// SetValue sets the value of the text input. // SetValue sets the value of the text input.
@ -105,8 +107,16 @@ func (m Model) Value() string {
// out of bounds the cursor will be moved to the start or end accordingly. // out of bounds the cursor will be moved to the start or end accordingly.
func (m *Model) SetCursor(pos int) { func (m *Model) SetCursor(pos int) {
m.pos = clamp(pos, 0, len(m.value)) m.pos = clamp(pos, 0, len(m.value))
m.blink = false
m.handleOverflow() m.handleOverflow()
m.blink = false
if m.blinkTimer != nil {
// Reset blink timer
if !m.blinkTimer.Stop() {
<-m.blinkTimer.C
}
m.blinkTimer.Reset(m.BlinkSpeed)
}
} }
// CursorStart moves the cursor to the start of the field. // CursorStart moves the cursor to the start of the field.
@ -381,24 +391,17 @@ func (m Model) echoTransform(v string) string {
} }
} }
// BlinkMsg is sent when the cursor should alternate it's blinking state.
type BlinkMsg struct{}
// NewModel creates a new model with default settings. // NewModel creates a new model with default settings.
func NewModel() Model { func NewModel() Model {
return Model{ return Model{
Prompt: "> ", Prompt: "> ",
Placeholder: "", Placeholder: "",
BlinkSpeed: defaultBlinkSpeed,
BlinkSpeed: defaultBlinkSpeed,
TextColor: "", TextColor: "",
PlaceholderColor: "240", PlaceholderColor: "240",
CursorColor: "", CursorColor: "",
EchoCharacter: '*',
EchoCharacter: '*', CharLimit: 0,
CharLimit: 0,
value: nil, value: nil,
focus: false, focus: false,
@ -407,7 +410,7 @@ func NewModel() Model {
} }
} }
// Update is the Tea update loop. // Update is the Bubble Tea update loop.
func Update(msg tea.Msg, m Model) (Model, tea.Cmd) { func Update(msg tea.Msg, m Model) (Model, tea.Cmd) {
if !m.focus { if !m.focus {
m.blink = true m.blink = true
@ -490,9 +493,11 @@ func Update(msg tea.Msg, m Model) (Model, tea.Cmd) {
} }
} }
case BlinkMsg: case blinkMsg:
m.blink = !m.blink m.blink = !m.blink
return m, Blink(m) t, cmd := m.blinkCmd()
m.blinkTimer = t
return m, cmd
} }
m.handleOverflow() m.handleOverflow()
@ -574,10 +579,16 @@ func cursorView(s string, m Model) string {
} }
// Blink is a command used to time the cursor blinking. // Blink is a command used to time the cursor blinking.
func Blink(model Model) tea.Cmd { func Blink() tea.Msg {
return func() tea.Msg { return blinkMsg{}
time.Sleep(model.BlinkSpeed) }
return BlinkMsg{}
// blinkCmd is an internal command used to manage cursor blinking
func (m Model) blinkCmd() (*time.Timer, tea.Cmd) {
t := time.NewTimer(m.BlinkSpeed)
return t, func() tea.Msg {
<-t.C
return blinkMsg{}
} }
} }