1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-02-13 13:59:06 +02:00

allow rendering to main panels from anywhere

This commit is contained in:
Jesse Duffield 2022-08-07 11:34:53 +10:00
parent fcf20f3b93
commit d73a236d7c
19 changed files with 329 additions and 280 deletions

View File

@ -1,21 +1,23 @@
package gui package gui
import "github.com/jesseduffield/lazygit/pkg/gui/types"
func (gui *Gui) branchesRenderToMain() error { func (gui *Gui) branchesRenderToMain() error {
var task updateTask var task types.UpdateTask
branch := gui.State.Contexts.Branches.GetSelected() branch := gui.State.Contexts.Branches.GetSelected()
if branch == nil { if branch == nil {
task = NewRenderStringTask(gui.c.Tr.NoBranchesThisRepo) task = types.NewRenderStringTask(gui.c.Tr.NoBranchesThisRepo)
} else { } else {
cmdObj := gui.git.Branch.GetGraphCmdObj(branch.FullRefName()) cmdObj := gui.git.Branch.GetGraphCmdObj(branch.FullRefName())
task = NewRunPtyTask(cmdObj.GetCmd()) task = types.NewRunPtyTask(cmdObj.GetCmd())
} }
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.normalMainContextPair(), Pair: gui.c.MainViewPairs().Normal,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: gui.c.Tr.LogTitle, Title: gui.c.Tr.LogTitle,
task: task, Task: task,
}, },
}) })
} }

View File

@ -16,20 +16,20 @@ func (gui *Gui) commitFilesRenderToMain() error {
from, reverse := gui.State.Modes.Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName()) from, reverse := gui.State.Modes.Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName())
cmdObj := gui.git.WorkingTree.ShowFileDiffCmdObj(from, to, reverse, node.GetPath(), false) cmdObj := gui.git.WorkingTree.ShowFileDiffCmdObj(from, to, reverse, node.GetPath(), false)
task := NewRunPtyTask(cmdObj.GetCmd()) task := types.NewRunPtyTask(cmdObj.GetCmd())
pair := gui.normalMainContextPair() pair := gui.c.MainViewPairs().Normal
if node.File != nil { if node.File != nil {
pair = gui.patchBuildingMainContextPair() pair = gui.c.MainViewPairs().PatchBuilding
} }
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: pair, Pair: pair,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: gui.Tr.Patch, Title: gui.Tr.Patch,
task: task, Task: task,
}, },
secondary: gui.secondaryPatchPanelUpdateOpts(), Secondary: gui.secondaryPatchPanelUpdateOpts(),
}) })
} }

View File

@ -2,6 +2,7 @@ package gui
import ( import (
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
) )
@ -29,32 +30,32 @@ func (gui *Gui) onCommitFocus() error {
} }
func (gui *Gui) branchCommitsRenderToMain() error { func (gui *Gui) branchCommitsRenderToMain() error {
var task updateTask var task types.UpdateTask
commit := gui.State.Contexts.LocalCommits.GetSelected() commit := gui.State.Contexts.LocalCommits.GetSelected()
if commit == nil { if commit == nil {
task = NewRenderStringTask(gui.c.Tr.NoCommitsThisBranch) task = types.NewRenderStringTask(gui.c.Tr.NoCommitsThisBranch)
} else { } else {
cmdObj := gui.git.Commit.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath()) cmdObj := gui.git.Commit.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath())
task = NewRunPtyTask(cmdObj.GetCmd()) task = types.NewRunPtyTask(cmdObj.GetCmd())
} }
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.normalMainContextPair(), Pair: gui.c.MainViewPairs().Normal,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: "Patch", Title: "Patch",
task: task, Task: task,
}, },
secondary: gui.secondaryPatchPanelUpdateOpts(), Secondary: gui.secondaryPatchPanelUpdateOpts(),
}) })
} }
func (gui *Gui) secondaryPatchPanelUpdateOpts() *viewUpdateOpts { func (gui *Gui) secondaryPatchPanelUpdateOpts() *types.ViewUpdateOpts {
if gui.git.Patch.PatchManager.Active() { if gui.git.Patch.PatchManager.Active() {
patch := gui.git.Patch.PatchManager.RenderAggregatedPatchColored(false) patch := gui.git.Patch.PatchManager.RenderAggregatedPatchColored(false)
return &viewUpdateOpts{ return &types.ViewUpdateOpts{
task: NewRenderStringWithoutScrollTask(patch), Task: types.NewRenderStringWithoutScrollTask(patch),
title: gui.Tr.CustomPatch, Title: gui.Tr.CustomPatch,
} }
} }

View File

@ -18,13 +18,13 @@ func (gui *Gui) renderDiff() error {
cmdObj := gui.os.Cmd.New( cmdObj := gui.os.Cmd.New(
fmt.Sprintf("git diff --submodule --no-ext-diff --color %s", gui.diffStr()), fmt.Sprintf("git diff --submodule --no-ext-diff --color %s", gui.diffStr()),
) )
task := NewRunPtyTask(cmdObj.GetCmd()) task := types.NewRunPtyTask(cmdObj.GetCmd())
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.normalMainContextPair(), Pair: gui.c.MainViewPairs().Normal,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: "Diff", Title: "Diff",
task: task, Task: task,
}, },
}) })
} }

View File

@ -4,6 +4,7 @@ import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/filetree" "github.com/jesseduffield/lazygit/pkg/gui/filetree"
"github.com/jesseduffield/lazygit/pkg/gui/types"
) )
func (gui *Gui) getSelectedFileNode() *filetree.FileNode { func (gui *Gui) getSelectedFileNode() *filetree.FileNode {
@ -22,11 +23,11 @@ func (gui *Gui) filesRenderToMain() error {
node := gui.getSelectedFileNode() node := gui.getSelectedFileNode()
if node == nil { if node == nil {
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.normalMainContextPair(), Pair: gui.c.MainViewPairs().Normal,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: gui.c.Tr.DiffTitle, Title: gui.c.Tr.DiffTitle,
task: NewRenderStringTask(gui.c.Tr.NoChangedFiles), Task: types.NewRenderStringTask(gui.c.Tr.NoChangedFiles),
}, },
}) })
} }
@ -44,9 +45,9 @@ func (gui *Gui) filesRenderToMain() error {
gui.helpers.MergeConflicts.ResetMergeState() gui.helpers.MergeConflicts.ResetMergeState()
pair := gui.normalMainContextPair() pair := gui.c.MainViewPairs().Normal
if node.File != nil { if node.File != nil {
pair = gui.stagingMainContextPair() pair = gui.c.MainViewPairs().Staging
} }
split := gui.c.UserConfig.Gui.SplitDiff == "always" || (node.GetHasUnstagedChanges() && node.GetHasStagedChanges()) split := gui.c.UserConfig.Gui.SplitDiff == "always" || (node.GetHasUnstagedChanges() && node.GetHasStagedChanges())
@ -57,11 +58,11 @@ func (gui *Gui) filesRenderToMain() error {
if mainShowsStaged { if mainShowsStaged {
title = gui.c.Tr.StagedChanges title = gui.c.Tr.StagedChanges
} }
refreshOpts := refreshMainOpts{ refreshOpts := types.RefreshMainOpts{
pair: pair, Pair: pair,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
task: NewRunPtyTask(cmdObj.GetCmd()), Task: types.NewRunPtyTask(cmdObj.GetCmd()),
title: title, Title: title,
}, },
} }
@ -73,13 +74,13 @@ func (gui *Gui) filesRenderToMain() error {
title = gui.c.Tr.UnstagedChanges title = gui.c.Tr.UnstagedChanges
} }
refreshOpts.secondary = &viewUpdateOpts{ refreshOpts.Secondary = &types.ViewUpdateOpts{
title: title, Title: title,
task: NewRunPtyTask(cmdObj.GetCmd()), Task: types.NewRunPtyTask(cmdObj.GetCmd()),
} }
} }
return gui.refreshMainViews(refreshOpts) return gui.c.RenderToMainViews(refreshOpts)
} }
func (gui *Gui) getSetTextareaTextFn(getView func() *gocui.View) func(string) { func (gui *Gui) getSetTextareaTextFn(getView func() *gocui.View) func(string) {

View File

@ -89,3 +89,16 @@ func (self *guiCommon) OpenSearch() {
func (self *guiCommon) OnUIThread(f func() error) { func (self *guiCommon) OnUIThread(f func() error) {
self.gui.onUIThread(f) self.gui.onUIThread(f)
} }
func (self *guiCommon) RenderToMainViews(opts types.RefreshMainOpts) error {
return self.gui.refreshMainViews(opts)
}
func (self *guiCommon) MainViewPairs() types.MainViewPairs {
return types.MainViewPairs{
Normal: self.gui.normalMainContextPair(),
Staging: self.gui.stagingMainContextPair(),
PatchBuilding: self.gui.patchBuildingMainContextPair(),
MergeConflicts: self.gui.mergingMainContextPair(),
}
}

View File

@ -1,124 +1,48 @@
package gui package gui
import ( import (
"os/exec"
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
) )
type viewUpdateOpts struct { func (gui *Gui) runTaskForView(view *gocui.View, task types.UpdateTask) error {
title string
task updateTask
}
type refreshMainOpts struct {
pair MainContextPair
main *viewUpdateOpts
secondary *viewUpdateOpts
}
type updateTask interface {
IsUpdateTask()
}
type renderStringTask struct {
str string
}
func (t *renderStringTask) IsUpdateTask() {}
func NewRenderStringTask(str string) *renderStringTask {
return &renderStringTask{str: str}
}
type renderStringWithoutScrollTask struct {
str string
}
func (t *renderStringWithoutScrollTask) IsUpdateTask() {}
func NewRenderStringWithoutScrollTask(str string) *renderStringWithoutScrollTask {
return &renderStringWithoutScrollTask{str: str}
}
type renderStringWithScrollTask struct {
str string
originX int
originY int
}
func (t *renderStringWithScrollTask) IsUpdateTask() {}
func NewRenderStringWithScrollTask(str string, originX int, originY int) *renderStringWithScrollTask {
return &renderStringWithScrollTask{str: str, originX: originX, originY: originY}
}
type runCommandTask struct {
cmd *exec.Cmd
prefix string
}
func (t *runCommandTask) IsUpdateTask() {}
func NewRunCommandTask(cmd *exec.Cmd) *runCommandTask {
return &runCommandTask{cmd: cmd}
}
func NewRunCommandTaskWithPrefix(cmd *exec.Cmd, prefix string) *runCommandTask {
return &runCommandTask{cmd: cmd, prefix: prefix}
}
type runPtyTask struct {
cmd *exec.Cmd
prefix string
}
func (t *runPtyTask) IsUpdateTask() {}
func NewRunPtyTask(cmd *exec.Cmd) *runPtyTask {
return &runPtyTask{cmd: cmd}
}
func (gui *Gui) runTaskForView(view *gocui.View, task updateTask) error {
switch v := task.(type) { switch v := task.(type) {
case *renderStringTask: case *types.RenderStringTask:
return gui.newStringTask(view, v.str) return gui.newStringTask(view, v.Str)
case *renderStringWithoutScrollTask: case *types.RenderStringWithoutScrollTask:
return gui.newStringTaskWithoutScroll(view, v.str) return gui.newStringTaskWithoutScroll(view, v.Str)
case *renderStringWithScrollTask: case *types.RenderStringWithScrollTask:
return gui.newStringTaskWithScroll(view, v.str, v.originX, v.originY) return gui.newStringTaskWithScroll(view, v.Str, v.OriginX, v.OriginY)
case *runCommandTask: case *types.RunCommandTask:
return gui.newCmdTask(view, v.cmd, v.prefix) return gui.newCmdTask(view, v.Cmd, v.Prefix)
case *runPtyTask: case *types.RunPtyTask:
return gui.newPtyTask(view, v.cmd, v.prefix) return gui.newPtyTask(view, v.Cmd, v.Prefix)
} }
return nil return nil
} }
func (gui *Gui) moveMainContextPairToTop(pair MainContextPair) { func (gui *Gui) moveMainContextPairToTop(pair types.MainContextPair) {
gui.setWindowContext(pair.main) gui.setWindowContext(pair.Main)
gui.moveToTopOfWindow(pair.main) gui.moveToTopOfWindow(pair.Main)
if pair.secondary != nil { if pair.Secondary != nil {
gui.setWindowContext(pair.secondary) gui.setWindowContext(pair.Secondary)
gui.moveToTopOfWindow(pair.secondary) gui.moveToTopOfWindow(pair.Secondary)
} }
} }
func (gui *Gui) refreshMainView(opts *viewUpdateOpts, context types.Context) error { func (gui *Gui) RefreshMainView(opts *types.ViewUpdateOpts, context types.Context) error {
view := context.GetView() view := context.GetView()
if opts.title != "" { if opts.Title != "" {
view.Title = opts.title view.Title = opts.Title
} }
if err := gui.runTaskForView(view, opts.task); err != nil { if err := gui.runTaskForView(view, opts.Task); err != nil {
gui.c.Log.Error(err) gui.c.Log.Error(err)
return nil return nil
} }
@ -126,41 +50,36 @@ func (gui *Gui) refreshMainView(opts *viewUpdateOpts, context types.Context) err
return nil return nil
} }
type MainContextPair struct { func (gui *Gui) normalMainContextPair() types.MainContextPair {
main types.Context return types.NewMainContextPair(
secondary types.Context gui.State.Contexts.Normal,
gui.State.Contexts.NormalSecondary,
)
} }
func (gui *Gui) normalMainContextPair() MainContextPair { func (gui *Gui) stagingMainContextPair() types.MainContextPair {
return MainContextPair{ return types.NewMainContextPair(
main: gui.State.Contexts.Normal, gui.State.Contexts.Staging,
secondary: gui.State.Contexts.NormalSecondary, gui.State.Contexts.StagingSecondary,
} )
} }
func (gui *Gui) stagingMainContextPair() MainContextPair { func (gui *Gui) patchBuildingMainContextPair() types.MainContextPair {
return MainContextPair{ return types.NewMainContextPair(
main: gui.State.Contexts.Staging, gui.State.Contexts.CustomPatchBuilder,
secondary: gui.State.Contexts.StagingSecondary, gui.State.Contexts.CustomPatchBuilderSecondary,
} )
} }
func (gui *Gui) patchBuildingMainContextPair() MainContextPair { func (gui *Gui) mergingMainContextPair() types.MainContextPair {
return MainContextPair{ return types.NewMainContextPair(
main: gui.State.Contexts.CustomPatchBuilder, gui.State.Contexts.MergeConflicts,
secondary: gui.State.Contexts.CustomPatchBuilderSecondary, nil,
} )
} }
func (gui *Gui) mergingMainContextPair() MainContextPair { func (gui *Gui) allMainContextPairs() []types.MainContextPair {
return MainContextPair{ return []types.MainContextPair{
main: gui.State.Contexts.MergeConflicts,
secondary: nil,
}
}
func (gui *Gui) allMainContextPairs() []MainContextPair {
return []MainContextPair{
gui.normalMainContextPair(), gui.normalMainContextPair(),
gui.stagingMainContextPair(), gui.stagingMainContextPair(),
gui.patchBuildingMainContextPair(), gui.patchBuildingMainContextPair(),
@ -168,34 +87,34 @@ func (gui *Gui) allMainContextPairs() []MainContextPair {
} }
} }
func (gui *Gui) refreshMainViews(opts refreshMainOpts) error { func (gui *Gui) refreshMainViews(opts types.RefreshMainOpts) error {
// need to reset scroll positions of all other main views // need to reset scroll positions of all other main views
for _, pair := range gui.allMainContextPairs() { for _, pair := range gui.allMainContextPairs() {
if pair.main != opts.pair.main { if pair.Main != opts.Pair.Main {
_ = pair.main.GetView().SetOrigin(0, 0) _ = pair.Main.GetView().SetOrigin(0, 0)
} }
if pair.secondary != nil && pair.secondary != opts.pair.secondary { if pair.Secondary != nil && pair.Secondary != opts.Pair.Secondary {
_ = pair.secondary.GetView().SetOrigin(0, 0) _ = pair.Secondary.GetView().SetOrigin(0, 0)
} }
} }
if opts.main != nil { if opts.Main != nil {
if err := gui.refreshMainView(opts.main, opts.pair.main); err != nil { if err := gui.RefreshMainView(opts.Main, opts.Pair.Main); err != nil {
return err return err
} }
} }
if opts.secondary != nil { if opts.Secondary != nil {
if err := gui.refreshMainView(opts.secondary, opts.pair.secondary); err != nil { if err := gui.RefreshMainView(opts.Secondary, opts.Pair.Secondary); err != nil {
return err return err
} }
} else if opts.pair.secondary != nil { } else if opts.Pair.Secondary != nil {
opts.pair.secondary.GetView().Clear() opts.Pair.Secondary.GetView().Clear()
} }
gui.moveMainContextPairToTop(opts.pair) gui.moveMainContextPairToTop(opts.Pair)
gui.splitMainPanel(opts.secondary != nil) gui.splitMainPanel(opts.Secondary != nil)
return nil return nil
} }

View File

@ -107,13 +107,13 @@ func (gui *Gui) handleCreateRecentReposMenu() error {
func (gui *Gui) handleShowAllBranchLogs() error { func (gui *Gui) handleShowAllBranchLogs() error {
cmdObj := gui.git.Branch.AllBranchesLogCmdObj() cmdObj := gui.git.Branch.AllBranchesLogCmdObj()
task := NewRunPtyTask(cmdObj.GetCmd()) task := types.NewRunPtyTask(cmdObj.GetCmd())
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.normalMainContextPair(), Pair: gui.c.MainViewPairs().Normal,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: gui.c.Tr.LogTitle, Title: gui.c.Tr.LogTitle,
task: task, Task: task,
}, },
}) })
} }

View File

@ -1,21 +1,23 @@
package gui package gui
import "github.com/jesseduffield/lazygit/pkg/gui/types"
func (gui *Gui) reflogCommitsRenderToMain() error { func (gui *Gui) reflogCommitsRenderToMain() error {
commit := gui.State.Contexts.ReflogCommits.GetSelected() commit := gui.State.Contexts.ReflogCommits.GetSelected()
var task updateTask var task types.UpdateTask
if commit == nil { if commit == nil {
task = NewRenderStringTask("No reflog history") task = types.NewRenderStringTask("No reflog history")
} else { } else {
cmdObj := gui.git.Commit.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath()) cmdObj := gui.git.Commit.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath())
task = NewRunPtyTask(cmdObj.GetCmd()) task = types.NewRunPtyTask(cmdObj.GetCmd())
} }
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.normalMainContextPair(), Pair: gui.c.MainViewPairs().Normal,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: "Reflog Entry", Title: "Reflog Entry",
task: task, Task: task,
}, },
}) })
} }

View File

@ -618,15 +618,15 @@ func (gui *Gui) refreshStagingPanel(focusOpts types.OnFocusOpts) error {
return gui.c.PushContext(mainContext, focusOpts) return gui.c.PushContext(mainContext, focusOpts)
} }
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.stagingMainContextPair(), Pair: gui.c.MainViewPairs().Staging,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
task: NewRenderStringWithoutScrollTask(mainContent), Task: types.NewRenderStringWithoutScrollTask(mainContent),
title: gui.Tr.UnstagedChanges, Title: gui.Tr.UnstagedChanges,
}, },
secondary: &viewUpdateOpts{ Secondary: &types.ViewUpdateOpts{
task: NewRenderStringWithoutScrollTask(secondaryContent), Task: types.NewRenderStringWithoutScrollTask(secondaryContent),
title: gui.Tr.StagedChanges, Title: gui.Tr.StagedChanges,
}, },
}) })
} }
@ -680,15 +680,15 @@ func (gui *Gui) refreshPatchBuildingPanel(opts types.OnFocusOpts) error {
mainContent := context.GetContentToRender(true) mainContent := context.GetContentToRender(true)
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.patchBuildingMainContextPair(), Pair: gui.c.MainViewPairs().PatchBuilding,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
task: NewRenderStringWithoutScrollTask(mainContent), Task: types.NewRenderStringWithoutScrollTask(mainContent),
title: gui.Tr.Patch, Title: gui.Tr.Patch,
}, },
secondary: &viewUpdateOpts{ Secondary: &types.ViewUpdateOpts{
task: NewRenderStringWithoutScrollTask(secondaryDiff), Task: types.NewRenderStringWithoutScrollTask(secondaryDiff),
title: gui.Tr.CustomPatch, Title: gui.Tr.CustomPatch,
}, },
}) })
} }
@ -696,18 +696,18 @@ func (gui *Gui) refreshPatchBuildingPanel(opts types.OnFocusOpts) error {
func (gui *Gui) refreshMergePanel(isFocused bool) error { func (gui *Gui) refreshMergePanel(isFocused bool) error {
content := gui.State.Contexts.MergeConflicts.GetContentToRender(isFocused) content := gui.State.Contexts.MergeConflicts.GetContentToRender(isFocused)
var task updateTask var task types.UpdateTask
if gui.State.Contexts.MergeConflicts.IsUserScrolling() { if gui.State.Contexts.MergeConflicts.IsUserScrolling() {
task = NewRenderStringWithoutScrollTask(content) task = types.NewRenderStringWithoutScrollTask(content)
} else { } else {
originY := gui.State.Contexts.MergeConflicts.GetOriginY() originY := gui.State.Contexts.MergeConflicts.GetOriginY()
task = NewRenderStringWithScrollTask(content, 0, originY) task = types.NewRenderStringWithScrollTask(content, 0, originY)
} }
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.mergingMainContextPair(), Pair: gui.c.MainViewPairs().MergeConflicts,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
task: task, Task: task,
}, },
}) })
} }

View File

@ -1,20 +1,22 @@
package gui package gui
import "github.com/jesseduffield/lazygit/pkg/gui/types"
func (gui *Gui) remoteBranchesRenderToMain() error { func (gui *Gui) remoteBranchesRenderToMain() error {
var task updateTask var task types.UpdateTask
remoteBranch := gui.State.Contexts.RemoteBranches.GetSelected() remoteBranch := gui.State.Contexts.RemoteBranches.GetSelected()
if remoteBranch == nil { if remoteBranch == nil {
task = NewRenderStringTask("No branches for this remote") task = types.NewRenderStringTask("No branches for this remote")
} else { } else {
cmdObj := gui.git.Branch.GetGraphCmdObj(remoteBranch.FullRefName()) cmdObj := gui.git.Branch.GetGraphCmdObj(remoteBranch.FullRefName())
task = NewRunCommandTask(cmdObj.GetCmd()) task = types.NewRunCommandTask(cmdObj.GetCmd())
} }
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.normalMainContextPair(), Pair: gui.c.MainViewPairs().Normal,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: "Remote Branch", Title: "Remote Branch",
task: task, Task: task,
}, },
}) })
} }

View File

@ -5,24 +5,25 @@ import (
"strings" "strings"
"github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/gui/types"
) )
// list panel functions // list panel functions
func (gui *Gui) remotesRenderToMain() error { func (gui *Gui) remotesRenderToMain() error {
var task updateTask var task types.UpdateTask
remote := gui.State.Contexts.Remotes.GetSelected() remote := gui.State.Contexts.Remotes.GetSelected()
if remote == nil { if remote == nil {
task = NewRenderStringTask("No remotes") task = types.NewRenderStringTask("No remotes")
} else { } else {
task = NewRenderStringTask(fmt.Sprintf("%s\nUrls:\n%s", style.FgGreen.Sprint(remote.Name), strings.Join(remote.Urls, "\n"))) task = types.NewRenderStringTask(fmt.Sprintf("%s\nUrls:\n%s", style.FgGreen.Sprint(remote.Name), strings.Join(remote.Urls, "\n")))
} }
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.normalMainContextPair(), Pair: gui.c.MainViewPairs().Normal,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: "Remote", Title: "Remote",
task: task, Task: task,
}, },
}) })
} }

View File

@ -1,19 +1,21 @@
package gui package gui
import "github.com/jesseduffield/lazygit/pkg/gui/types"
func (gui *Gui) stashRenderToMain() error { func (gui *Gui) stashRenderToMain() error {
var task updateTask var task types.UpdateTask
stashEntry := gui.State.Contexts.Stash.GetSelected() stashEntry := gui.State.Contexts.Stash.GetSelected()
if stashEntry == nil { if stashEntry == nil {
task = NewRenderStringTask(gui.c.Tr.NoStashEntries) task = types.NewRenderStringTask(gui.c.Tr.NoStashEntries)
} else { } else {
task = NewRunPtyTask(gui.git.Stash.ShowStashEntryCmdObj(stashEntry.Index).GetCmd()) task = types.NewRunPtyTask(gui.git.Stash.ShowStashEntryCmdObj(stashEntry.Index).GetCmd())
} }
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.normalMainContextPair(), Pair: gui.c.MainViewPairs().Normal,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: "Stash", Title: "Stash",
task: task, Task: task,
}, },
}) })
} }

View File

@ -87,11 +87,11 @@ func (gui *Gui) statusRenderToMain() error {
style.FgMagenta.Sprintf("Become a sponsor: %s", constants.Links.Donate), // caffeine ain't free style.FgMagenta.Sprintf("Become a sponsor: %s", constants.Links.Donate), // caffeine ain't free
}, "\n\n") }, "\n\n")
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.normalMainContextPair(), Pair: gui.c.MainViewPairs().Normal,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: gui.c.Tr.StatusTitle, Title: gui.c.Tr.StatusTitle,
task: NewRenderStringTask(dashboardString), Task: types.NewRenderStringTask(dashboardString),
}, },
}) })
} }

View File

@ -1,23 +1,25 @@
package gui package gui
import "github.com/jesseduffield/lazygit/pkg/gui/types"
// list panel functions // list panel functions
func (gui *Gui) subCommitsRenderToMain() error { func (gui *Gui) subCommitsRenderToMain() error {
commit := gui.State.Contexts.SubCommits.GetSelected() commit := gui.State.Contexts.SubCommits.GetSelected()
var task updateTask var task types.UpdateTask
if commit == nil { if commit == nil {
task = NewRenderStringTask("No commits") task = types.NewRenderStringTask("No commits")
} else { } else {
cmdObj := gui.git.Commit.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath()) cmdObj := gui.git.Commit.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath())
task = NewRunPtyTask(cmdObj.GetCmd()) task = types.NewRunPtyTask(cmdObj.GetCmd())
} }
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.normalMainContextPair(), Pair: gui.c.MainViewPairs().Normal,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: "Commit", Title: "Commit",
task: task, Task: task,
}, },
}) })
} }

View File

@ -6,13 +6,14 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/gui/types"
) )
func (gui *Gui) submodulesRenderToMain() error { func (gui *Gui) submodulesRenderToMain() error {
var task updateTask var task types.UpdateTask
submodule := gui.State.Contexts.Submodules.GetSelected() submodule := gui.State.Contexts.Submodules.GetSelected()
if submodule == nil { if submodule == nil {
task = NewRenderStringTask("No submodules") task = types.NewRenderStringTask("No submodules")
} else { } else {
prefix := fmt.Sprintf( prefix := fmt.Sprintf(
"Name: %s\nPath: %s\nUrl: %s\n\n", "Name: %s\nPath: %s\nUrl: %s\n\n",
@ -23,18 +24,18 @@ func (gui *Gui) submodulesRenderToMain() error {
file := gui.helpers.WorkingTree.FileForSubmodule(submodule) file := gui.helpers.WorkingTree.FileForSubmodule(submodule)
if file == nil { if file == nil {
task = NewRenderStringTask(prefix) task = types.NewRenderStringTask(prefix)
} else { } else {
cmdObj := gui.git.WorkingTree.WorktreeFileDiffCmdObj(file, false, !file.HasUnstagedChanges && file.HasStagedChanges, gui.IgnoreWhitespaceInDiffView) cmdObj := gui.git.WorkingTree.WorktreeFileDiffCmdObj(file, false, !file.HasUnstagedChanges && file.HasStagedChanges, gui.IgnoreWhitespaceInDiffView)
task = NewRunCommandTaskWithPrefix(cmdObj.GetCmd(), prefix) task = types.NewRunCommandTaskWithPrefix(cmdObj.GetCmd(), prefix)
} }
} }
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.normalMainContextPair(), Pair: gui.c.MainViewPairs().Normal,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: "Submodule", Title: "Submodule",
task: task, Task: task,
}, },
}) })
} }

View File

@ -1,20 +1,22 @@
package gui package gui
import "github.com/jesseduffield/lazygit/pkg/gui/types"
func (gui *Gui) tagsRenderToMain() error { func (gui *Gui) tagsRenderToMain() error {
var task updateTask var task types.UpdateTask
tag := gui.State.Contexts.Tags.GetSelected() tag := gui.State.Contexts.Tags.GetSelected()
if tag == nil { if tag == nil {
task = NewRenderStringTask("No tags") task = types.NewRenderStringTask("No tags")
} else { } else {
cmdObj := gui.git.Branch.GetGraphCmdObj(tag.FullRefName()) cmdObj := gui.git.Branch.GetGraphCmdObj(tag.FullRefName())
task = NewRunCommandTask(cmdObj.GetCmd()) task = types.NewRunCommandTask(cmdObj.GetCmd())
} }
return gui.refreshMainViews(refreshMainOpts{ return gui.c.RenderToMainViews(types.RefreshMainOpts{
pair: gui.normalMainContextPair(), Pair: gui.c.MainViewPairs().Normal,
main: &viewUpdateOpts{ Main: &types.ViewUpdateOpts{
title: "Tag", Title: "Tag",
task: task, Task: task,
}, },
}) })
} }

View File

@ -28,6 +28,12 @@ type IGuiCommon interface {
PostRefreshUpdate(Context) error PostRefreshUpdate(Context) error
// this just re-renders the screen // this just re-renders the screen
Render() Render()
// allows rendering to main views (i.e. the ones to the right of the side panel)
// in such a way that avoids concurrency issues when there are slow commands
// to display the output of
RenderToMainViews(opts RefreshMainOpts) error
// used purely for the sake of RenderToMainViews to provide the pair of main views we want to render to
MainViewPairs() MainViewPairs
// returns true if command completed successfully // returns true if command completed successfully
RunSubprocess(cmdObj oscommands.ICmdObj) (bool, error) RunSubprocess(cmdObj oscommands.ICmdObj) (bool, error)

View File

@ -0,0 +1,95 @@
package types
import (
"os/exec"
)
type MainContextPair struct {
Main Context
Secondary Context
}
func NewMainContextPair(main Context, secondary Context) MainContextPair {
return MainContextPair{Main: main, Secondary: secondary}
}
type MainViewPairs struct {
Normal MainContextPair
MergeConflicts MainContextPair
Staging MainContextPair
PatchBuilding MainContextPair
}
type ViewUpdateOpts struct {
Title string
Task UpdateTask
}
type RefreshMainOpts struct {
Pair MainContextPair
Main *ViewUpdateOpts
Secondary *ViewUpdateOpts
}
type UpdateTask interface {
IsUpdateTask()
}
type RenderStringTask struct {
Str string
}
func (t *RenderStringTask) IsUpdateTask() {}
func NewRenderStringTask(str string) *RenderStringTask {
return &RenderStringTask{Str: str}
}
type RenderStringWithoutScrollTask struct {
Str string
}
func (t *RenderStringWithoutScrollTask) IsUpdateTask() {}
func NewRenderStringWithoutScrollTask(str string) *RenderStringWithoutScrollTask {
return &RenderStringWithoutScrollTask{Str: str}
}
type RenderStringWithScrollTask struct {
Str string
OriginX int
OriginY int
}
func (t *RenderStringWithScrollTask) IsUpdateTask() {}
func NewRenderStringWithScrollTask(str string, originX int, originY int) *RenderStringWithScrollTask {
return &RenderStringWithScrollTask{Str: str, OriginX: originX, OriginY: originY}
}
type RunCommandTask struct {
Cmd *exec.Cmd
Prefix string
}
func (t *RunCommandTask) IsUpdateTask() {}
func NewRunCommandTask(cmd *exec.Cmd) *RunCommandTask {
return &RunCommandTask{Cmd: cmd}
}
func NewRunCommandTaskWithPrefix(cmd *exec.Cmd, prefix string) *RunCommandTask {
return &RunCommandTask{Cmd: cmd, Prefix: prefix}
}
type RunPtyTask struct {
Cmd *exec.Cmd
Prefix string
}
func (t *RunPtyTask) IsUpdateTask() {}
func NewRunPtyTask(cmd *exec.Cmd) *RunPtyTask {
return &RunPtyTask{Cmd: cmd}
}