1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-07-30 03:23:08 +03:00

more support for command log and more code reuse for contexts

This commit is contained in:
Jesse Duffield
2021-04-11 13:17:20 +10:00
parent 4f03d7733a
commit cf78b86cb5
9 changed files with 753 additions and 721 deletions

View File

@ -13,111 +13,9 @@ const (
MAIN_CONTEXT
TEMPORARY_POPUP
PERSISTENT_POPUP
EXTRAS_CONTEXT
)
type ContextKey string
const (
STATUS_CONTEXT_KEY ContextKey = "status"
FILES_CONTEXT_KEY ContextKey = "files"
LOCAL_BRANCHES_CONTEXT_KEY ContextKey = "localBranches"
REMOTES_CONTEXT_KEY ContextKey = "remotes"
REMOTE_BRANCHES_CONTEXT_KEY ContextKey = "remoteBranches"
TAGS_CONTEXT_KEY ContextKey = "tags"
BRANCH_COMMITS_CONTEXT_KEY ContextKey = "commits"
REFLOG_COMMITS_CONTEXT_KEY ContextKey = "reflogCommits"
SUB_COMMITS_CONTEXT_KEY ContextKey = "subCommits"
COMMIT_FILES_CONTEXT_KEY ContextKey = "commitFiles"
STASH_CONTEXT_KEY ContextKey = "stash"
MAIN_NORMAL_CONTEXT_KEY ContextKey = "normal"
MAIN_MERGING_CONTEXT_KEY ContextKey = "merging"
MAIN_PATCH_BUILDING_CONTEXT_KEY ContextKey = "patchBuilding"
MAIN_STAGING_CONTEXT_KEY ContextKey = "staging"
MENU_CONTEXT_KEY ContextKey = "menu"
CREDENTIALS_CONTEXT_KEY ContextKey = "credentials"
CONFIRMATION_CONTEXT_KEY ContextKey = "confirmation"
SEARCH_CONTEXT_KEY ContextKey = "search"
COMMIT_MESSAGE_CONTEXT_KEY ContextKey = "commitMessage"
SUBMODULES_CONTEXT_KEY ContextKey = "submodules"
SUGGESTIONS_CONTEXT_KEY ContextKey = "suggestions"
)
var allContextKeys = []ContextKey{
STATUS_CONTEXT_KEY,
FILES_CONTEXT_KEY,
LOCAL_BRANCHES_CONTEXT_KEY,
REMOTES_CONTEXT_KEY,
REMOTE_BRANCHES_CONTEXT_KEY,
TAGS_CONTEXT_KEY,
BRANCH_COMMITS_CONTEXT_KEY,
REFLOG_COMMITS_CONTEXT_KEY,
SUB_COMMITS_CONTEXT_KEY,
COMMIT_FILES_CONTEXT_KEY,
STASH_CONTEXT_KEY,
MAIN_NORMAL_CONTEXT_KEY,
MAIN_MERGING_CONTEXT_KEY,
MAIN_PATCH_BUILDING_CONTEXT_KEY,
MAIN_STAGING_CONTEXT_KEY,
MENU_CONTEXT_KEY,
CREDENTIALS_CONTEXT_KEY,
CONFIRMATION_CONTEXT_KEY,
SEARCH_CONTEXT_KEY,
COMMIT_MESSAGE_CONTEXT_KEY,
SUBMODULES_CONTEXT_KEY,
SUGGESTIONS_CONTEXT_KEY,
}
type ContextTree struct {
Status Context
Files *ListContext
Submodules *ListContext
Menu *ListContext
Branches *ListContext
Remotes *ListContext
RemoteBranches *ListContext
Tags *ListContext
BranchCommits *ListContext
CommitFiles *ListContext
ReflogCommits *ListContext
SubCommits *ListContext
Stash *ListContext
Suggestions *ListContext
Normal Context
Staging Context
PatchBuilding Context
Merging Context
Credentials Context
Confirmation Context
CommitMessage Context
Search Context
}
func (gui *Gui) allContexts() []Context {
return []Context{
gui.State.Contexts.Status,
gui.State.Contexts.Files,
gui.State.Contexts.Submodules,
gui.State.Contexts.Branches,
gui.State.Contexts.Remotes,
gui.State.Contexts.RemoteBranches,
gui.State.Contexts.Tags,
gui.State.Contexts.BranchCommits,
gui.State.Contexts.CommitFiles,
gui.State.Contexts.ReflogCommits,
gui.State.Contexts.Stash,
gui.State.Contexts.Menu,
gui.State.Contexts.Confirmation,
gui.State.Contexts.Credentials,
gui.State.Contexts.CommitMessage,
gui.State.Contexts.Normal,
gui.State.Contexts.Staging,
gui.State.Contexts.Merging,
gui.State.Contexts.PatchBuilding,
gui.State.Contexts.SubCommits,
gui.State.Contexts.Suggestions,
}
}
type Context interface {
HandleFocus() error
HandleFocusLost() error
@ -134,170 +32,6 @@ type Context interface {
GetOptionsMap() map[string]string
}
type BasicContext struct {
OnFocus func() error
OnFocusLost func() error
OnRender func() error
OnGetOptionsMap func() map[string]string
Kind ContextKind
Key ContextKey
ViewName string
}
func (c BasicContext) GetOptionsMap() map[string]string {
if c.OnGetOptionsMap != nil {
return c.OnGetOptionsMap()
}
return nil
}
func (c BasicContext) SetWindowName(windowName string) {
panic("can't set window name on basic context")
}
func (c BasicContext) GetWindowName() string {
// TODO: fix this up
return c.GetViewName()
}
func (c BasicContext) SetParentContext(Context) {
panic("can't set parent context on basic context")
}
func (c BasicContext) GetParentContext() (Context, bool) {
return nil, false
}
func (c BasicContext) HandleRender() error {
if c.OnRender != nil {
return c.OnRender()
}
return nil
}
func (c BasicContext) GetViewName() string {
return c.ViewName
}
func (c BasicContext) HandleFocus() error {
return c.OnFocus()
}
func (c BasicContext) HandleFocusLost() error {
if c.OnFocusLost != nil {
return c.OnFocusLost()
}
return nil
}
func (c BasicContext) GetKind() ContextKind {
return c.Kind
}
func (c BasicContext) GetKey() ContextKey {
return c.Key
}
func (gui *Gui) contextTree() ContextTree {
return ContextTree{
Status: BasicContext{
OnFocus: gui.handleStatusSelect,
Kind: SIDE_CONTEXT,
ViewName: "status",
Key: STATUS_CONTEXT_KEY,
},
Files: gui.filesListContext(),
Submodules: gui.submodulesListContext(),
Menu: gui.menuListContext(),
Remotes: gui.remotesListContext(),
RemoteBranches: gui.remoteBranchesListContext(),
BranchCommits: gui.branchCommitsListContext(),
CommitFiles: gui.commitFilesListContext(),
ReflogCommits: gui.reflogCommitsListContext(),
SubCommits: gui.subCommitsListContext(),
Branches: gui.branchesListContext(),
Tags: gui.tagsListContext(),
Stash: gui.stashListContext(),
Normal: BasicContext{
OnFocus: func() error {
return nil // TODO: should we do something here? We should allow for scrolling the panel
},
Kind: MAIN_CONTEXT,
ViewName: "main",
Key: MAIN_NORMAL_CONTEXT_KEY,
},
Staging: BasicContext{
OnFocus: func() error {
return nil
// TODO: centralise the code here
// return gui.refreshStagingPanel(false, -1)
},
Kind: MAIN_CONTEXT,
ViewName: "main",
Key: MAIN_STAGING_CONTEXT_KEY,
},
PatchBuilding: BasicContext{
OnFocus: func() error {
return nil
// TODO: centralise the code here
// return gui.refreshPatchBuildingPanel(-1)
},
Kind: MAIN_CONTEXT,
ViewName: "main",
Key: MAIN_PATCH_BUILDING_CONTEXT_KEY,
},
Merging: BasicContext{
OnFocus: gui.refreshMergePanelWithLock,
Kind: MAIN_CONTEXT,
ViewName: "main",
Key: MAIN_MERGING_CONTEXT_KEY,
OnGetOptionsMap: gui.getMergingOptions,
},
Credentials: BasicContext{
OnFocus: gui.handleCredentialsViewFocused,
Kind: PERSISTENT_POPUP,
ViewName: "credentials",
Key: CREDENTIALS_CONTEXT_KEY,
},
Confirmation: BasicContext{
OnFocus: func() error { return nil },
Kind: TEMPORARY_POPUP,
ViewName: "confirmation",
Key: CONFIRMATION_CONTEXT_KEY,
},
Suggestions: gui.suggestionsListContext(),
CommitMessage: BasicContext{
OnFocus: gui.handleCommitMessageFocused,
Kind: PERSISTENT_POPUP,
ViewName: "commitMessage",
Key: COMMIT_MESSAGE_CONTEXT_KEY,
},
Search: BasicContext{
OnFocus: func() error { return nil },
Kind: PERSISTENT_POPUP,
ViewName: "search",
Key: SEARCH_CONTEXT_KEY,
},
}
}
func (tree ContextTree) initialViewContextMap() map[string]Context {
return map[string]Context{
"status": tree.Status,
"files": tree.Files,
"branches": tree.Branches,
"commits": tree.BranchCommits,
"commitFiles": tree.CommitFiles,
"stash": tree.Stash,
"menu": tree.Menu,
"confirmation": tree.Confirmation,
"credentials": tree.Credentials,
"commitMessage": tree.CommitMessage,
"main": tree.Normal,
"secondary": tree.Normal,
}
}
func (gui *Gui) popupViewNames() []string {
result := []string{}
for _, context := range gui.allContexts() {
@ -309,52 +43,6 @@ func (gui *Gui) popupViewNames() []string {
return result
}
func (tree ContextTree) initialViewTabContextMap() map[string][]tabContext {
return map[string][]tabContext{
"branches": {
{
tab: "Local Branches",
contexts: []Context{tree.Branches},
},
{
tab: "Remotes",
contexts: []Context{
tree.Remotes,
tree.RemoteBranches,
},
},
{
tab: "Tags",
contexts: []Context{tree.Tags},
},
},
"commits": {
{
tab: "Commits",
contexts: []Context{tree.BranchCommits},
},
{
tab: "Reflog",
contexts: []Context{
tree.ReflogCommits,
},
},
},
"files": {
{
tab: "Files",
contexts: []Context{tree.Files},
},
{
tab: "Submodules",
contexts: []Context{
tree.Submodules,
},
},
},
}
}
func (gui *Gui) currentContextKeyIgnoringPopups() ContextKey {
gui.State.ContextManager.RLock()
defer gui.State.ContextManager.RUnlock()
@ -416,7 +104,7 @@ func (gui *Gui) pushContextDirect(c Context) error {
}
}
gui.State.ContextManager.ContextStack = []Context{c}
} else if len(gui.State.ContextManager.ContextStack) == 0 || gui.State.ContextManager.ContextStack[len(gui.State.ContextManager.ContextStack)-1].GetKey() != c.GetKey() {
} else if len(gui.State.ContextManager.ContextStack) == 0 || gui.currentContextWithoutLock().GetKey() != c.GetKey() {
// Do not append if the one at the end is the same context (e.g. opening a menu from a menu)
// In that case we'll just close the menu entirely when the user hits escape.
@ -580,6 +268,10 @@ func (gui *Gui) currentContext() Context {
gui.State.ContextManager.RLock()
defer gui.State.ContextManager.RUnlock()
return gui.currentContextWithoutLock()
}
func (gui *Gui) currentContextWithoutLock() Context {
if len(gui.State.ContextManager.ContextStack) == 0 {
return gui.defaultSideContext()
}