mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-10-05 21:46:49 -04:00
Let the main section show the secondary pane alone
The main section shows one pane or two, which was enough while the second pane only ever accompanied the first. It is about to have to show the second one by itself: the working tree's staged changes are moving there for good, and a file with nothing but staged changes has only that side to show — it should have the whole section rather than sit under an empty pane. So which panes are shown becomes a three-way answer, derived from which of them the render has content for. Behaviour-preserving: nothing renders into the secondary pane alone yet. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6b51922bb9
commit
0dfd7ec1e4
@@ -60,7 +60,7 @@ type WindowArrangementArgs struct {
|
||||
ContentHeightForWindow func(window string) int
|
||||
// Whether the main panel is split (as is the case e.g. when a file has both
|
||||
// staged and unstaged changes)
|
||||
SplitMainPanel bool
|
||||
MainPanes types.MainPanes
|
||||
// The current screen mode (normal, half, full)
|
||||
ScreenMode types.ScreenMode
|
||||
// The content shown on the bottom left of the screen when showing a loader
|
||||
@@ -103,7 +103,7 @@ func (self *WindowArrangementHelper) GetWindowDimensions(informationStr string,
|
||||
ContentHeightForWindow: func(window string) int {
|
||||
return self.windowHelper.GetContextForWindow(window).TotalContentHeight()
|
||||
},
|
||||
SplitMainPanel: repoState.GetSplitMainPanel(),
|
||||
MainPanes: repoState.GetMainPanes(),
|
||||
ScreenMode: repoState.GetScreenMode(),
|
||||
AppStatus: appStatus,
|
||||
InformationStr: informationStr,
|
||||
@@ -215,36 +215,27 @@ func MergeMaps[K comparable, V any](maps ...map[K]V) map[K]V {
|
||||
}
|
||||
|
||||
func mainSectionChildren(args WindowArrangementArgs) []*boxlayout.Box {
|
||||
// if we're not in split mode we can just show the one main panel. Likewise if
|
||||
// the main panel is focused and we're in full-screen mode
|
||||
if !args.SplitMainPanel || (args.ScreenMode == types.SCREEN_FULL && args.CurrentWindow == "main") {
|
||||
return []*boxlayout.Box{
|
||||
{
|
||||
Window: "main",
|
||||
Weight: 1,
|
||||
},
|
||||
mainPane := &boxlayout.Box{Window: "main", Weight: 1}
|
||||
secondaryPane := &boxlayout.Box{Window: "secondary", Weight: 1}
|
||||
|
||||
switch args.MainPanes {
|
||||
case types.MainPaneOnly:
|
||||
return []*boxlayout.Box{mainPane}
|
||||
case types.SecondaryPaneOnly:
|
||||
return []*boxlayout.Box{secondaryPane}
|
||||
case types.BothMainPanes:
|
||||
// In full-screen mode the focused one takes the whole section anyway.
|
||||
if args.ScreenMode == types.SCREEN_FULL {
|
||||
if args.CurrentWindow == "main" {
|
||||
return []*boxlayout.Box{mainPane}
|
||||
}
|
||||
if args.CurrentWindow == "secondary" {
|
||||
return []*boxlayout.Box{secondaryPane}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if args.CurrentWindow == "secondary" && args.ScreenMode == types.SCREEN_FULL {
|
||||
return []*boxlayout.Box{
|
||||
{
|
||||
Window: "secondary",
|
||||
Weight: 1,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return []*boxlayout.Box{
|
||||
{
|
||||
Window: "main",
|
||||
Weight: 1,
|
||||
},
|
||||
{
|
||||
Window: "secondary",
|
||||
Weight: 1,
|
||||
},
|
||||
}
|
||||
return []*boxlayout.Box{mainPane, secondaryPane}
|
||||
}
|
||||
|
||||
func getMidSectionWeights(args WindowArrangementArgs) (int, int) {
|
||||
@@ -382,7 +373,7 @@ func infoSectionChildren(args WindowArrangementArgs) []*boxlayout.Box {
|
||||
}
|
||||
|
||||
func splitMainPanelSideBySide(args WindowArrangementArgs) bool {
|
||||
if !args.SplitMainPanel {
|
||||
if args.MainPanes != types.BothMainPanes {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ func TestGetWindowDimensions(t *testing.T) {
|
||||
// Each panel shows its first tab by default; for the special-cased
|
||||
// panels (status, stash) the view name matches the window name.
|
||||
ActiveViewForWindow: func(window string) string { return window },
|
||||
SplitMainPanel: false,
|
||||
MainPanes: types.MainPaneOnly,
|
||||
ScreenMode: types.SCREEN_NORMAL,
|
||||
AppStatus: "",
|
||||
InformationStr: "information",
|
||||
|
||||
+5
-5
@@ -231,7 +231,7 @@ type GuiRepoState struct {
|
||||
Model *types.Model
|
||||
Modes *types.Modes
|
||||
|
||||
SplitMainPanel bool
|
||||
MainPanes types.MainPanes
|
||||
|
||||
SearchState *types.SearchState
|
||||
// Lets us not load everything at once. Written and read from refresh
|
||||
@@ -321,12 +321,12 @@ func (self *GuiRepoState) GetSearchState() *types.SearchState {
|
||||
return self.SearchState
|
||||
}
|
||||
|
||||
func (self *GuiRepoState) SetSplitMainPanel(value bool) {
|
||||
self.SplitMainPanel = value
|
||||
func (self *GuiRepoState) SetMainPanes(value types.MainPanes) {
|
||||
self.MainPanes = value
|
||||
}
|
||||
|
||||
func (self *GuiRepoState) GetSplitMainPanel() bool {
|
||||
return self.SplitMainPanel
|
||||
func (self *GuiRepoState) GetMainPanes() types.MainPanes {
|
||||
return self.MainPanes
|
||||
}
|
||||
|
||||
func (gui *Gui) onSwitchToNewRepo(startArgs appTypes.StartArgs, contextKey types.ContextKey) error {
|
||||
|
||||
+18
-3
@@ -112,6 +112,8 @@ func (gui *Gui) refreshMainViews(opts types.RefreshMainOpts) {
|
||||
|
||||
if opts.Main != nil {
|
||||
gui.RefreshMainView(opts.Main, opts.Pair.Main)
|
||||
} else {
|
||||
opts.Pair.Main.GetView().Clear()
|
||||
}
|
||||
|
||||
if opts.Secondary != nil {
|
||||
@@ -134,7 +136,20 @@ func (gui *Gui) refreshMainViews(opts types.RefreshMainOpts) {
|
||||
}
|
||||
}
|
||||
|
||||
gui.splitMainPanel(opts.Secondary != nil)
|
||||
gui.setMainPanes(mainPanesFor(opts))
|
||||
}
|
||||
|
||||
// mainPanesFor says which panes the given render occupies: the one it has content for,
|
||||
// or both when it has content for both.
|
||||
func mainPanesFor(opts types.RefreshMainOpts) types.MainPanes {
|
||||
switch {
|
||||
case opts.Secondary == nil:
|
||||
return types.MainPaneOnly
|
||||
case opts.Main == nil:
|
||||
return types.SecondaryPaneOnly
|
||||
default:
|
||||
return types.BothMainPanes
|
||||
}
|
||||
}
|
||||
|
||||
// clampDiffSelectionToContent brings the focused main view's selection back onto the
|
||||
@@ -298,8 +313,8 @@ func (gui *Gui) mainContextForView(view *gocui.View) *context.MainContext {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) splitMainPanel(splitMainPanel bool) {
|
||||
gui.State.SplitMainPanel = splitMainPanel
|
||||
func (gui *Gui) setMainPanes(panes types.MainPanes) {
|
||||
gui.State.MainPanes = panes
|
||||
}
|
||||
|
||||
// reApplySearch runs a search the view holds again over the content a render has just
|
||||
|
||||
@@ -461,8 +461,8 @@ type IRepoStateAccessor interface {
|
||||
SetScreenMode(ScreenMode)
|
||||
InSearchPrompt() bool
|
||||
GetSearchState() *SearchState
|
||||
SetSplitMainPanel(bool)
|
||||
GetSplitMainPanel() bool
|
||||
SetMainPanes(MainPanes)
|
||||
GetMainPanes() MainPanes
|
||||
GetMergeOrRebaseStartedInLazygit() bool
|
||||
SetMergeOrRebaseStartedInLazygit(bool)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,19 @@ func NewMainContextPair(main Context, secondary Context) MainContextPair {
|
||||
return MainContextPair{Main: main, Secondary: secondary}
|
||||
}
|
||||
|
||||
// MainPanes says which of the two panes of the main section are shown. Most content
|
||||
// takes the main pane alone; content with two sides to it — the working tree's
|
||||
// unstaged and staged changes, a commit's diff and the patch built from it — takes
|
||||
// both; and content whose only side is the second one takes the secondary pane alone,
|
||||
// so that it has the whole section rather than sitting under an empty pane.
|
||||
type MainPanes int
|
||||
|
||||
const (
|
||||
MainPaneOnly MainPanes = iota
|
||||
BothMainPanes
|
||||
SecondaryPaneOnly
|
||||
)
|
||||
|
||||
type MainViewPairs struct {
|
||||
Normal MainContextPair
|
||||
MergeConflicts MainContextPair
|
||||
|
||||
Reference in New Issue
Block a user