From c57461a1e652cd0b3e7be91cb502e1b1ea8e8b46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=BCseyin=20Akba=C5=9F?= Date: Wed, 6 May 2026 15:33:11 +0300 Subject: [PATCH 1/2] Add unstaged, staged tabs on [2] Files section --- pkg/gui/gui.go | 8 +++++++ pkg/gui/view_helpers.go | 52 +++++++++++++++++++++++++++++++++++++++++ pkg/gui/views.go | 4 ++++ 3 files changed, 64 insertions(+) diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index ce22f42404b..236debabba7 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -862,6 +862,14 @@ func (gui *Gui) viewTabMap() map[string][]context.TabView { Tab: gui.c.Tr.FilesTitle, ViewName: "files", }, + { + Tab: gui.c.Tr.UnstagedChanges, + ViewName: "files", + }, + { + Tab: gui.c.Tr.StagedChanges, + ViewName: "files", + }, context.TabView{ Tab: gui.c.Tr.WorktreesTitle, ViewName: "worktrees", diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index 453ccd6c932..7a1c7e543c2 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -5,6 +5,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/gocui" "github.com/jesseduffield/lazygit/pkg/gui/context" + "github.com/jesseduffield/lazygit/pkg/gui/filetree" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/tasks" "github.com/jesseduffield/lazygit/pkg/utils" @@ -63,6 +64,12 @@ func (gui *Gui) onViewTabClick(windowName string, tabIndex int) error { return nil } + if windowName == "files" { + if err := gui.applyFilesTab(tabs[tabIndex].Tab); err != nil { + return err + } + } + viewName := tabs[tabIndex].ViewName context, ok := gui.helpers.View.ContextForView(viewName) @@ -114,9 +121,54 @@ func getTabbedView(gui *Gui) *gocui.View { // It safe assumption that only static contexts have tabs context := gui.c.Context().CurrentStatic() view, _ := gui.g.View(context.GetViewName()) + if view != nil && view.Name() == "files" { + view.TabIndex = gui.filesTabIndex() + } return view } +func (gui *Gui) filesTabIndex() int { + if gui.State == nil || gui.State.Contexts == nil || gui.State.Contexts.Files == nil { + return 0 + } + + filter := gui.State.Contexts.Files.GetStatusFilter() + switch filter { + case filetree.DisplayUnstaged: + return 1 + case filetree.DisplayStaged: + return 2 + default: + return 0 + } +} + +func (gui *Gui) applyFilesTab(tabName string) error { + if gui.State == nil || gui.State.Contexts == nil || gui.State.Contexts.Files == nil { + return nil + } + + filesContext := gui.State.Contexts.Files + desiredFilter := filetree.DisplayAll + + switch tabName { + case gui.c.Tr.UnstagedChanges: + desiredFilter = filetree.DisplayUnstaged + case gui.c.Tr.StagedChanges: + desiredFilter = filetree.DisplayStaged + case gui.c.Tr.FilesTitle: + desiredFilter = filetree.DisplayAll + default: + return nil + } + + filesContext.FileTreeViewModel.SetStatusFilter(desiredFilter) + filesContext.GetView().Subtitle = "" + filesContext.GetView().TabIndex = gui.filesTabIndex() + gui.postRefreshUpdate(filesContext) + return nil +} + func (gui *Gui) render() { gui.c.OnUIThread(func() error { return nil }) } diff --git a/pkg/gui/views.go b/pkg/gui/views.go index 09325799893..702d2b8d1a4 100644 --- a/pkg/gui/views.go +++ b/pkg/gui/views.go @@ -271,4 +271,8 @@ func (gui *Gui) configureViewProperties() { } } } + + if gui.Views.Files != nil { + gui.Views.Files.TabIndex = gui.filesTabIndex() + } } From e7de017924710629e09b98c0cc97a65fbf297fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=BCseyin=20Akba=C5=9F?= Date: Wed, 6 May 2026 16:02:52 +0300 Subject: [PATCH 2/2] Add showFileChangeTabs gui option to enable/disable unstaged/staged tabs on [2] Files --- docs/Config.md | 3 +++ pkg/config/user_config.go | 3 +++ pkg/gui/gui.go | 52 ++++++++++++++++++++++----------------- pkg/gui/view_helpers.go | 7 ++++++ 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/docs/Config.md b/docs/Config.md index 9931fda61fe..b6749775302 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -246,6 +246,9 @@ gui: # If true, show jump-to-window keybindings in window titles. showPanelJumps: true + # If true, show separate Unstaged/Staged tabs in the Files window. + showFileChangeTabs: false + # Nerd fonts version to use. # One of: '2' | '3' | empty string (default) # If empty, do not show icons. diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index ddb0c087666..ceab1661168 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -151,6 +151,8 @@ type GuiConfig struct { ShowBottomLine bool `yaml:"showBottomLine"` // If true, show jump-to-window keybindings in window titles. ShowPanelJumps bool `yaml:"showPanelJumps"` + // If true, show separate Unstaged/Staged tabs in the Files window. + ShowFileChangeTabs bool `yaml:"showFileChangeTabs"` // Deprecated: use nerdFontsVersion instead ShowIcons bool `yaml:"showIcons" jsonschema:"deprecated"` // Nerd fonts version to use. @@ -817,6 +819,7 @@ func GetDefaultConfigForPlatform(platform string) *UserConfig { ShowCommandLog: true, ShowBottomLine: true, ShowPanelJumps: true, + ShowFileChangeTabs: false, ShowFileTree: true, ShowRootItemInFileTree: true, FileTreeSortOrder: "mixed", diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 236debabba7..d5104e4f448 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -832,6 +832,35 @@ func (gui *Gui) initGocui(headless bool, test integrationTypes.IntegrationTest) } func (gui *Gui) viewTabMap() map[string][]context.TabView { + filesTabs := []context.TabView{ + { + Tab: gui.c.Tr.FilesTitle, + ViewName: "files", + }, + } + if gui.c.UserConfig().Gui.ShowFileChangeTabs { + filesTabs = append(filesTabs, + context.TabView{ + Tab: gui.c.Tr.UnstagedChanges, + ViewName: "files", + }, + context.TabView{ + Tab: gui.c.Tr.StagedChanges, + ViewName: "files", + }, + ) + } + filesTabs = append(filesTabs, + context.TabView{ + Tab: gui.c.Tr.WorktreesTitle, + ViewName: "worktrees", + }, + context.TabView{ + Tab: gui.c.Tr.SubmodulesTitle, + ViewName: "submodules", + }, + ) + result := map[string][]context.TabView{ "branches": { { @@ -857,28 +886,7 @@ func (gui *Gui) viewTabMap() map[string][]context.TabView { ViewName: "reflogCommits", }, }, - "files": { - { - Tab: gui.c.Tr.FilesTitle, - ViewName: "files", - }, - { - Tab: gui.c.Tr.UnstagedChanges, - ViewName: "files", - }, - { - Tab: gui.c.Tr.StagedChanges, - ViewName: "files", - }, - context.TabView{ - Tab: gui.c.Tr.WorktreesTitle, - ViewName: "worktrees", - }, - { - Tab: gui.c.Tr.SubmodulesTitle, - ViewName: "submodules", - }, - }, + "files": filesTabs, } return result diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index 7a1c7e543c2..e08d182e3f3 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -131,6 +131,9 @@ func (gui *Gui) filesTabIndex() int { if gui.State == nil || gui.State.Contexts == nil || gui.State.Contexts.Files == nil { return 0 } + if !gui.c.UserConfig().Gui.ShowFileChangeTabs { + return 0 + } filter := gui.State.Contexts.Files.GetStatusFilter() switch filter { @@ -148,6 +151,10 @@ func (gui *Gui) applyFilesTab(tabName string) error { return nil } + if !gui.c.UserConfig().Gui.ShowFileChangeTabs { + return nil + } + filesContext := gui.State.Contexts.Files desiredFilter := filetree.DisplayAll