mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-06-15 00:15:32 +02:00
fix mutex deadlock
This commit is contained in:
@ -77,7 +77,7 @@ func (gui *Gui) handleDiscardOldFileChange(g *gocui.Gui, v *gocui.View) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) refreshCommitFilesView() error {
|
func (gui *Gui) refreshCommitFilesView() error {
|
||||||
if err := gui.refreshPatchBuildingPanel(-1); err != nil {
|
if err := gui.handleRefreshPatchBuildingPanel(-1); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ func (gui *Gui) enterCommitFile(selectedLineIdx int) error {
|
|||||||
if err := gui.switchContext(gui.Contexts.PatchBuilding.Context); err != nil {
|
if err := gui.switchContext(gui.Contexts.PatchBuilding.Context); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return gui.refreshPatchBuildingPanel(selectedLineIdx)
|
return gui.handleRefreshPatchBuildingPanel(selectedLineIdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if gui.GitCommand.PatchManager.Active() && gui.GitCommand.PatchManager.To != commitFile.Parent {
|
if gui.GitCommand.PatchManager.Active() && gui.GitCommand.PatchManager.To != commitFile.Parent {
|
||||||
|
@ -185,7 +185,7 @@ func (gui *Gui) enterFile(forceSecondaryFocused bool, selectedLineIdx int) error
|
|||||||
}
|
}
|
||||||
gui.switchContext(gui.Contexts.Staging.Context)
|
gui.switchContext(gui.Contexts.Staging.Context)
|
||||||
|
|
||||||
return gui.refreshStagingPanel(forceSecondaryFocused, selectedLineIdx) // TODO: check if this is broken, try moving into context code
|
return gui.handleRefreshStagingPanel(forceSecondaryFocused, selectedLineIdx) // TODO: check if this is broken, try moving into context code
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleFilePress() error {
|
func (gui *Gui) handleFilePress() error {
|
||||||
|
@ -142,7 +142,7 @@ type IListPanelState interface {
|
|||||||
// for now the staging panel state, unlike the other panel states, is going to be
|
// for now the staging panel state, unlike the other panel states, is going to be
|
||||||
// non-mutative, so that we don't accidentally end up
|
// non-mutative, so that we don't accidentally end up
|
||||||
// with mismatches of data. We might change this in the future
|
// with mismatches of data. We might change this in the future
|
||||||
type lineByLinePanelState struct {
|
type lBlPanelState struct {
|
||||||
SelectedLineIdx int
|
SelectedLineIdx int
|
||||||
FirstLineIdx int
|
FirstLineIdx int
|
||||||
LastLineIdx int
|
LastLineIdx int
|
||||||
@ -234,7 +234,7 @@ type panelStates struct {
|
|||||||
SubCommits *subCommitPanelState
|
SubCommits *subCommitPanelState
|
||||||
Stash *stashPanelState
|
Stash *stashPanelState
|
||||||
Menu *menuPanelState
|
Menu *menuPanelState
|
||||||
LineByLine *lineByLinePanelState
|
LineByLine *lBlPanelState
|
||||||
Merging *mergingPanelState
|
Merging *mergingPanelState
|
||||||
CommitFiles *commitFilesPanelState
|
CommitFiles *commitFilesPanelState
|
||||||
Submodules *submodulePanelState
|
Submodules *submodulePanelState
|
||||||
|
@ -1112,21 +1112,21 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||||||
ViewName: "main",
|
ViewName: "main",
|
||||||
Contexts: []string{MAIN_STAGING_CONTEXT_KEY},
|
Contexts: []string{MAIN_STAGING_CONTEXT_KEY},
|
||||||
Key: gui.getKey(config.Universal.Select),
|
Key: gui.getKey(config.Universal.Select),
|
||||||
Handler: gui.handleToggleStagedSelection,
|
Handler: gui.wrappedHandler(gui.handleToggleStagedSelection),
|
||||||
Description: gui.Tr.StageSelection,
|
Description: gui.Tr.StageSelection,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "main",
|
ViewName: "main",
|
||||||
Contexts: []string{MAIN_STAGING_CONTEXT_KEY},
|
Contexts: []string{MAIN_STAGING_CONTEXT_KEY},
|
||||||
Key: gui.getKey(config.Universal.Remove),
|
Key: gui.getKey(config.Universal.Remove),
|
||||||
Handler: gui.handleResetSelection,
|
Handler: gui.wrappedHandler(gui.handleResetSelection),
|
||||||
Description: gui.Tr.ResetSelection,
|
Description: gui.Tr.ResetSelection,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "main",
|
ViewName: "main",
|
||||||
Contexts: []string{MAIN_STAGING_CONTEXT_KEY},
|
Contexts: []string{MAIN_STAGING_CONTEXT_KEY},
|
||||||
Key: gui.getKey(config.Universal.TogglePanel),
|
Key: gui.getKey(config.Universal.TogglePanel),
|
||||||
Handler: gui.handleTogglePanel,
|
Handler: gui.wrappedHandler(gui.handleTogglePanel),
|
||||||
Description: gui.Tr.TogglePanel,
|
Description: gui.Tr.TogglePanel,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -24,12 +24,7 @@ const (
|
|||||||
|
|
||||||
// returns whether the patch is empty so caller can escape if necessary
|
// returns whether the patch is empty so caller can escape if necessary
|
||||||
// both diffs should be non-coloured because we'll parse them and colour them here
|
// both diffs should be non-coloured because we'll parse them and colour them here
|
||||||
func (gui *Gui) refreshLineByLinePanel(diff string, secondaryDiff string, secondaryFocused bool, selectedLineIdx int) (bool, error) {
|
func (gui *Gui) refreshLineByLinePanel(diff string, secondaryDiff string, secondaryFocused bool, selectedLineIdx int, state *lBlPanelState) (bool, error) {
|
||||||
gui.Mutexes.LineByLinePanelMutex.Lock()
|
|
||||||
defer gui.Mutexes.LineByLinePanelMutex.Unlock()
|
|
||||||
|
|
||||||
state := gui.State.Panels.LineByLine
|
|
||||||
|
|
||||||
patchParser, err := patch.NewPatchParser(gui.Log, diff)
|
patchParser, err := patch.NewPatchParser(gui.Log, diff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -66,7 +61,7 @@ func (gui *Gui) refreshLineByLinePanel(diff string, secondaryDiff string, second
|
|||||||
firstLineIdx, lastLineIdx = selectedLineIdx, selectedLineIdx
|
firstLineIdx, lastLineIdx = selectedLineIdx, selectedLineIdx
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.State.Panels.LineByLine = &lineByLinePanelState{
|
state = &lBlPanelState{
|
||||||
PatchParser: patchParser,
|
PatchParser: patchParser,
|
||||||
SelectedLineIdx: selectedLineIdx,
|
SelectedLineIdx: selectedLineIdx,
|
||||||
SelectMode: selectMode,
|
SelectMode: selectMode,
|
||||||
@ -75,12 +70,13 @@ func (gui *Gui) refreshLineByLinePanel(diff string, secondaryDiff string, second
|
|||||||
Diff: diff,
|
Diff: diff,
|
||||||
SecondaryFocused: secondaryFocused,
|
SecondaryFocused: secondaryFocused,
|
||||||
}
|
}
|
||||||
|
gui.State.Panels.LineByLine = state
|
||||||
|
|
||||||
if err := gui.refreshMainViewForLineByLine(); err != nil {
|
if err := gui.refreshMainViewForLineByLine(state); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gui.focusSelection(selectMode == HUNK); err != nil {
|
if err := gui.focusSelection(selectMode == HUNK, state); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,35 +98,34 @@ func (gui *Gui) refreshLineByLinePanel(diff string, secondaryDiff string, second
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleSelectPrevLine() error {
|
func (gui *Gui) handleSelectPrevLine() error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
return gui.LBLCycleLine(-1)
|
return gui.LBLCycleLine(-1, state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleSelectNextLine() error {
|
func (gui *Gui) handleSelectNextLine() error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
return gui.LBLCycleLine(+1)
|
return gui.LBLCycleLine(+1, state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleSelectPrevHunk() error {
|
func (gui *Gui) handleSelectPrevHunk() error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
newHunk := state.PatchParser.GetHunkContainingLine(state.SelectedLineIdx, -1)
|
newHunk := state.PatchParser.GetHunkContainingLine(state.SelectedLineIdx, -1)
|
||||||
|
|
||||||
return gui.selectNewHunk(newHunk)
|
return gui.selectNewHunk(newHunk, state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleSelectNextHunk() error {
|
func (gui *Gui) handleSelectNextHunk() error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
newHunk := state.PatchParser.GetHunkContainingLine(state.SelectedLineIdx, 1)
|
newHunk := state.PatchParser.GetHunkContainingLine(state.SelectedLineIdx, 1)
|
||||||
|
|
||||||
return gui.selectNewHunk(newHunk)
|
return gui.selectNewHunk(newHunk, state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) selectNewHunk(newHunk *patch.PatchHunk) error {
|
func (gui *Gui) selectNewHunk(newHunk *patch.PatchHunk, state *lBlPanelState) error {
|
||||||
state := gui.State.Panels.LineByLine
|
|
||||||
state.SelectedLineIdx = state.PatchParser.GetNextStageableLineIndex(newHunk.FirstLineIdx)
|
state.SelectedLineIdx = state.PatchParser.GetNextStageableLineIndex(newHunk.FirstLineIdx)
|
||||||
if state.SelectMode == HUNK {
|
if state.SelectMode == HUNK {
|
||||||
state.FirstLineIdx, state.LastLineIdx = newHunk.FirstLineIdx, newHunk.LastLineIdx()
|
state.FirstLineIdx, state.LastLineIdx = newHunk.FirstLineIdx, newHunk.LastLineIdx()
|
||||||
@ -138,27 +133,23 @@ func (gui *Gui) selectNewHunk(newHunk *patch.PatchHunk) error {
|
|||||||
state.FirstLineIdx, state.LastLineIdx = state.SelectedLineIdx, state.SelectedLineIdx
|
state.FirstLineIdx, state.LastLineIdx = state.SelectedLineIdx, state.SelectedLineIdx
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gui.refreshMainViewForLineByLine(); err != nil {
|
if err := gui.refreshMainViewForLineByLine(state); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return gui.focusSelection(true)
|
return gui.focusSelection(true, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) LBLCycleLine(change int) error {
|
func (gui *Gui) LBLCycleLine(change int, state *lBlPanelState) error {
|
||||||
state := gui.State.Panels.LineByLine
|
|
||||||
|
|
||||||
if state.SelectMode == HUNK {
|
if state.SelectMode == HUNK {
|
||||||
newHunk := state.PatchParser.GetHunkContainingLine(state.SelectedLineIdx, change)
|
newHunk := state.PatchParser.GetHunkContainingLine(state.SelectedLineIdx, change)
|
||||||
return gui.selectNewHunk(newHunk)
|
return gui.selectNewHunk(newHunk, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
return gui.LBLSelectLine(state.SelectedLineIdx + change)
|
return gui.LBLSelectLine(state.SelectedLineIdx+change, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) LBLSelectLine(newSelectedLineIdx int) error {
|
func (gui *Gui) LBLSelectLine(newSelectedLineIdx int, state *lBlPanelState) error {
|
||||||
state := gui.State.Panels.LineByLine
|
|
||||||
|
|
||||||
if newSelectedLineIdx < 0 {
|
if newSelectedLineIdx < 0 {
|
||||||
newSelectedLineIdx = 0
|
newSelectedLineIdx = 0
|
||||||
} else if newSelectedLineIdx > len(state.PatchParser.PatchLines)-1 {
|
} else if newSelectedLineIdx > len(state.PatchParser.PatchLines)-1 {
|
||||||
@ -178,15 +169,15 @@ func (gui *Gui) LBLSelectLine(newSelectedLineIdx int) error {
|
|||||||
state.FirstLineIdx = state.SelectedLineIdx
|
state.FirstLineIdx = state.SelectedLineIdx
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gui.refreshMainViewForLineByLine(); err != nil {
|
if err := gui.refreshMainViewForLineByLine(state); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return gui.focusSelection(false)
|
return gui.focusSelection(false, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleLBLMouseDown(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleLBLMouseDown(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
if gui.popupPanelFocused() {
|
if gui.popupPanelFocused() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -197,41 +188,41 @@ func (gui *Gui) handleLBLMouseDown(g *gocui.Gui, v *gocui.View) error {
|
|||||||
|
|
||||||
state.SelectMode = RANGE
|
state.SelectMode = RANGE
|
||||||
|
|
||||||
return gui.LBLSelectLine(newSelectedLineIdx)
|
return gui.LBLSelectLine(newSelectedLineIdx, state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleMouseDrag(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleMouseDrag(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.withLBLActiveCheck(func(*lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
if gui.popupPanelFocused() {
|
if gui.popupPanelFocused() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return gui.LBLSelectLine(v.SelectedLineIdx())
|
return gui.LBLSelectLine(v.SelectedLineIdx(), state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleMouseScrollUp(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleMouseScrollUp(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
if gui.popupPanelFocused() {
|
if gui.popupPanelFocused() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
state.SelectMode = LINE
|
state.SelectMode = LINE
|
||||||
|
|
||||||
return gui.LBLCycleLine(-1)
|
return gui.LBLCycleLine(-1, state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleMouseScrollDown(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleMouseScrollDown(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
if gui.popupPanelFocused() {
|
if gui.popupPanelFocused() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
state.SelectMode = LINE
|
state.SelectMode = LINE
|
||||||
|
|
||||||
return gui.LBLCycleLine(1)
|
return gui.LBLCycleLine(1, state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,9 +230,7 @@ func (gui *Gui) getSelectedCommitFileName() string {
|
|||||||
return gui.State.CommitFiles[gui.State.Panels.CommitFiles.SelectedLineIdx].Name
|
return gui.State.CommitFiles[gui.State.Panels.CommitFiles.SelectedLineIdx].Name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) refreshMainViewForLineByLine() error {
|
func (gui *Gui) refreshMainViewForLineByLine(state *lBlPanelState) error {
|
||||||
state := gui.State.Panels.LineByLine
|
|
||||||
|
|
||||||
var includedLineIndices []int
|
var includedLineIndices []int
|
||||||
// I'd prefer not to have knowledge of contexts using this file but I'm not sure
|
// I'd prefer not to have knowledge of contexts using this file but I'm not sure
|
||||||
// how to get around this
|
// how to get around this
|
||||||
@ -269,9 +258,8 @@ func (gui *Gui) refreshMainViewForLineByLine() error {
|
|||||||
|
|
||||||
// focusSelection works out the best focus for the staging panel given the
|
// focusSelection works out the best focus for the staging panel given the
|
||||||
// selected line and size of the hunk
|
// selected line and size of the hunk
|
||||||
func (gui *Gui) focusSelection(includeCurrentHunk bool) error {
|
func (gui *Gui) focusSelection(includeCurrentHunk bool, state *lBlPanelState) error {
|
||||||
stagingView := gui.getMainView()
|
stagingView := gui.getMainView()
|
||||||
state := gui.State.Panels.LineByLine
|
|
||||||
|
|
||||||
_, viewHeight := stagingView.Size()
|
_, viewHeight := stagingView.Size()
|
||||||
bufferHeight := viewHeight - 1
|
bufferHeight := viewHeight - 1
|
||||||
@ -309,7 +297,7 @@ func (gui *Gui) focusSelection(includeCurrentHunk bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleToggleSelectRange() error {
|
func (gui *Gui) handleToggleSelectRange() error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
if state.SelectMode == RANGE {
|
if state.SelectMode == RANGE {
|
||||||
state.SelectMode = LINE
|
state.SelectMode = LINE
|
||||||
} else {
|
} else {
|
||||||
@ -317,12 +305,12 @@ func (gui *Gui) handleToggleSelectRange() error {
|
|||||||
}
|
}
|
||||||
state.FirstLineIdx, state.LastLineIdx = state.SelectedLineIdx, state.SelectedLineIdx
|
state.FirstLineIdx, state.LastLineIdx = state.SelectedLineIdx, state.SelectedLineIdx
|
||||||
|
|
||||||
return gui.refreshMainViewForLineByLine()
|
return gui.refreshMainViewForLineByLine(state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleToggleSelectHunk() error {
|
func (gui *Gui) handleToggleSelectHunk() error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
if state.SelectMode == HUNK {
|
if state.SelectMode == HUNK {
|
||||||
state.SelectMode = LINE
|
state.SelectMode = LINE
|
||||||
state.FirstLineIdx, state.LastLineIdx = state.SelectedLineIdx, state.SelectedLineIdx
|
state.FirstLineIdx, state.LastLineIdx = state.SelectedLineIdx, state.SelectedLineIdx
|
||||||
@ -332,23 +320,20 @@ func (gui *Gui) handleToggleSelectHunk() error {
|
|||||||
state.FirstLineIdx, state.LastLineIdx = selectedHunk.FirstLineIdx, selectedHunk.LastLineIdx()
|
state.FirstLineIdx, state.LastLineIdx = selectedHunk.FirstLineIdx, selectedHunk.LastLineIdx()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gui.refreshMainViewForLineByLine(); err != nil {
|
if err := gui.refreshMainViewForLineByLine(state); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return gui.focusSelection(state.SelectMode == HUNK)
|
return gui.focusSelection(state.SelectMode == HUNK, state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) escapeLineByLinePanel() {
|
func (gui *Gui) escapeLineByLinePanel() {
|
||||||
_ = gui.withLBLActiveCheck(func(*lineByLinePanelState) error {
|
|
||||||
gui.State.Panels.LineByLine = nil
|
gui.State.Panels.LineByLine = nil
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleOpenFileAtLine() error {
|
func (gui *Gui) handleOpenFileAtLine() error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
// again, would be good to use inheritance here (or maybe even composition)
|
// again, would be good to use inheritance here (or maybe even composition)
|
||||||
var filename string
|
var filename string
|
||||||
switch gui.State.MainContext {
|
switch gui.State.MainContext {
|
||||||
@ -377,47 +362,48 @@ func (gui *Gui) handleOpenFileAtLine() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleLineByLineNextPage() error {
|
func (gui *Gui) handleLineByLineNextPage() error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
newSelectedLineIdx := state.SelectedLineIdx + gui.pageDelta(gui.getMainView())
|
newSelectedLineIdx := state.SelectedLineIdx + gui.pageDelta(gui.getMainView())
|
||||||
|
|
||||||
return gui.lineByLineNavigateTo(newSelectedLineIdx)
|
return gui.lineByLineNavigateTo(newSelectedLineIdx, state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleLineByLinePrevPage() error {
|
func (gui *Gui) handleLineByLinePrevPage() error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
newSelectedLineIdx := state.SelectedLineIdx - gui.pageDelta(gui.getMainView())
|
newSelectedLineIdx := state.SelectedLineIdx - gui.pageDelta(gui.getMainView())
|
||||||
|
|
||||||
return gui.lineByLineNavigateTo(newSelectedLineIdx)
|
return gui.lineByLineNavigateTo(newSelectedLineIdx, state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleLineByLineGotoBottom() error {
|
func (gui *Gui) handleLineByLineGotoBottom() error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
newSelectedLineIdx := len(state.PatchParser.PatchLines) - 1
|
newSelectedLineIdx := len(state.PatchParser.PatchLines) - 1
|
||||||
|
|
||||||
return gui.lineByLineNavigateTo(newSelectedLineIdx)
|
return gui.lineByLineNavigateTo(newSelectedLineIdx, state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleLineByLineGotoTop() error {
|
func (gui *Gui) handleLineByLineGotoTop() error {
|
||||||
return gui.lineByLineNavigateTo(0)
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
}
|
return gui.lineByLineNavigateTo(0, state)
|
||||||
|
|
||||||
func (gui *Gui) handlelineByLineNavigateTo(selectedLineIdx int) error {
|
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
|
||||||
return gui.lineByLineNavigateTo(selectedLineIdx)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) lineByLineNavigateTo(selectedLineIdx int) error {
|
func (gui *Gui) handlelineByLineNavigateTo(selectedLineIdx int) error {
|
||||||
state := gui.State.Panels.LineByLine
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
state.SelectMode = LINE
|
return gui.lineByLineNavigateTo(selectedLineIdx, state)
|
||||||
|
})
|
||||||
return gui.LBLSelectLine(selectedLineIdx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) withLBLActiveCheck(f func(*lineByLinePanelState) error) error {
|
func (gui *Gui) lineByLineNavigateTo(selectedLineIdx int, state *lBlPanelState) error {
|
||||||
|
state.SelectMode = LINE
|
||||||
|
|
||||||
|
return gui.LBLSelectLine(selectedLineIdx, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) withLBLActiveCheck(f func(*lBlPanelState) error) error {
|
||||||
gui.Mutexes.LineByLinePanelMutex.Lock()
|
gui.Mutexes.LineByLinePanelMutex.Lock()
|
||||||
defer gui.Mutexes.LineByLinePanelMutex.Unlock()
|
defer gui.Mutexes.LineByLinePanelMutex.Unlock()
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ func (gui *Gui) getFromAndReverseArgsForDiff(to string) (string, bool) {
|
|||||||
return from, reverse
|
return from, reverse
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error {
|
func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int, state *lBlPanelState) error {
|
||||||
if !gui.GitCommand.PatchManager.Active() {
|
if !gui.GitCommand.PatchManager.Active() {
|
||||||
return gui.handleEscapePatchBuildingPanel()
|
return gui.handleEscapePatchBuildingPanel()
|
||||||
}
|
}
|
||||||
@ -45,7 +45,7 @@ func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
empty, err := gui.refreshLineByLinePanel(diff, secondaryDiff, false, selectedLineIdx)
|
empty, err := gui.refreshLineByLinePanel(diff, secondaryDiff, false, selectedLineIdx, state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -57,8 +57,15 @@ func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) handleRefreshPatchBuildingPanel(selectedLineIdx int) error {
|
||||||
|
gui.Mutexes.LineByLinePanelMutex.Lock()
|
||||||
|
defer gui.Mutexes.LineByLinePanelMutex.Unlock()
|
||||||
|
|
||||||
|
return gui.refreshPatchBuildingPanel(selectedLineIdx, gui.State.Panels.LineByLine)
|
||||||
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleToggleSelectionForPatch() error {
|
func (gui *Gui) handleToggleSelectionForPatch() error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
err := gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
toggleFunc := gui.GitCommand.PatchManager.AddFileLineRange
|
toggleFunc := gui.GitCommand.PatchManager.AddFileLineRange
|
||||||
filename := gui.getSelectedCommitFileName()
|
filename := gui.getSelectedCommitFileName()
|
||||||
includedLineIndices, err := gui.GitCommand.PatchManager.GetFileIncLineIndices(filename)
|
includedLineIndices, err := gui.GitCommand.PatchManager.GetFileIncLineIndices(filename)
|
||||||
@ -81,16 +88,18 @@ func (gui *Gui) handleToggleSelectionForPatch() error {
|
|||||||
gui.Log.Error(err)
|
gui.Log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := gui.refreshCommitFilesView(); err != nil {
|
if err := gui.refreshCommitFilesView(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gui.refreshPatchBuildingPanel(-1); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleEscapePatchBuildingPanel() error {
|
func (gui *Gui) handleEscapePatchBuildingPanel() error {
|
||||||
|
@ -7,17 +7,11 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/commands/patch"
|
"github.com/jesseduffield/lazygit/pkg/commands/patch"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (gui *Gui) refreshStagingPanel(forceSecondaryFocused bool, selectedLineIdx int) error {
|
func (gui *Gui) refreshStagingPanel(forceSecondaryFocused bool, selectedLineIdx int, state *lBlPanelState) error {
|
||||||
gui.splitMainPanel(true)
|
gui.splitMainPanel(true)
|
||||||
|
|
||||||
state := gui.State.Panels.LineByLine
|
|
||||||
|
|
||||||
file := gui.getSelectedFile()
|
file := gui.getSelectedFile()
|
||||||
if file == nil {
|
if file == nil || (!file.HasUnstagedChanges && !file.HasStagedChanges) {
|
||||||
return gui.handleStagingEscape()
|
|
||||||
}
|
|
||||||
|
|
||||||
if !file.HasUnstagedChanges && !file.HasStagedChanges {
|
|
||||||
return gui.handleStagingEscape()
|
return gui.handleStagingEscape()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +50,7 @@ func (gui *Gui) refreshStagingPanel(forceSecondaryFocused bool, selectedLineIdx
|
|||||||
diff, secondaryDiff = secondaryDiff, diff
|
diff, secondaryDiff = secondaryDiff, diff
|
||||||
}
|
}
|
||||||
|
|
||||||
empty, err := gui.refreshLineByLinePanel(diff, secondaryDiff, secondaryFocused, selectedLineIdx)
|
empty, err := gui.refreshLineByLinePanel(diff, secondaryDiff, secondaryFocused, selectedLineIdx, state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -69,17 +63,24 @@ func (gui *Gui) refreshStagingPanel(forceSecondaryFocused bool, selectedLineIdx
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleTogglePanelClick(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleTogglePanelClick(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
state.SecondaryFocused = !state.SecondaryFocused
|
state.SecondaryFocused = !state.SecondaryFocused
|
||||||
|
|
||||||
return gui.refreshStagingPanel(false, v.SelectedLineIdx())
|
return gui.refreshStagingPanel(false, v.SelectedLineIdx(), state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleTogglePanel(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleRefreshStagingPanel(forceSecondaryFocused bool, selectedLineIdx int) error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
gui.Mutexes.LineByLinePanelMutex.Lock()
|
||||||
|
defer gui.Mutexes.LineByLinePanelMutex.Unlock()
|
||||||
|
|
||||||
|
return gui.refreshStagingPanel(forceSecondaryFocused, selectedLineIdx, gui.State.Panels.LineByLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) handleTogglePanel() error {
|
||||||
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
state.SecondaryFocused = !state.SecondaryFocused
|
state.SecondaryFocused = !state.SecondaryFocused
|
||||||
return gui.refreshStagingPanel(false, -1)
|
return gui.refreshStagingPanel(false, -1, state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,17 +90,17 @@ func (gui *Gui) handleStagingEscape() error {
|
|||||||
return gui.switchContext(gui.Contexts.Files.Context)
|
return gui.switchContext(gui.Contexts.Files.Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleToggleStagedSelection(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleToggleStagedSelection() error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
return gui.applySelection(state.SecondaryFocused)
|
return gui.applySelection(state.SecondaryFocused, state)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleResetSelection(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleResetSelection() error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
if state.SecondaryFocused {
|
if state.SecondaryFocused {
|
||||||
// for backwards compatibility
|
// for backwards compatibility
|
||||||
return gui.applySelection(true)
|
return gui.applySelection(true, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !gui.Config.GetUserConfig().Gui.SkipUnstageLineWarning {
|
if !gui.Config.GetUserConfig().Gui.SkipUnstageLineWarning {
|
||||||
@ -108,24 +109,25 @@ func (gui *Gui) handleResetSelection(g *gocui.Gui, v *gocui.View) error {
|
|||||||
prompt: gui.Tr.UnstageLinesPrompt,
|
prompt: gui.Tr.UnstageLinesPrompt,
|
||||||
handlersManageFocus: true,
|
handlersManageFocus: true,
|
||||||
handleConfirm: func() error {
|
handleConfirm: func() error {
|
||||||
|
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||||
if err := gui.switchContext(gui.Contexts.Staging.Context); err != nil {
|
if err := gui.switchContext(gui.Contexts.Staging.Context); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return gui.applySelection(true)
|
return gui.applySelection(true, state)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
handleClose: func() error {
|
handleClose: func() error {
|
||||||
return gui.switchContext(gui.Contexts.Staging.Context)
|
return gui.switchContext(gui.Contexts.Staging.Context)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return gui.applySelection(true)
|
return gui.applySelection(true, state)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) applySelection(reverse bool) error {
|
func (gui *Gui) applySelection(reverse bool, state *lBlPanelState) error {
|
||||||
return gui.withLBLActiveCheck(func(state *lineByLinePanelState) error {
|
|
||||||
file := gui.getSelectedFile()
|
file := gui.getSelectedFile()
|
||||||
if file == nil {
|
if file == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -155,9 +157,8 @@ func (gui *Gui) applySelection(reverse bool) error {
|
|||||||
if err := gui.refreshSidePanels(refreshOptions{scope: []int{FILES}}); err != nil {
|
if err := gui.refreshSidePanels(refreshOptions{scope: []int{FILES}}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := gui.refreshStagingPanel(false, -1); err != nil {
|
if err := gui.refreshStagingPanel(false, -1, state); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -405,7 +405,8 @@ func (gui *Gui) wrappedHandler(f func() error) func(g *gocui.Gui, v *gocui.View)
|
|||||||
|
|
||||||
// secondaryViewFocused tells us whether it appears that the secondary view is focused. The view is actually never focused for real: we just swap the main and secondary views and then you're still focused on the main view so that we can give you access to all its keybindings for free. I will probably regret this design decision soon enough.
|
// secondaryViewFocused tells us whether it appears that the secondary view is focused. The view is actually never focused for real: we just swap the main and secondary views and then you're still focused on the main view so that we can give you access to all its keybindings for free. I will probably regret this design decision soon enough.
|
||||||
func (gui *Gui) secondaryViewFocused() bool {
|
func (gui *Gui) secondaryViewFocused() bool {
|
||||||
return gui.State.Panels.LineByLine != nil && gui.State.Panels.LineByLine.SecondaryFocused
|
state := gui.State.Panels.LineByLine
|
||||||
|
return state != nil && state.SecondaryFocused
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) clearEditorView(v *gocui.View) {
|
func (gui *Gui) clearEditorView(v *gocui.View) {
|
||||||
|
Reference in New Issue
Block a user