/
githubmirror
/
lazygit
Обзор
Документация
Войти
/
githubmirror
/
lazygit
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
pkg/gui/side_panels.go
137 строк
5 KB
Stefan Haller
Assign the transient contexts' initial windows from the side panel config
17 июл 2026, 13:07
17 июл 2026, 13:07
74a77e5
Код
Авторство
О чём код?
package gui import ( "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/samber/lo" ) // sidePanelViewNames maps each gui.sidePanels name to the gocui view it controls. // A panel's window name is the name of its first tab, so for a panel's first tab // this also gives the default view of its window. The keys must match // config.ValidSidePanelTabs (enforced by a test). var sidePanelViewNames = map[string]string{ "status": "status", "files": "files", "worktrees": "worktrees", "submodules": "submodules", "branches": "localBranches", "remotes": "remotes", "tags": "tags", "commits": "commits", "reflog": "reflogCommits", "stash": "stash", } // sidePanelTabTitles maps each gui.sidePanels name to the title shown on its tab. func (gui *Gui) sidePanelTabTitles() map[string]string { tr := gui.c.Tr return map[string]string{ "status": tr.StatusTitle, "files": tr.FilesTitle, "worktrees": tr.WorktreesTitle, "submodules": tr.SubmodulesTitle, "branches": tr.LocalBranchesTitle, "remotes": tr.RemotesTitle, "tags": tr.TagsTitle, "commits": tr.CommitsTitle, "reflog": tr.ReflogCommitsTitle, "stash": tr.StashTitle, } } // sidePanelContexts maps each gui.sidePanels name to the context it controls. func sidePanelContexts(contextTree *context.ContextTree) map[string]types.Context { return map[string]types.Context{ "status": contextTree.Status, "files": contextTree.Files, "worktrees": contextTree.Worktrees, "submodules": contextTree.Submodules, "branches": contextTree.Branches, "remotes": contextTree.Remotes, "tags": contextTree.Tags, "commits": contextTree.LocalCommits, "reflog": contextTree.ReflogCommits, "stash": contextTree.Stash, } } // applySidePanelConfig (re)assigns each side context's window and resets each // window's default view from the current gui.sidePanels config. It runs against // the current repo's contexts, so gui.State must already be set. We call it on // every repo entry (a repo's per-repo config can differ from the previous one's) // and on a live config reload. func (gui *Gui) applySidePanelConfig() { contextTree := gui.State.Contexts gui.assignSidePanelWindows(contextTree) gui.State.WindowViewNameMap = gui.initialWindowViewNameMap(contextTree) } // moveDefaultTabsToTop brings each panel's first configured tab to the top of // its window, so the configured default tab is the one shown when a panel hasn't // been focused yet (the view z-order is otherwise set from a fixed list that // need not match the configured tab order). func (gui *Gui) moveDefaultTabsToTop() { contexts := sidePanelContexts(gui.State.Contexts) for _, panel := range gui.c.UserConfig().Gui.SidePanels { gui.helpers.Window.MoveToTopOfWindow(contexts[panel[0]]) } } // reloadSidePanels re-applies the side panel config to the current repo after a // live config reload: it reassigns windows and default views, restores each // panel's default tab, and keeps the focused panel in a consistent state. func (gui *Gui) reloadSidePanels() { gui.applySidePanelConfig() gui.moveDefaultTabsToTop() // applySidePanelConfig reset every window to show its first configured tab, // which would leave the focused tab hidden behind its panel's default tab // (the panel would look unfocused even though its tab is selected). Re-focus // the current context so its tab stays shown and highlighted. If the new // config has hidden the focused panel entirely, move focus to the default // side panel instead. current := gui.c.Context().Current() if current.GetKind() != types.SIDE_CONTEXT { return } if lo.Contains(gui.helpers.Window.SideWindows(), current.GetWindowName()) { gui.c.Context().Activate(current, types.OnFocusOpts{}) } else { gui.c.Context().Push(gui.defaultSideContext(), types.OnFocusOpts{}) } } // assignSidePanelWindows sets each side context's window name from the config so // that contexts grouped into one panel share a window (the window name being the // panel's first tab). Side panels the user hasn't listed get their own window // name; since the layout produces no dimensions for those windows, their views // stay hidden rather than overlapping a visible panel. func (gui *Gui) assignSidePanelWindows(contextTree *context.ContextTree) { contexts := sidePanelContexts(contextTree) assigned := make(map[string]bool, len(contexts)) for _, panel := range gui.c.UserConfig().Gui.SidePanels { windowName := panel[0] for _, name := range panel { contexts[name].SetWindowName(windowName) assigned[name] = true } } for name, ctx := range contexts { if !assigned[name] { ctx.SetWindowName(name) } } // The transient contexts take over the window of the context they are // drilled into from, but they need a valid initial window before their // first use. Assign the window hosting branches or commits, respectively; // unlike e.g. remotes, those tabs can't be hidden, so their windows are // always part of the layout. contextTree.RemoteBranches.SetWindowName(contextTree.Branches.GetWindowName()) contextTree.SubCommits.SetWindowName(contextTree.Branches.GetWindowName()) contextTree.CommitFiles.SetWindowName(contextTree.LocalCommits.GetWindowName()) }