mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-11 16:16:28 -04:00
Each command a side panel handles in the focused main view needed its own delegation channel: a HasKeybindings getter, an IBaseContext Add method, a BaseContext field + getter, a baseController nil default, and an attach.go registration — roughly five touch points per command. With three commands (click, stage, toggle-patch) that was already a lot of boilerplate, and it doesn't scale to the discard / copy commands coming next. Replace the three channels with one: a side panel exposes a single FocusedMainViewActions interface via GetFocusedMainViewActions (nil when its diff offers no actions), and the controllers implement that interface directly. The stage and toggle-patch handlers, already unified to a plain error return, become one PrimaryAction method whose meaning is the panel's business (stage for the files panel, patch toggle for the commit panels); the click handler becomes OnClick. MainViewController is now a thin dispatcher: fetch the actions from the panel beneath, call the method. Adding a command is now one interface method, an implementation in the two or three controllers, and a keybinding — no plumbing. The toggle-patch channel did double duty as the "this panel builds a custom patch" signal for the inclusion gutter (shown only beneath a patch-building panel, not the staging files panel). Collapsing the channels removes that proxy, so make the classification explicit on DiffMainViewContext, whose marker method now returns a DiffMainViewType (none / staging / patch-building) instead of being a bare marker. The gutter shows only beneath a panel whose type is patch-building (commit files, local commits, sub-commits, stash). Behavior-preserving. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
112 lines
3.4 KiB
Go
112 lines
3.4 KiB
Go
package context
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/presentation/icons"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
|
"github.com/samber/lo"
|
|
)
|
|
|
|
type CommitFilesContext struct {
|
|
*filetree.CommitFileTreeViewModel
|
|
*ListContextTrait
|
|
*DynamicTitleBuilder
|
|
}
|
|
|
|
var (
|
|
_ types.IListContext = (*CommitFilesContext)(nil)
|
|
_ types.DiffableContext = (*CommitFilesContext)(nil)
|
|
_ types.IFilterableContext = (*CommitFilesContext)(nil)
|
|
_ types.DiffMainViewContext = (*CommitFilesContext)(nil)
|
|
)
|
|
|
|
func (self *CommitFilesContext) GetDiffMainViewType() types.DiffMainViewType {
|
|
return types.DiffMainViewTypePatchBuilding
|
|
}
|
|
|
|
func NewCommitFilesContext(c *ContextCommon) *CommitFilesContext {
|
|
viewModel := filetree.NewCommitFileTreeViewModel(
|
|
func() []*models.CommitFile { return c.Model().CommitFiles },
|
|
c.Common,
|
|
c.UserConfig().Gui.ShowFileTree,
|
|
)
|
|
|
|
getDisplayStrings := func(_ int, _ int) [][]string {
|
|
if viewModel.Len() == 0 {
|
|
return [][]string{{style.FgRed.Sprint("(none)")}}
|
|
}
|
|
|
|
showFileIcons := icons.IsIconEnabled() && c.UserConfig().Gui.ShowFileIcons
|
|
lines := presentation.RenderCommitFileTree(viewModel, c.Git().Patch.PatchBuilder, showFileIcons, &c.UserConfig().Gui.CustomIcons)
|
|
return lo.Map(lines, func(line string, _ int) []string {
|
|
return []string{line}
|
|
})
|
|
}
|
|
|
|
ctx := &CommitFilesContext{
|
|
CommitFileTreeViewModel: viewModel,
|
|
DynamicTitleBuilder: NewDynamicTitleBuilder(c.Tr.CommitFilesDynamicTitle),
|
|
ListContextTrait: &ListContextTrait{
|
|
Context: NewSimpleContext(
|
|
NewBaseContext(NewBaseContextOpts{
|
|
View: c.Views().CommitFiles,
|
|
WindowName: "commits",
|
|
Key: COMMIT_FILES_CONTEXT_KEY,
|
|
Kind: types.SIDE_CONTEXT,
|
|
Focusable: true,
|
|
Transient: true,
|
|
}),
|
|
),
|
|
ListRenderer: ListRenderer{
|
|
list: viewModel,
|
|
getDisplayStrings: getDisplayStrings,
|
|
},
|
|
c: c,
|
|
},
|
|
}
|
|
|
|
return ctx
|
|
}
|
|
|
|
func (self *CommitFilesContext) GetDiffTerminals() []string {
|
|
return []string{self.GetRef().RefName()}
|
|
}
|
|
|
|
func (self *CommitFilesContext) RefForAdjustingLineNumberInDiff() string {
|
|
if refs := self.GetRefRange(); refs != nil {
|
|
return refs.To.RefName()
|
|
}
|
|
return self.GetRef().RefName()
|
|
}
|
|
|
|
func (self *CommitFilesContext) GetFromAndToForDiff() (string, string) {
|
|
return FromAndToForDiff(self.GetRef(), self.GetRefRange())
|
|
}
|
|
|
|
// FromAndToForDiff derives the diff endpoints for a ref (or a range of refs): a range
|
|
// diffs its parent-of-from against to, a single ref its parent against itself. It's
|
|
// shared by the commit files context and by patch building straight from the commits /
|
|
// sub-commits / stash main views, which build a patch for the panel's selected ref.
|
|
func FromAndToForDiff(ref models.Ref, refRange *types.RefRange) (string, string) {
|
|
if refRange != nil {
|
|
return refRange.From.ParentRefName(), refRange.To.RefName()
|
|
}
|
|
return ref.ParentRefName(), ref.RefName()
|
|
}
|
|
|
|
func (self *CommitFilesContext) ReInit(ref models.Ref, refRange *types.RefRange) {
|
|
self.SetRef(ref)
|
|
self.SetRefRange(refRange)
|
|
if refRange != nil {
|
|
self.SetTitleRef(fmt.Sprintf("%s-%s", refRange.From.ShortRefName(), refRange.To.ShortRefName()))
|
|
} else {
|
|
self.SetTitleRef(ref.Description())
|
|
}
|
|
self.GetView().Title = self.Title()
|
|
}
|