1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-04-04 22:34:39 +02:00
lazygit/pkg/gui/services/custom_commands/session_state_loader.go
Stefan Haller 2dfc3491bd Rename Name to Path in File and CommitFile
Name was very confusing and misleading.
2025-03-20 12:31:34 +01:00

245 lines
7.4 KiB
Go

package custom_commands
import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/samber/lo"
)
// loads the session state at the time that a custom command is invoked, for use
// in the custom command's template strings
type SessionStateLoader struct {
c *helpers.HelperCommon
refsHelper *helpers.RefsHelper
}
func NewSessionStateLoader(c *helpers.HelperCommon, refsHelper *helpers.RefsHelper) *SessionStateLoader {
return &SessionStateLoader{
c: c,
refsHelper: refsHelper,
}
}
func commitShimFromModelCommit(commit *models.Commit) *Commit {
if commit == nil {
return nil
}
return &Commit{
Hash: commit.Hash,
Sha: commit.Hash,
Name: commit.Name,
Status: commit.Status,
Action: commit.Action,
Tags: commit.Tags,
ExtraInfo: commit.ExtraInfo,
AuthorName: commit.AuthorName,
AuthorEmail: commit.AuthorEmail,
UnixTimestamp: commit.UnixTimestamp,
Divergence: commit.Divergence,
Parents: commit.Parents,
}
}
func fileShimFromModelFile(file *models.File) *File {
if file == nil {
return nil
}
return &File{
Name: file.Path,
PreviousName: file.PreviousPath,
HasStagedChanges: file.HasStagedChanges,
HasUnstagedChanges: file.HasUnstagedChanges,
Tracked: file.Tracked,
Added: file.Added,
Deleted: file.Deleted,
HasMergeConflicts: file.HasMergeConflicts,
HasInlineMergeConflicts: file.HasInlineMergeConflicts,
DisplayString: file.DisplayString,
ShortStatus: file.ShortStatus,
IsWorktree: file.IsWorktree,
}
}
func branchShimFromModelBranch(branch *models.Branch) *Branch {
if branch == nil {
return nil
}
return &Branch{
Name: branch.Name,
DisplayName: branch.DisplayName,
Recency: branch.Recency,
Pushables: branch.AheadForPull,
Pullables: branch.BehindForPull,
AheadForPull: branch.AheadForPull,
BehindForPull: branch.BehindForPull,
AheadForPush: branch.AheadForPush,
BehindForPush: branch.BehindForPush,
UpstreamGone: branch.UpstreamGone,
Head: branch.Head,
DetachedHead: branch.DetachedHead,
UpstreamRemote: branch.UpstreamRemote,
UpstreamBranch: branch.UpstreamBranch,
Subject: branch.Subject,
CommitHash: branch.CommitHash,
}
}
func remoteBranchShimFromModelRemoteBranch(remoteBranch *models.RemoteBranch) *RemoteBranch {
if remoteBranch == nil {
return nil
}
return &RemoteBranch{
Name: remoteBranch.Name,
RemoteName: remoteBranch.RemoteName,
}
}
func remoteShimFromModelRemote(remote *models.Remote) *Remote {
if remote == nil {
return nil
}
return &Remote{
Name: remote.Name,
Urls: remote.Urls,
Branches: lo.Map(remote.Branches, func(branch *models.RemoteBranch, _ int) *RemoteBranch {
return remoteBranchShimFromModelRemoteBranch(branch)
}),
}
}
func tagShimFromModelRemote(tag *models.Tag) *Tag {
if tag == nil {
return nil
}
return &Tag{
Name: tag.Name,
Message: tag.Message,
}
}
func stashEntryShimFromModelRemote(stashEntry *models.StashEntry) *StashEntry {
if stashEntry == nil {
return nil
}
return &StashEntry{
Index: stashEntry.Index,
Recency: stashEntry.Recency,
Name: stashEntry.Name,
}
}
func commitFileShimFromModelRemote(commitFile *models.CommitFile) *CommitFile {
if commitFile == nil {
return nil
}
return &CommitFile{
Name: commitFile.Path,
ChangeStatus: commitFile.ChangeStatus,
}
}
func worktreeShimFromModelRemote(worktree *models.Worktree) *Worktree {
if worktree == nil {
return nil
}
return &Worktree{
IsMain: worktree.IsMain,
IsCurrent: worktree.IsCurrent,
Path: worktree.Path,
IsPathMissing: worktree.IsPathMissing,
GitDir: worktree.GitDir,
Branch: worktree.Branch,
Name: worktree.Name,
}
}
type CommitRange struct {
From string
To string
}
func makeCommitRange(commits []*models.Commit, _ int, _ int) *CommitRange {
if len(commits) == 0 {
return nil
}
return &CommitRange{
From: commits[len(commits)-1].Hash,
To: commits[0].Hash,
}
}
// SessionState captures the current state of the application for use in custom commands
type SessionState struct {
SelectedLocalCommit *Commit // deprecated, use SelectedCommit
SelectedReflogCommit *Commit // deprecated, use SelectedCommit
SelectedSubCommit *Commit // deprecated, use SelectedCommit
SelectedCommit *Commit
SelectedCommitRange *CommitRange
SelectedFile *File
SelectedPath string
SelectedLocalBranch *Branch
SelectedRemoteBranch *RemoteBranch
SelectedRemote *Remote
SelectedTag *Tag
SelectedStashEntry *StashEntry
SelectedCommitFile *CommitFile
SelectedCommitFilePath string
SelectedWorktree *Worktree
CheckedOutBranch *Branch
}
func (self *SessionStateLoader) call() *SessionState {
selectedLocalCommit := commitShimFromModelCommit(self.c.Contexts().LocalCommits.GetSelected())
selectedLocalCommitRange := makeCommitRange(self.c.Contexts().LocalCommits.GetSelectedItems())
selectedReflogCommit := commitShimFromModelCommit(self.c.Contexts().ReflogCommits.GetSelected())
selectedReflogCommitRange := makeCommitRange(self.c.Contexts().ReflogCommits.GetSelectedItems())
selectedSubCommit := commitShimFromModelCommit(self.c.Contexts().SubCommits.GetSelected())
selectedSubCommitRange := makeCommitRange(self.c.Contexts().SubCommits.GetSelectedItems())
selectedCommit := selectedLocalCommit
selectedCommitRange := selectedLocalCommitRange
if self.c.Context().IsCurrentOrParent(self.c.Contexts().ReflogCommits) {
selectedCommit = selectedReflogCommit
selectedCommitRange = selectedReflogCommitRange
} else if self.c.Context().IsCurrentOrParent(self.c.Contexts().SubCommits) {
selectedCommit = selectedSubCommit
selectedCommitRange = selectedSubCommitRange
}
selectedPath := self.c.Contexts().Files.GetSelectedPath()
selectedCommitFilePath := self.c.Contexts().CommitFiles.GetSelectedPath()
if self.c.Context().IsCurrent(self.c.Contexts().CommitFiles) {
selectedPath = selectedCommitFilePath
}
return &SessionState{
SelectedFile: fileShimFromModelFile(self.c.Contexts().Files.GetSelectedFile()),
SelectedPath: selectedPath,
SelectedLocalCommit: selectedLocalCommit,
SelectedReflogCommit: selectedReflogCommit,
SelectedSubCommit: selectedSubCommit,
SelectedCommit: selectedCommit,
SelectedCommitRange: selectedCommitRange,
SelectedLocalBranch: branchShimFromModelBranch(self.c.Contexts().Branches.GetSelected()),
SelectedRemoteBranch: remoteBranchShimFromModelRemoteBranch(self.c.Contexts().RemoteBranches.GetSelected()),
SelectedRemote: remoteShimFromModelRemote(self.c.Contexts().Remotes.GetSelected()),
SelectedTag: tagShimFromModelRemote(self.c.Contexts().Tags.GetSelected()),
SelectedStashEntry: stashEntryShimFromModelRemote(self.c.Contexts().Stash.GetSelected()),
SelectedCommitFile: commitFileShimFromModelRemote(self.c.Contexts().CommitFiles.GetSelectedFile()),
SelectedCommitFilePath: selectedCommitFilePath,
SelectedWorktree: worktreeShimFromModelRemote(self.c.Contexts().Worktrees.GetSelected()),
CheckedOutBranch: branchShimFromModelBranch(self.refsHelper.GetCheckedOutRef()),
}
}