Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ updates:
labels:
- "dependencies"
commit-message:
prefix: "feat"
prefix: "chore"
include: "scope"
8 changes: 0 additions & 8 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ linters:
generated: lax
presets:
- common-false-positives
paths:
- third_party$
- builtin$
- examples$
issues:
max-issues-per-linter: 0
max-same-issues: 0
Expand All @@ -43,7 +39,3 @@ formatters:
- goimports
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@
[![Go ReportCard](https://goreportcard.com/badge/charmbracelet/bubbles)](https://goreportcard.com/report/charmbracelet/bubbles)

Some components for [Bubble Tea](https://github.com/charmbracelet/bubbletea)
applications. These components are used in production in [Glow][glow],
[Charm][charm] and [many other applications][otherstuff].
applications. These components are used in production in [Glow][glow], and [many other applications][otherstuff].

[glow]: https://github.com/charmbracelet/glow
[charm]: https://github.com/charmbracelet/charm
[otherstuff]: https://github.com/charmbracelet/bubbletea/#bubble-tea-in-the-wild

## Spinner
Expand Down
4 changes: 3 additions & 1 deletion cursor/cursor.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,13 @@ func (m *Model) BlinkCmd() tea.Cmd {

m.blinkTag++

blinkMsg := BlinkMsg{id: m.id, tag: m.blinkTag}

return func() tea.Msg {
defer cancel()
<-ctx.Done()
if ctx.Err() == context.DeadlineExceeded {
return BlinkMsg{id: m.id, tag: m.blinkTag}
return blinkMsg
}
return blinkCanceled{}
}
Expand Down
50 changes: 50 additions & 0 deletions cursor/cursor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package cursor

import (
"sync"
"testing"
"time"
)

// TestBlinkCmdDataRace tests for a race on [Cursor.blinkTag].
//
// The original [Model.BlinkCmd] implementation returned a closure over the pointer receiver:
//
// return func() tea.Msg {
// defer cancel()
// <-ctx.Done()
// if ctx.Err() == context.DeadlineExceeded {
// return BlinkMsg{id: m.id, tag: m.blinkTag}
// }
// return blinkCanceled{}
// }
//
// A race on “m.blinkTag” will occur if:
// 1. [Model.BlinkCmd] is called e.g. by calling [Model.Focus] from
// ["github.com/charmbracelet/bubbletea".Model.Update];
// 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;
// 3. at least [Mode.BlinkSpeed] time elapses;
// 4. [Model.BlinkCmd] is called again;
// 5. ["github.com/charmbracelet/bubbletea".handleCommands] gets around to receiving and executing the original
// closure.
//
// Even if this did not formally race, the value of the tag fetched would be semantically incorrect (likely being the
// current value rather than the value at the time the closure was created).
func TestBlinkCmdDataRace(t *testing.T) {
m := New()
cmd := m.BlinkCmd()
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
time.Sleep(m.BlinkSpeed * 3)
cmd()
}()
go func() {
defer wg.Done()
time.Sleep(m.BlinkSpeed * 2)
m.BlinkCmd()
}()
wg.Wait()
}
1 change: 1 addition & 0 deletions list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,7 @@ func (m *Model) setSize(width, height int) {
m.Help.Width = width
m.FilterInput.SetWidth(width - promptWidth - lipgloss.Width(m.spinnerView()))
m.updatePagination()
m.updateKeybindings()
}

func (m *Model) resetFiltering() {
Expand Down
5 changes: 5 additions & 0 deletions table/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,11 @@ func (m Model) Columns() []Column {
// SetRows sets a new rows state.
func (m *Model) SetRows(r []Row) {
m.rows = r

if m.cursor > len(m.rows)-1 {
m.cursor = len(m.rows) - 1
}

m.UpdateViewport()
}

Expand Down
Loading
Loading