1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-04-23 12:18:51 +02:00
lazygit/pkg/gui/main_panels.go
Stefan Haller 8b8343b8a9 Run PTY tasks after layout so that they get the correct view size
This is important when using a pager that draws a horizontal line across the
entire width of the view; when changing from a file or directory that has only
unstaged (or only staged) changes to one that has both, the main view is split
in half, but the PTY task would be run on the view in its old state, so the
horizonal line would be too long and wrap around.
2024-06-23 12:36:40 +02:00

150 lines
3.8 KiB
Go

package gui
import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
func (gui *Gui) runTaskForView(view *gocui.View, task types.UpdateTask) error {
switch v := task.(type) {
case *types.RenderStringTask:
return gui.newStringTask(view, v.Str)
case *types.RenderStringWithoutScrollTask:
return gui.newStringTaskWithoutScroll(view, v.Str)
case *types.RenderStringWithScrollTask:
return gui.newStringTaskWithScroll(view, v.Str, v.OriginX, v.OriginY)
case *types.RunCommandTask:
return gui.newCmdTask(view, v.Cmd, v.Prefix)
case *types.RunPtyTask:
gui.afterLayout(func() error {
return gui.newPtyTask(view, v.Cmd, v.Prefix)
})
return nil
}
return nil
}
func (gui *Gui) moveMainContextPairToTop(pair types.MainContextPair) {
gui.moveMainContextToTop(pair.Main)
if pair.Secondary != nil {
gui.moveMainContextToTop(pair.Secondary)
}
}
func (gui *Gui) moveMainContextToTop(context types.Context) {
gui.helpers.Window.SetWindowContext(context)
view := context.GetView()
topView := gui.helpers.Window.TopViewInWindow(context.GetWindowName(), true)
if topView != nil && topView != view {
// We need to copy the content to avoid a flicker effect: If we're flicking
// through files in the files panel, we use a different view to render the
// files vs the directories, and if you select dir A, then file B, then dir
// C, you'll briefly see dir A's contents again before the view is updated.
// So here we're copying the content from the top window to avoid that
// flicker effect.
gui.g.CopyContent(topView, view)
if err := gui.g.SetViewOnTopOf(view.Name(), topView.Name()); err != nil {
gui.Log.Error(err)
}
}
}
func (gui *Gui) RefreshMainView(opts *types.ViewUpdateOpts, context types.Context) error {
view := context.GetView()
if opts.Title != "" {
view.Title = opts.Title
}
view.Subtitle = opts.SubTitle
if err := gui.runTaskForView(view, opts.Task); err != nil {
gui.c.Log.Error(err)
return nil
}
return nil
}
func (gui *Gui) normalMainContextPair() types.MainContextPair {
return types.NewMainContextPair(
gui.State.Contexts.Normal,
gui.State.Contexts.NormalSecondary,
)
}
func (gui *Gui) stagingMainContextPair() types.MainContextPair {
return types.NewMainContextPair(
gui.State.Contexts.Staging,
gui.State.Contexts.StagingSecondary,
)
}
func (gui *Gui) patchBuildingMainContextPair() types.MainContextPair {
return types.NewMainContextPair(
gui.State.Contexts.CustomPatchBuilder,
gui.State.Contexts.CustomPatchBuilderSecondary,
)
}
func (gui *Gui) mergingMainContextPair() types.MainContextPair {
return types.NewMainContextPair(
gui.State.Contexts.MergeConflicts,
nil,
)
}
func (gui *Gui) allMainContextPairs() []types.MainContextPair {
return []types.MainContextPair{
gui.normalMainContextPair(),
gui.stagingMainContextPair(),
gui.patchBuildingMainContextPair(),
gui.mergingMainContextPair(),
}
}
func (gui *Gui) refreshMainViews(opts types.RefreshMainOpts) error {
// need to reset scroll positions of all other main views
for _, pair := range gui.allMainContextPairs() {
if pair.Main != opts.Pair.Main {
_ = pair.Main.GetView().SetOrigin(0, 0)
}
if pair.Secondary != nil && pair.Secondary != opts.Pair.Secondary {
_ = pair.Secondary.GetView().SetOrigin(0, 0)
}
}
if opts.Main != nil {
if err := gui.RefreshMainView(opts.Main, opts.Pair.Main); err != nil {
return err
}
}
if opts.Secondary != nil {
if err := gui.RefreshMainView(opts.Secondary, opts.Pair.Secondary); err != nil {
return err
}
} else if opts.Pair.Secondary != nil {
opts.Pair.Secondary.GetView().Clear()
}
gui.moveMainContextPairToTop(opts.Pair)
gui.splitMainPanel(opts.Secondary != nil)
return nil
}
func (gui *Gui) splitMainPanel(splitMainPanel bool) {
gui.State.SplitMainPanel = splitMainPanel
}