chore!(cursor): improve naming around 'blinking'

This commit is contained in:
Christian Rocha
2025-05-26 09:15:38 -04:00
parent 0f113d10c4
commit e89dc94c85
4 changed files with 24 additions and 27 deletions
+14 -17
View File
@@ -73,10 +73,9 @@ type Model struct {
// unless [CursorMode] is not set to [CursorBlink]. // unless [CursorMode] is not set to [CursorBlink].
BlinkSpeed time.Duration BlinkSpeed time.Duration
// Blink is the state of the cursor blink. When true, the cursor is hidden. // IsBlinked is the state of the cursor blink. When true, the cursor is
// // hidden.
// TODO: rename to Blinking. IsBlinked bool
Blink bool
// char is the character under the cursor // char is the character under the cursor
char string char string
@@ -102,7 +101,7 @@ func New() Model {
return Model{ return Model{
id: nextID(), id: nextID(),
BlinkSpeed: defaultBlinkSpeed, BlinkSpeed: defaultBlinkSpeed,
Blink: true, IsBlinked: true,
mode: CursorBlink, mode: CursorBlink,
blinkCtx: &blinkCtx{ blinkCtx: &blinkCtx{
@@ -121,7 +120,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
return m, nil return m, nil
} }
cmd := m.BlinkCmd() cmd := m.Blink()
return m, cmd return m, cmd
case tea.FocusMsg: case tea.FocusMsg:
@@ -147,8 +146,8 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
var cmd tea.Cmd var cmd tea.Cmd
if m.mode == CursorBlink { if m.mode == CursorBlink {
m.Blink = !m.Blink m.IsBlinked = !m.IsBlinked
cmd = m.BlinkCmd() cmd = m.Blink()
} }
return m, cmd return m, cmd
@@ -173,17 +172,15 @@ func (m *Model) SetMode(mode Mode) tea.Cmd {
return nil return nil
} }
m.mode = mode m.mode = mode
m.Blink = m.mode == CursorHide || !m.focus m.IsBlinked = m.mode == CursorHide || !m.focus
if mode == CursorBlink { if mode == CursorBlink {
return Blink return Blink
} }
return nil return nil
} }
// BlinkCmd is a command used to manage cursor blinking. // Blink is a command used to manage cursor blinking.
// func (m *Model) Blink() tea.Cmd {
// TODO: Rename to Blink.
func (m *Model) BlinkCmd() tea.Cmd {
if m.mode != CursorBlink { if m.mode != CursorBlink {
return nil return nil
} }
@@ -216,10 +213,10 @@ func Blink() tea.Msg {
// Focus focuses the cursor to allow it to blink if desired. // Focus focuses the cursor to allow it to blink if desired.
func (m *Model) Focus() tea.Cmd { func (m *Model) Focus() tea.Cmd {
m.focus = true m.focus = true
m.Blink = m.mode == CursorHide // show the cursor unless we've explicitly hidden it m.IsBlinked = m.mode == CursorHide // show the cursor unless we've explicitly hidden it
if m.mode == CursorBlink && m.focus { if m.mode == CursorBlink && m.focus {
return m.BlinkCmd() return m.Blink()
} }
return nil return nil
} }
@@ -227,7 +224,7 @@ func (m *Model) Focus() tea.Cmd {
// Blur blurs the cursor. // Blur blurs the cursor.
func (m *Model) Blur() { func (m *Model) Blur() {
m.focus = false m.focus = false
m.Blink = true m.IsBlinked = true
} }
// SetChar sets the character under the cursor. // SetChar sets the character under the cursor.
@@ -237,7 +234,7 @@ func (m *Model) SetChar(char string) {
// View displays the cursor. // View displays the cursor.
func (m Model) View() string { func (m Model) View() string {
if m.Blink { if m.IsBlinked {
return m.TextStyle.Inline(true).Render(m.char) return m.TextStyle.Inline(true).Render(m.char)
} }
return m.Style.Inline(true).Reverse(true).Render(m.char) return m.Style.Inline(true).Reverse(true).Render(m.char)
+6 -6
View File
@@ -8,7 +8,7 @@ import (
// TestBlinkCmdDataRace tests for a race on [Cursor.blinkTag]. // TestBlinkCmdDataRace tests for a race on [Cursor.blinkTag].
// //
// The original [Model.BlinkCmd] implementation returned a closure over the pointer receiver: // The original [Model.Blink] implementation returned a closure over the pointer receiver:
// //
// return func() tea.Msg { // return func() tea.Msg {
// defer cancel() // defer cancel()
@@ -20,12 +20,12 @@ import (
// } // }
// //
// A race on “m.blinkTag” will occur if: // A race on “m.blinkTag” will occur if:
// 1. [Model.BlinkCmd] is called e.g. by calling [Model.Focus] from // 1. [Model.Blink] is called e.g. by calling [Model.Focus] from
// ["github.com/charmbracelet/bubbletea".Model.Update]; // ["github.com/charmbracelet/bubbletea".Model.Update];
// 2. ["github.com/charmbracelet/bubbletea".handleCommands] is kept sufficiently busy that it does not recieve and // 2. ["github.com/charmbracelet/bubbletea".handleCommands] is kept sufficiently busy that it does not recieve and
// execute the [Model.BlinkCmd] e.g. by other long running command or commands; // execute the [Model.Blink] e.g. by other long running command or commands;
// 3. at least [Mode.BlinkSpeed] time elapses; // 3. at least [Mode.BlinkSpeed] time elapses;
// 4. [Model.BlinkCmd] is called again; // 4. [Model.Blink] is called again;
// 5. ["github.com/charmbracelet/bubbletea".handleCommands] gets around to receiving and executing the original // 5. ["github.com/charmbracelet/bubbletea".handleCommands] gets around to receiving and executing the original
// closure. // closure.
// //
@@ -33,7 +33,7 @@ import (
// current value rather than the value at the time the closure was created). // current value rather than the value at the time the closure was created).
func TestBlinkCmdDataRace(t *testing.T) { func TestBlinkCmdDataRace(t *testing.T) {
m := New() m := New()
cmd := m.BlinkCmd() cmd := m.Blink()
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(2) wg.Add(2)
go func() { go func() {
@@ -44,7 +44,7 @@ func TestBlinkCmdDataRace(t *testing.T) {
go func() { go func() {
defer wg.Done() defer wg.Done()
time.Sleep(m.BlinkSpeed * 2) time.Sleep(m.BlinkSpeed * 2)
m.BlinkCmd() m.Blink()
}() }()
wg.Wait() wg.Wait()
} }
+2 -2
View File
@@ -1204,8 +1204,8 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
// nuance that makes cursor movement obvious and feel snappy. // nuance that makes cursor movement obvious and feel snappy.
newRow, newCol := m.cursorLineNumber(), m.col newRow, newCol := m.cursorLineNumber(), m.col
if (newRow != oldRow || newCol != oldCol) && m.virtualCursor.Mode() == cursor.CursorBlink { if (newRow != oldRow || newCol != oldCol) && m.virtualCursor.Mode() == cursor.CursorBlink {
m.virtualCursor.Blink = false m.virtualCursor.IsBlinked = false
cmd = m.virtualCursor.BlinkCmd() cmd = m.virtualCursor.Blink()
} }
cmds = append(cmds, cmd) cmds = append(cmds, cmd)
} }
+2 -2
View File
@@ -671,8 +671,8 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
// If the cursor position changed, reset the blink state. This is a // If the cursor position changed, reset the blink state. This is a
// small UX nuance that makes cursor movement obvious and feel snappy. // small UX nuance that makes cursor movement obvious and feel snappy.
if oldPos != m.pos && m.virtualCursor.Mode() == cursor.CursorBlink { if oldPos != m.pos && m.virtualCursor.Mode() == cursor.CursorBlink {
m.virtualCursor.Blink = false m.virtualCursor.IsBlinked = false
cmds = append(cmds, m.virtualCursor.BlinkCmd()) cmds = append(cmds, m.virtualCursor.Blink())
} }
} }