From bb081ca764e42a5cfa67a0dd42acbdef4ae57e05 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Wed, 7 Oct 2020 17:54:45 +1100 Subject: [PATCH] more mutex safety with staging panel --- pkg/gui/keybindings.go | 2 +- pkg/gui/line_by_line_panel.go | 2 +- pkg/gui/patch_building_panel.go | 60 +++++++------- pkg/gui/staging_panel.go | 136 ++++++++++++++++---------------- 4 files changed, 101 insertions(+), 99 deletions(-) diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index ac87b6dd8..b9ada7628 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -1275,7 +1275,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { ViewName: "main", Contexts: []string{MAIN_PATCH_BUILDING_CONTEXT_KEY}, Key: gui.getKey(config.Universal.Select), - Handler: gui.handleToggleSelectionForPatch, + Handler: gui.wrappedHandler(gui.handleToggleSelectionForPatch), Description: gui.Tr.ToggleSelectionForPatch, }, { diff --git a/pkg/gui/line_by_line_panel.go b/pkg/gui/line_by_line_panel.go index bd74d0fc6..cb93468a3 100644 --- a/pkg/gui/line_by_line_panel.go +++ b/pkg/gui/line_by_line_panel.go @@ -341,7 +341,7 @@ func (gui *Gui) handleToggleSelectHunk() error { } func (gui *Gui) escapeLineByLinePanel() { - gui.withLBLActiveCheck(func(*lineByLinePanelState) error { + _ = gui.withLBLActiveCheck(func(*lineByLinePanelState) error { gui.State.Panels.LineByLine = nil return nil }) diff --git a/pkg/gui/patch_building_panel.go b/pkg/gui/patch_building_panel.go index f246ce92d..3f6a71c95 100644 --- a/pkg/gui/patch_building_panel.go +++ b/pkg/gui/patch_building_panel.go @@ -1,7 +1,6 @@ package gui import ( - "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/utils" ) @@ -58,37 +57,40 @@ func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error { return nil } -func (gui *Gui) handleToggleSelectionForPatch(g *gocui.Gui, v *gocui.View) error { - state := gui.State.Panels.LineByLine +func (gui *Gui) handleToggleSelectionForPatch() error { + return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error { + toggleFunc := gui.GitCommand.PatchManager.AddFileLineRange + filename := gui.getSelectedCommitFileName() + includedLineIndices, err := gui.GitCommand.PatchManager.GetFileIncLineIndices(filename) + if err != nil { + return err + } + currentLineIsStaged := utils.IncludesInt(includedLineIndices, state.SelectedLineIdx) + if currentLineIsStaged { + toggleFunc = gui.GitCommand.PatchManager.RemoveFileLineRange + } - toggleFunc := gui.GitCommand.PatchManager.AddFileLineRange - filename := gui.getSelectedCommitFileName() - includedLineIndices, err := gui.GitCommand.PatchManager.GetFileIncLineIndices(filename) - if err != nil { - return err - } - currentLineIsStaged := utils.IncludesInt(includedLineIndices, state.SelectedLineIdx) - if currentLineIsStaged { - toggleFunc = gui.GitCommand.PatchManager.RemoveFileLineRange - } + // add range of lines to those set for the file + commitFile := gui.getSelectedCommitFile() + if commitFile == nil { + return nil + } + + if err := toggleFunc(commitFile.Name, state.FirstLineIdx, state.LastLineIdx); err != nil { + // might actually want to return an error here + gui.Log.Error(err) + } + + if err := gui.refreshCommitFilesView(); err != nil { + return err + } + + if err := gui.refreshPatchBuildingPanel(-1); err != nil { + return err + } - // add range of lines to those set for the file - commitFile := gui.getSelectedCommitFile() - if commitFile == nil { return nil - } - - toggleFunc(commitFile.Name, state.FirstLineIdx, state.LastLineIdx) - - if err := gui.refreshCommitFilesView(); err != nil { - return err - } - - if err := gui.refreshPatchBuildingPanel(-1); err != nil { - return err - } - - return nil + }) } func (gui *Gui) handleEscapePatchBuildingPanel() error { diff --git a/pkg/gui/staging_panel.go b/pkg/gui/staging_panel.go index e2010b980..68c7c8391 100644 --- a/pkg/gui/staging_panel.go +++ b/pkg/gui/staging_panel.go @@ -69,18 +69,18 @@ func (gui *Gui) refreshStagingPanel(forceSecondaryFocused bool, selectedLineIdx } func (gui *Gui) handleTogglePanelClick(g *gocui.Gui, v *gocui.View) error { - state := gui.State.Panels.LineByLine + return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error { + state.SecondaryFocused = !state.SecondaryFocused - state.SecondaryFocused = !state.SecondaryFocused - - return gui.refreshStagingPanel(false, v.SelectedLineIdx()) + return gui.refreshStagingPanel(false, v.SelectedLineIdx()) + }) } func (gui *Gui) handleTogglePanel(g *gocui.Gui, v *gocui.View) error { - state := gui.State.Panels.LineByLine - - state.SecondaryFocused = !state.SecondaryFocused - return gui.refreshStagingPanel(false, -1) + return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error { + state.SecondaryFocused = !state.SecondaryFocused + return gui.refreshStagingPanel(false, -1) + }) } func (gui *Gui) handleStagingEscape() error { @@ -90,74 +90,74 @@ func (gui *Gui) handleStagingEscape() error { } func (gui *Gui) handleToggleStagedSelection(g *gocui.Gui, v *gocui.View) error { - state := gui.State.Panels.LineByLine - - return gui.applySelection(state.SecondaryFocused) + return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error { + return gui.applySelection(state.SecondaryFocused) + }) } func (gui *Gui) handleResetSelection(g *gocui.Gui, v *gocui.View) error { - state := gui.State.Panels.LineByLine + return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error { + if state.SecondaryFocused { + // for backwards compatibility + return gui.applySelection(true) + } - if state.SecondaryFocused { - // for backwards compatibility - return gui.applySelection(true) - } + if !gui.Config.GetUserConfig().Gui.SkipUnstageLineWarning { + return gui.ask(askOpts{ + title: gui.Tr.UnstageLinesTitle, + prompt: gui.Tr.UnstageLinesPrompt, + handlersManageFocus: true, + handleConfirm: func() error { + if err := gui.switchContext(gui.Contexts.Staging.Context); err != nil { + return err + } - if !gui.Config.GetUserConfig().Gui.SkipUnstageLineWarning { - return gui.ask(askOpts{ - title: gui.Tr.UnstageLinesTitle, - prompt: gui.Tr.UnstageLinesPrompt, - handlersManageFocus: true, - handleConfirm: func() error { - if err := gui.switchContext(gui.Contexts.Staging.Context); err != nil { - return err - } - - return gui.applySelection(true) - }, - handleClose: func() error { - return gui.switchContext(gui.Contexts.Staging.Context) - }, - }) - } else { - return gui.applySelection(true) - } + return gui.applySelection(true) + }, + handleClose: func() error { + return gui.switchContext(gui.Contexts.Staging.Context) + }, + }) + } else { + return gui.applySelection(true) + } + }) } func (gui *Gui) applySelection(reverse bool) error { - state := gui.State.Panels.LineByLine + return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error { + file := gui.getSelectedFile() + if file == nil { + return nil + } - file := gui.getSelectedFile() - if file == nil { + patch := patch.ModifiedPatchForRange(gui.Log, file.Name, state.Diff, state.FirstLineIdx, state.LastLineIdx, reverse, false) + + if patch == "" { + return nil + } + + // apply the patch then refresh this panel + // create a new temp file with the patch, then call git apply with that patch + applyFlags := []string{} + if !reverse || state.SecondaryFocused { + applyFlags = append(applyFlags, "cached") + } + err := gui.GitCommand.ApplyPatch(patch, applyFlags...) + if err != nil { + return gui.surfaceError(err) + } + + if state.SelectMode == RANGE { + state.SelectMode = LINE + } + + if err := gui.refreshSidePanels(refreshOptions{scope: []int{FILES}}); err != nil { + return err + } + if err := gui.refreshStagingPanel(false, -1); err != nil { + return err + } return nil - } - - patch := patch.ModifiedPatchForRange(gui.Log, file.Name, state.Diff, state.FirstLineIdx, state.LastLineIdx, reverse, false) - - if patch == "" { - return nil - } - - // apply the patch then refresh this panel - // create a new temp file with the patch, then call git apply with that patch - applyFlags := []string{} - if !reverse || state.SecondaryFocused { - applyFlags = append(applyFlags, "cached") - } - err := gui.GitCommand.ApplyPatch(patch, applyFlags...) - if err != nil { - return gui.surfaceError(err) - } - - if state.SelectMode == RANGE { - state.SelectMode = LINE - } - - if err := gui.refreshSidePanels(refreshOptions{scope: []int{FILES}}); err != nil { - return err - } - if err := gui.refreshStagingPanel(false, -1); err != nil { - return err - } - return nil + }) }