mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-08-24 10:13:41 -05:00
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>
62 lines
1.8 KiB
Go
62 lines
1.8 KiB
Go
package gui
|
|
|
|
import (
|
|
"github.com/jesseduffield/lazygit/pkg/gocui"
|
|
)
|
|
|
|
func (gui *Gui) handleEditorKeypress(v *gocui.View, key gocui.Key, allowMultiline bool) bool {
|
|
if key.Equals(gocui.NewKeyName(gocui.KeyEnter)) && allowMultiline {
|
|
v.TextArea.TypeCharacter("\n")
|
|
v.RenderTextArea()
|
|
return true
|
|
}
|
|
|
|
return gocui.DefaultEditor.Edit(v, key)
|
|
}
|
|
|
|
// we've just copy+pasted the editor from gocui to here so that we can also re-
|
|
// render the commit message length on each keypress
|
|
func (gui *Gui) commitMessageEditor(v *gocui.View, key gocui.Key) bool {
|
|
matched := gui.handleEditorKeypress(v, key, false)
|
|
v.RenderTextArea()
|
|
gui.c.Contexts().CommitMessage.RenderSubtitle()
|
|
return matched
|
|
}
|
|
|
|
func (gui *Gui) commitDescriptionEditor(v *gocui.View, key gocui.Key) bool {
|
|
matched := gui.handleEditorKeypress(v, key, true)
|
|
v.RenderTextArea()
|
|
return matched
|
|
}
|
|
|
|
func (gui *Gui) promptEditor(v *gocui.View, key gocui.Key) bool {
|
|
matched := gui.handleEditorKeypress(v, key, false)
|
|
|
|
v.RenderTextArea()
|
|
|
|
suggestionsContext := gui.State.Contexts.Suggestions
|
|
// 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 := findSuggestions(input)
|
|
return func() { suggestionsContext.SetSuggestions(suggestions) }
|
|
})
|
|
}
|
|
|
|
return matched
|
|
}
|
|
|
|
func (gui *Gui) searchEditor(v *gocui.View, key gocui.Key) bool {
|
|
matched := gui.handleEditorKeypress(v, key, false)
|
|
v.RenderTextArea()
|
|
|
|
searchString := v.TextArea.GetContent()
|
|
|
|
gui.helpers.Search.OnPromptContentChanged(searchString)
|
|
|
|
return matched
|
|
}
|