mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-12 00:26:24 -04:00
Capture suggestions inputs on the UI thread
RefreshSuggestions dispatched to an AsyncHandler worker that read State.FindSuggestions and the prompt's TextArea (via GetPromptInput) from the worker goroutine. The main thread rewrites both in preparePromptPanel when it (re)creates a prompt panel, so an in-flight suggestions worker races those writes -- two data races surfaced under -race (filter_by_path/reword_commit_in_filtering_mode). Capture both on the UI thread (RefreshSuggestions is only ever called from UI-thread handlers) before dispatching to the worker. This is also more correct: we search for the input as it was when dispatched, which is what this request's AsyncHandler id corresponds to. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1b0cc02e1e
commit
d36ce51559
|
|
@ -81,10 +81,17 @@ func (self *SuggestionsContext) SetSuggestions(suggestions []*types.Suggestion)
|
|||
}
|
||||
|
||||
func (self *SuggestionsContext) RefreshSuggestions() {
|
||||
// Capture the suggestions function and the prompt input here, on the UI
|
||||
// thread, rather than inside the worker below: the main thread rewrites both
|
||||
// (State.FindSuggestions and the prompt's TextArea) when it (re)creates a
|
||||
// prompt panel, so reading them from the worker races those writes. It's
|
||||
// also more correct -- we search for the input as it was when dispatched,
|
||||
// which is what this request's AsyncHandler id corresponds to.
|
||||
findSuggestionsFn := self.State.FindSuggestions
|
||||
promptInput := self.c.GetPromptInput()
|
||||
self.State.AsyncHandler.Do(func() func() {
|
||||
findSuggestionsFn := self.State.FindSuggestions
|
||||
if findSuggestionsFn != nil {
|
||||
suggestions := findSuggestionsFn(self.c.GetPromptInput())
|
||||
suggestions := findSuggestionsFn(promptInput)
|
||||
return func() { self.SetSuggestions(suggestions) }
|
||||
}
|
||||
return func() {}
|
||||
|
|
|
|||
|
|
@ -35,10 +35,13 @@ func (gui *Gui) promptEditor(v *gocui.View, key gocui.Key) bool {
|
|||
v.RenderTextArea()
|
||||
|
||||
suggestionsContext := gui.State.Contexts.Suggestions
|
||||
if suggestionsContext.State.FindSuggestions != nil {
|
||||
// Capture the suggestions function and the input here, on the UI thread; the
|
||||
// main thread rewrites State.FindSuggestions when it (re)creates a prompt
|
||||
// panel, so reading it from the worker below would race that write.
|
||||
if findSuggestions := suggestionsContext.State.FindSuggestions; findSuggestions != nil {
|
||||
input := v.TextArea.GetContent()
|
||||
suggestionsContext.State.AsyncHandler.Do(func() func() {
|
||||
suggestions := suggestionsContext.State.FindSuggestions(input)
|
||||
suggestions := findSuggestions(input)
|
||||
return func() { suggestionsContext.SetSuggestions(suggestions) }
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue