mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-02-09 13:47:11 +02:00
working again
This commit is contained in:
parent
482bdc4f1e
commit
145c69d9ae
@ -46,10 +46,16 @@ func (gui *Gui) commitFilesRenderToMain() error {
|
||||
cmdObj := gui.git.WorkingTree.ShowFileDiffCmdObj(from, to, reverse, node.GetPath(), false)
|
||||
task := NewRunPtyTask(cmdObj.GetCmd())
|
||||
|
||||
mainContext := gui.State.Contexts.Normal
|
||||
if node.File != nil {
|
||||
mainContext = gui.State.Contexts.PatchBuilding
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
title: "Patch",
|
||||
task: task,
|
||||
title: "Patch",
|
||||
task: task,
|
||||
context: mainContext,
|
||||
},
|
||||
secondary: gui.secondaryPatchPanelUpdateOpts(),
|
||||
})
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
|
||||
func (gui *Gui) popupViewNames() []string {
|
||||
result := []string{}
|
||||
for _, context := range gui.allContexts() {
|
||||
for _, context := range gui.State.Contexts.Flatten() {
|
||||
if context.GetKind() == types.PERSISTENT_POPUP || context.GetKind() == types.TEMPORARY_POPUP {
|
||||
result = append(result, context.GetViewName())
|
||||
}
|
||||
@ -44,6 +44,10 @@ func (gui *Gui) replaceContext(c types.Context) error {
|
||||
gui.State.ContextManager.Lock()
|
||||
defer gui.State.ContextManager.Unlock()
|
||||
|
||||
if !c.IsFocusable() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(gui.State.ContextManager.ContextStack) == 0 {
|
||||
gui.State.ContextManager.ContextStack = []types.Context{c}
|
||||
} else {
|
||||
@ -60,8 +64,9 @@ func (gui *Gui) pushContext(c types.Context, opts ...types.OnFocusOpts) error {
|
||||
return errors.New("cannot pass multiple opts to pushContext")
|
||||
}
|
||||
|
||||
if c.GetKey() == context.GLOBAL_CONTEXT_KEY {
|
||||
return errors.New("Cannot push global context")
|
||||
if !c.IsFocusable() {
|
||||
panic(c.GetKey())
|
||||
return nil
|
||||
}
|
||||
|
||||
gui.State.ContextManager.Lock()
|
||||
@ -97,7 +102,7 @@ func (gui *Gui) pushContext(c types.Context, opts ...types.OnFocusOpts) error {
|
||||
// want to switch to: you only know the view that you want to switch to. It will
|
||||
// look up the context currently active for that view and switch to that context
|
||||
func (gui *Gui) pushContextWithView(viewName string) error {
|
||||
return gui.c.PushContext(gui.State.ViewContextMap[viewName])
|
||||
return gui.c.PushContext(gui.State.ViewContextMap.Get(viewName))
|
||||
}
|
||||
|
||||
func (gui *Gui) returnFromContext() error {
|
||||
@ -152,7 +157,7 @@ func (gui *Gui) deactivateContext(c types.Context) error {
|
||||
// if the context's view is set to another context we do nothing.
|
||||
// if the context's view is the current view we trigger a focus; re-selecting the current item.
|
||||
func (gui *Gui) postRefreshUpdate(c types.Context) error {
|
||||
if gui.State.ViewContextMap[c.GetViewName()].GetKey() != c.GetKey() {
|
||||
if gui.State.ViewContextMap.Get(c.GetViewName()).GetKey() != c.GetKey() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -175,7 +180,7 @@ func (gui *Gui) activateContext(c types.Context, opts ...types.OnFocusOpts) erro
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
originalViewContextKey := gui.State.ViewContextMap[viewName].GetKey()
|
||||
originalViewContextKey := gui.State.ViewContextMap.Get(viewName).GetKey()
|
||||
|
||||
gui.setWindowContext(c)
|
||||
gui.setViewTabForContext(c)
|
||||
@ -200,7 +205,7 @@ func (gui *Gui) activateContext(c types.Context, opts ...types.OnFocusOpts) erro
|
||||
}
|
||||
}
|
||||
|
||||
gui.State.ViewContextMap[viewName] = c
|
||||
gui.ViewContextMapSet(viewName, c)
|
||||
|
||||
gui.g.Cursor = v.Editable
|
||||
|
||||
@ -215,12 +220,19 @@ func (gui *Gui) activateContext(c types.Context, opts ...types.OnFocusOpts) erro
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: consider removing this and instead depending on the .Context field of views
|
||||
gui.State.ViewContextMap[c.GetViewName()] = c
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// also setting context on view for now. We'll need to pick one of these two approaches to stick with.
|
||||
func (gui *Gui) ViewContextMapSet(viewName string, c types.Context) {
|
||||
gui.State.ViewContextMap.Set(viewName, c)
|
||||
view, err := gui.g.View(viewName)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
view.Context = string(c.GetKey())
|
||||
}
|
||||
|
||||
// // currently unused
|
||||
// func (gui *Gui) renderContextStack() string {
|
||||
// result := ""
|
||||
@ -369,8 +381,8 @@ func (gui *Gui) changeMainViewsContext(c types.Context) {
|
||||
|
||||
switch c.GetKey() {
|
||||
case context.MAIN_NORMAL_CONTEXT_KEY, context.MAIN_PATCH_BUILDING_CONTEXT_KEY, context.MAIN_STAGING_CONTEXT_KEY, context.MAIN_MERGING_CONTEXT_KEY:
|
||||
gui.State.ViewContextMap[gui.Views.Main.Name()] = c
|
||||
gui.State.ViewContextMap[gui.Views.Secondary.Name()] = c
|
||||
gui.ViewContextMapSet(gui.Views.Main.Name(), c)
|
||||
gui.ViewContextMapSet(gui.Views.Secondary.Name(), c)
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown context for main: %s", c.GetKey()))
|
||||
}
|
||||
@ -416,18 +428,8 @@ func (gui *Gui) setViewTabForContext(c types.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func (gui *Gui) mustContextForContextKey(contextKey types.ContextKey) types.Context {
|
||||
context, ok := gui.contextForContextKey(contextKey)
|
||||
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("context not found for key %s", contextKey))
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
func (gui *Gui) contextForContextKey(contextKey types.ContextKey) (types.Context, bool) {
|
||||
for _, context := range gui.allContexts() {
|
||||
for _, context := range gui.State.Contexts.Flatten() {
|
||||
if context.GetKey() == contextKey {
|
||||
return context, true
|
||||
}
|
||||
@ -437,13 +439,7 @@ func (gui *Gui) contextForContextKey(contextKey types.ContextKey) (types.Context
|
||||
}
|
||||
|
||||
func (gui *Gui) rerenderView(view *gocui.View) error {
|
||||
context, ok := gui.State.ViewContextMap[view.Name()]
|
||||
|
||||
if !ok {
|
||||
panic("no context set against view " + view.Name())
|
||||
}
|
||||
|
||||
return context.HandleRender()
|
||||
return gui.State.ViewContextMap.Get(view.Name()).HandleRender()
|
||||
}
|
||||
|
||||
func (gui *Gui) getSideContextSelectedItemId() string {
|
||||
@ -456,7 +452,7 @@ func (gui *Gui) getSideContextSelectedItemId() string {
|
||||
}
|
||||
|
||||
func (gui *Gui) isContextVisible(c types.Context) bool {
|
||||
return gui.State.WindowViewNameMap[c.GetWindowName()] == c.GetViewName() && gui.State.ViewContextMap[c.GetViewName()].GetKey() == c.GetKey()
|
||||
return gui.State.WindowViewNameMap[c.GetWindowName()] == c.GetViewName() && gui.State.ViewContextMap.Get(c.GetViewName()).GetKey() == c.GetKey()
|
||||
}
|
||||
|
||||
// currently unused
|
||||
|
@ -15,6 +15,8 @@ type BaseContext struct {
|
||||
keybindingsFns []types.KeybindingsFn
|
||||
mouseKeybindingsFns []types.MouseKeybindingsFn
|
||||
|
||||
focusable bool
|
||||
|
||||
*ParentContextMgr
|
||||
}
|
||||
|
||||
@ -25,6 +27,7 @@ type NewBaseContextOpts struct {
|
||||
Key types.ContextKey
|
||||
ViewName string
|
||||
WindowName string
|
||||
Focusable bool
|
||||
|
||||
OnGetOptionsMap func() map[string]string
|
||||
}
|
||||
@ -36,6 +39,7 @@ func NewBaseContext(opts NewBaseContextOpts) *BaseContext {
|
||||
ViewName: opts.ViewName,
|
||||
windowName: opts.WindowName,
|
||||
onGetOptionsMap: opts.OnGetOptionsMap,
|
||||
focusable: opts.Focusable,
|
||||
ParentContextMgr: &ParentContextMgr{},
|
||||
}
|
||||
}
|
||||
@ -96,3 +100,7 @@ func (self *BaseContext) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocu
|
||||
|
||||
return bindings
|
||||
}
|
||||
|
||||
func (self *BaseContext) IsFocusable() bool {
|
||||
return self.focusable
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ func NewCommitFilesContext(
|
||||
WindowName: "commits",
|
||||
Key: COMMIT_FILES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
})
|
||||
|
||||
self := &CommitFilesContext{}
|
||||
|
@ -30,7 +30,7 @@ const (
|
||||
)
|
||||
|
||||
var AllContextKeys = []types.ContextKey{
|
||||
GLOBAL_CONTEXT_KEY,
|
||||
GLOBAL_CONTEXT_KEY, // not focusable
|
||||
STATUS_CONTEXT_KEY,
|
||||
FILES_CONTEXT_KEY,
|
||||
LOCAL_BRANCHES_CONTEXT_KEY,
|
||||
@ -42,10 +42,10 @@ var AllContextKeys = []types.ContextKey{
|
||||
SUB_COMMITS_CONTEXT_KEY,
|
||||
COMMIT_FILES_CONTEXT_KEY,
|
||||
STASH_CONTEXT_KEY,
|
||||
MAIN_NORMAL_CONTEXT_KEY,
|
||||
MAIN_NORMAL_CONTEXT_KEY, // not focusable
|
||||
MAIN_MERGING_CONTEXT_KEY,
|
||||
MAIN_PATCH_BUILDING_CONTEXT_KEY,
|
||||
MAIN_STAGING_CONTEXT_KEY,
|
||||
MAIN_STAGING_CONTEXT_KEY, // not focusable for secondary view
|
||||
MENU_CONTEXT_KEY,
|
||||
CREDENTIALS_CONTEXT_KEY,
|
||||
CONFIRMATION_CONTEXT_KEY,
|
||||
@ -83,24 +83,50 @@ type ContextTree struct {
|
||||
CommandLog types.Context
|
||||
}
|
||||
|
||||
func (tree ContextTree) InitialViewContextMap() map[string]types.Context {
|
||||
return map[string]types.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,
|
||||
"extras": tree.CommandLog,
|
||||
func (self *ContextTree) Flatten() []types.Context {
|
||||
return []types.Context{
|
||||
self.Global,
|
||||
self.Status,
|
||||
self.Files,
|
||||
self.Submodules,
|
||||
self.Branches,
|
||||
self.Remotes,
|
||||
self.RemoteBranches,
|
||||
self.Tags,
|
||||
self.BranchCommits,
|
||||
self.CommitFiles,
|
||||
self.ReflogCommits,
|
||||
self.Stash,
|
||||
self.Menu,
|
||||
self.Confirmation,
|
||||
self.Credentials,
|
||||
self.CommitMessage,
|
||||
self.Normal,
|
||||
self.Staging,
|
||||
self.Merging,
|
||||
self.PatchBuilding,
|
||||
self.SubCommits,
|
||||
self.Suggestions,
|
||||
self.CommandLog,
|
||||
}
|
||||
}
|
||||
|
||||
type ViewContextMap struct {
|
||||
content map[string]types.Context
|
||||
}
|
||||
|
||||
func NewViewContextMap() *ViewContextMap {
|
||||
return &ViewContextMap{content: map[string]types.Context{}}
|
||||
}
|
||||
|
||||
func (self *ViewContextMap) Get(viewName string) types.Context {
|
||||
return self.content[viewName]
|
||||
}
|
||||
|
||||
func (self *ViewContextMap) Set(viewName string, context types.Context) {
|
||||
self.content[viewName] = context
|
||||
}
|
||||
|
||||
type TabContext struct {
|
||||
Tab string
|
||||
Contexts []types.Context
|
||||
|
@ -31,6 +31,7 @@ func NewTagsContext(
|
||||
WindowName: "branches",
|
||||
Key: TAGS_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
})
|
||||
|
||||
self := &TagsContext{}
|
||||
|
@ -31,6 +31,7 @@ func NewWorkingTreeContext(
|
||||
WindowName: "files",
|
||||
Key: FILES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
})
|
||||
|
||||
self := &WorkingTreeContext{}
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
func (gui *Gui) allContexts() []types.Context {
|
||||
func (gui *Gui) allContexts2() []types.Context {
|
||||
return []types.Context{
|
||||
gui.State.Contexts.Global,
|
||||
gui.State.Contexts.Status,
|
||||
@ -41,6 +41,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
||||
ViewName: "",
|
||||
WindowName: "",
|
||||
Key: context.GLOBAL_CONTEXT_KEY,
|
||||
Focusable: false,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
OnRenderToMain: OnFocusWrapper(gui.statusRenderToMain),
|
||||
@ -52,6 +53,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
||||
ViewName: "status",
|
||||
WindowName: "status",
|
||||
Key: context.STATUS_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
OnRenderToMain: OnFocusWrapper(gui.statusRenderToMain),
|
||||
@ -76,6 +78,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
||||
ViewName: "main",
|
||||
WindowName: "main",
|
||||
Key: context.MAIN_NORMAL_CONTEXT_KEY,
|
||||
Focusable: false,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
OnFocus: func(opts ...types.OnFocusOpts) error {
|
||||
@ -89,6 +92,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
||||
ViewName: "main",
|
||||
WindowName: "main",
|
||||
Key: context.MAIN_STAGING_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
OnFocus: func(opts ...types.OnFocusOpts) error {
|
||||
@ -112,6 +116,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
||||
ViewName: "main",
|
||||
WindowName: "main",
|
||||
Key: context.MAIN_PATCH_BUILDING_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
OnFocus: func(opts ...types.OnFocusOpts) error {
|
||||
@ -131,6 +136,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
||||
WindowName: "main",
|
||||
Key: context.MAIN_MERGING_CONTEXT_KEY,
|
||||
OnGetOptionsMap: gui.getMergingOptions,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
OnFocus: OnFocusWrapper(func() error { return gui.renderConflictsWithLock(true) }),
|
||||
@ -142,6 +148,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
||||
ViewName: "credentials",
|
||||
WindowName: "credentials",
|
||||
Key: context.CREDENTIALS_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
OnFocus: OnFocusWrapper(gui.handleAskFocused),
|
||||
@ -153,6 +160,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
||||
ViewName: "confirmation",
|
||||
WindowName: "confirmation",
|
||||
Key: context.CONFIRMATION_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
OnFocus: OnFocusWrapper(gui.handleAskFocused),
|
||||
@ -164,6 +172,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
||||
ViewName: "commitMessage",
|
||||
WindowName: "commitMessage",
|
||||
Key: context.COMMIT_MESSAGE_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
OnFocus: OnFocusWrapper(gui.handleCommitMessageFocused),
|
||||
@ -175,6 +184,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
||||
ViewName: "search",
|
||||
WindowName: "search",
|
||||
Key: context.SEARCH_CONTEXT_KEY,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{},
|
||||
),
|
||||
@ -185,6 +195,7 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
||||
WindowName: "extras",
|
||||
Key: context.COMMAND_LOG_CONTEXT_KEY,
|
||||
OnGetOptionsMap: gui.getMergingOptions,
|
||||
Focusable: true,
|
||||
}),
|
||||
NewSimpleContextOpts{
|
||||
OnFocusLost: func() error {
|
||||
|
@ -55,9 +55,15 @@ func (gui *Gui) filesRenderToMain() error {
|
||||
|
||||
cmdObj := gui.git.WorkingTree.WorktreeFileDiffCmdObj(node, false, !node.GetHasUnstagedChanges() && node.GetHasStagedChanges(), gui.IgnoreWhitespaceInDiffView)
|
||||
|
||||
mainContext := gui.State.Contexts.Normal
|
||||
if node.File != nil {
|
||||
mainContext = gui.State.Contexts.Staging
|
||||
}
|
||||
|
||||
refreshOpts := refreshMainOpts{main: &viewUpdateOpts{
|
||||
title: gui.c.Tr.UnstagedChanges,
|
||||
task: NewRunPtyTask(cmdObj.GetCmd()),
|
||||
title: gui.c.Tr.UnstagedChanges,
|
||||
task: NewRunPtyTask(cmdObj.GetCmd()),
|
||||
context: mainContext,
|
||||
}}
|
||||
|
||||
if node.GetHasUnstagedChanges() {
|
||||
@ -65,8 +71,9 @@ func (gui *Gui) filesRenderToMain() error {
|
||||
cmdObj := gui.git.WorkingTree.WorktreeFileDiffCmdObj(node, false, true, gui.IgnoreWhitespaceInDiffView)
|
||||
|
||||
refreshOpts.secondary = &viewUpdateOpts{
|
||||
title: gui.c.Tr.StagedChanges,
|
||||
task: NewRunPtyTask(cmdObj.GetCmd()),
|
||||
title: gui.c.Tr.StagedChanges,
|
||||
task: NewRunPtyTask(cmdObj.GetCmd()),
|
||||
context: mainContext,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
160
pkg/gui/gui.go
160
pkg/gui/gui.go
@ -193,7 +193,7 @@ type GuiRepoState struct {
|
||||
MainContext types.ContextKey // used to keep the main and secondary views' contexts in sync
|
||||
ContextManager ContextManager
|
||||
Contexts *context.ContextTree
|
||||
ViewContextMap map[string]types.Context
|
||||
ViewContextMap *context.ViewContextMap
|
||||
ViewTabContextMap map[string][]context.TabContext
|
||||
|
||||
// WindowViewNameMap is a mapping of windows to the current view of that window.
|
||||
@ -417,13 +417,23 @@ func (gui *Gui) resetState(filterPath string, reuseState bool) {
|
||||
}
|
||||
}
|
||||
|
||||
contexts := gui.contextTree()
|
||||
contextTree := gui.contextTree()
|
||||
|
||||
screenMode := SCREEN_NORMAL
|
||||
var initialContext types.IListContext = contexts.Files
|
||||
var initialContext types.IListContext = contextTree.Files
|
||||
if filterPath != "" {
|
||||
screenMode = SCREEN_HALF
|
||||
initialContext = contexts.BranchCommits
|
||||
initialContext = contextTree.BranchCommits
|
||||
}
|
||||
|
||||
viewContextMap := context.NewViewContextMap()
|
||||
for viewName, context := range initialViewContextMapping(contextTree) {
|
||||
viewContextMap.Set(viewName, context)
|
||||
view, err := gui.g.View(viewName)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
view.Context = string(context.GetKey())
|
||||
}
|
||||
|
||||
gui.State = &GuiRepoState{
|
||||
@ -461,17 +471,35 @@ func (gui *Gui) resetState(filterPath string, reuseState bool) {
|
||||
CherryPicking: cherrypicking.New(),
|
||||
Diffing: diffing.New(),
|
||||
},
|
||||
ViewContextMap: contexts.InitialViewContextMap(),
|
||||
ViewTabContextMap: contexts.InitialViewTabContextMap(),
|
||||
ViewContextMap: viewContextMap,
|
||||
ViewTabContextMap: contextTree.InitialViewTabContextMap(),
|
||||
ScreenMode: screenMode,
|
||||
// TODO: put contexts in the context manager
|
||||
ContextManager: NewContextManager(initialContext),
|
||||
Contexts: contexts,
|
||||
Contexts: contextTree,
|
||||
}
|
||||
|
||||
gui.RepoStateMap[Repo(currentDir)] = gui.State
|
||||
}
|
||||
|
||||
func initialViewContextMapping(contextTree *context.ContextTree) map[string]types.Context {
|
||||
return map[string]types.Context{
|
||||
"status": contextTree.Status,
|
||||
"files": contextTree.Files,
|
||||
"branches": contextTree.Branches,
|
||||
"commits": contextTree.BranchCommits,
|
||||
"commitFiles": contextTree.CommitFiles,
|
||||
"stash": contextTree.Stash,
|
||||
"menu": contextTree.Menu,
|
||||
"confirmation": contextTree.Confirmation,
|
||||
"credentials": contextTree.Credentials,
|
||||
"commitMessage": contextTree.CommitMessage,
|
||||
"main": contextTree.Normal,
|
||||
"secondary": contextTree.Normal,
|
||||
"extras": contextTree.CommandLog,
|
||||
}
|
||||
}
|
||||
|
||||
// for now the split view will always be on
|
||||
// NewGui builds a new gui handler
|
||||
func NewGui(
|
||||
@ -760,6 +788,10 @@ func (gui *Gui) Run(filterPath string) error {
|
||||
|
||||
gui.g.SetManager(gocui.ManagerFunc(gui.layout), gocui.ManagerFunc(gui.getFocusLayout()))
|
||||
|
||||
if err := gui.createAllViews(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// onNewRepo must be called after g.SetManager because SetManager deletes keybindings
|
||||
if err := gui.onNewRepo(filterPath, false); err != nil {
|
||||
return err
|
||||
@ -777,6 +809,120 @@ func (gui *Gui) Run(filterPath string) error {
|
||||
return gui.g.MainLoop()
|
||||
}
|
||||
|
||||
func (gui *Gui) createAllViews() error {
|
||||
viewNameMappings := []struct {
|
||||
viewPtr **gocui.View
|
||||
name string
|
||||
}{
|
||||
{viewPtr: &gui.Views.Status, name: "status"},
|
||||
{viewPtr: &gui.Views.Files, name: "files"},
|
||||
{viewPtr: &gui.Views.Branches, name: "branches"},
|
||||
{viewPtr: &gui.Views.Commits, name: "commits"},
|
||||
{viewPtr: &gui.Views.Stash, name: "stash"},
|
||||
{viewPtr: &gui.Views.CommitFiles, name: "commitFiles"},
|
||||
{viewPtr: &gui.Views.Main, name: "main"},
|
||||
{viewPtr: &gui.Views.Secondary, name: "secondary"},
|
||||
{viewPtr: &gui.Views.Options, name: "options"},
|
||||
{viewPtr: &gui.Views.AppStatus, name: "appStatus"},
|
||||
{viewPtr: &gui.Views.Information, name: "information"},
|
||||
{viewPtr: &gui.Views.Search, name: "search"},
|
||||
{viewPtr: &gui.Views.SearchPrefix, name: "searchPrefix"},
|
||||
{viewPtr: &gui.Views.CommitMessage, name: "commitMessage"},
|
||||
{viewPtr: &gui.Views.Credentials, name: "credentials"},
|
||||
{viewPtr: &gui.Views.Menu, name: "menu"},
|
||||
{viewPtr: &gui.Views.Suggestions, name: "suggestions"},
|
||||
{viewPtr: &gui.Views.Confirmation, name: "confirmation"},
|
||||
{viewPtr: &gui.Views.Limit, name: "limit"},
|
||||
{viewPtr: &gui.Views.Extras, name: "extras"},
|
||||
}
|
||||
|
||||
var err error
|
||||
for _, mapping := range viewNameMappings {
|
||||
*mapping.viewPtr, err = gui.prepareView(mapping.name)
|
||||
if err != nil && err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
gui.Views.Options.Frame = false
|
||||
gui.Views.Options.FgColor = theme.OptionsColor
|
||||
|
||||
gui.Views.SearchPrefix.BgColor = gocui.ColorDefault
|
||||
gui.Views.SearchPrefix.FgColor = gocui.ColorGreen
|
||||
gui.Views.SearchPrefix.Frame = false
|
||||
gui.setViewContent(gui.Views.SearchPrefix, SEARCH_PREFIX)
|
||||
|
||||
gui.Views.Stash.Title = gui.c.Tr.StashTitle
|
||||
gui.Views.Stash.FgColor = theme.GocuiDefaultTextColor
|
||||
|
||||
gui.Views.Commits.Title = gui.c.Tr.CommitsTitle
|
||||
gui.Views.Commits.FgColor = theme.GocuiDefaultTextColor
|
||||
|
||||
gui.Views.CommitFiles.Title = gui.c.Tr.CommitFiles
|
||||
gui.Views.CommitFiles.FgColor = theme.GocuiDefaultTextColor
|
||||
|
||||
gui.Views.Branches.Title = gui.c.Tr.BranchesTitle
|
||||
gui.Views.Branches.FgColor = theme.GocuiDefaultTextColor
|
||||
|
||||
gui.Views.Files.Highlight = true
|
||||
gui.Views.Files.Title = gui.c.Tr.FilesTitle
|
||||
gui.Views.Files.FgColor = theme.GocuiDefaultTextColor
|
||||
|
||||
gui.Views.Secondary.Title = gui.c.Tr.DiffTitle
|
||||
gui.Views.Secondary.Wrap = true
|
||||
gui.Views.Secondary.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Secondary.IgnoreCarriageReturns = true
|
||||
|
||||
gui.Views.Main.Title = gui.c.Tr.DiffTitle
|
||||
gui.Views.Main.Wrap = true
|
||||
gui.Views.Main.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Main.IgnoreCarriageReturns = true
|
||||
|
||||
gui.Views.Limit.Title = gui.c.Tr.NotEnoughSpace
|
||||
gui.Views.Limit.Wrap = true
|
||||
|
||||
gui.Views.Status.Title = gui.c.Tr.StatusTitle
|
||||
gui.Views.Status.FgColor = theme.GocuiDefaultTextColor
|
||||
|
||||
gui.Views.Search.BgColor = gocui.ColorDefault
|
||||
gui.Views.Search.FgColor = gocui.ColorGreen
|
||||
gui.Views.Search.Frame = false
|
||||
gui.Views.Search.Editable = true
|
||||
|
||||
gui.Views.AppStatus.BgColor = gocui.ColorDefault
|
||||
gui.Views.AppStatus.FgColor = gocui.ColorCyan
|
||||
gui.Views.AppStatus.Frame = false
|
||||
gui.Views.AppStatus.Visible = false
|
||||
|
||||
gui.Views.CommitMessage.Visible = false
|
||||
gui.Views.CommitMessage.Title = gui.c.Tr.CommitMessage
|
||||
gui.Views.CommitMessage.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.CommitMessage.Editable = true
|
||||
gui.Views.CommitMessage.Editor = gocui.EditorFunc(gui.commitMessageEditor)
|
||||
|
||||
gui.Views.Confirmation.Visible = false
|
||||
|
||||
gui.Views.Credentials.Visible = false
|
||||
gui.Views.Credentials.Title = gui.c.Tr.CredentialsUsername
|
||||
gui.Views.Credentials.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Credentials.Editable = true
|
||||
|
||||
gui.Views.Suggestions.Visible = false
|
||||
|
||||
gui.Views.Menu.Visible = false
|
||||
|
||||
gui.Views.Information.BgColor = gocui.ColorDefault
|
||||
gui.Views.Information.FgColor = gocui.ColorGreen
|
||||
gui.Views.Information.Frame = false
|
||||
|
||||
gui.Views.Extras.Title = gui.c.Tr.CommandLog
|
||||
gui.Views.Extras.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Extras.Autoscroll = true
|
||||
gui.Views.Extras.Wrap = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) RunAndHandleError(filterPath string) error {
|
||||
gui.stopChan = make(chan struct{})
|
||||
return utils.SafeWithError(func() error {
|
||||
|
@ -1348,7 +1348,7 @@ func (gui *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBin
|
||||
}
|
||||
|
||||
mouseKeybindings := []*gocui.ViewMouseBinding{}
|
||||
for _, c := range gui.allContexts() {
|
||||
for _, c := range gui.State.Contexts.Flatten() {
|
||||
viewName := c.GetViewName()
|
||||
contextKey := c.GetKey()
|
||||
for _, binding := range c.GetKeybindings(keybindingsOpts) {
|
||||
|
@ -7,130 +7,12 @@ import (
|
||||
|
||||
const SEARCH_PREFIX = "search: "
|
||||
|
||||
func (gui *Gui) createAllViews() error {
|
||||
viewNameMappings := []struct {
|
||||
viewPtr **gocui.View
|
||||
name string
|
||||
}{
|
||||
{viewPtr: &gui.Views.Status, name: "status"},
|
||||
{viewPtr: &gui.Views.Files, name: "files"},
|
||||
{viewPtr: &gui.Views.Branches, name: "branches"},
|
||||
{viewPtr: &gui.Views.Commits, name: "commits"},
|
||||
{viewPtr: &gui.Views.Stash, name: "stash"},
|
||||
{viewPtr: &gui.Views.CommitFiles, name: "commitFiles"},
|
||||
{viewPtr: &gui.Views.Main, name: "main"},
|
||||
{viewPtr: &gui.Views.Secondary, name: "secondary"},
|
||||
{viewPtr: &gui.Views.Options, name: "options"},
|
||||
{viewPtr: &gui.Views.AppStatus, name: "appStatus"},
|
||||
{viewPtr: &gui.Views.Information, name: "information"},
|
||||
{viewPtr: &gui.Views.Search, name: "search"},
|
||||
{viewPtr: &gui.Views.SearchPrefix, name: "searchPrefix"},
|
||||
{viewPtr: &gui.Views.CommitMessage, name: "commitMessage"},
|
||||
{viewPtr: &gui.Views.Credentials, name: "credentials"},
|
||||
{viewPtr: &gui.Views.Menu, name: "menu"},
|
||||
{viewPtr: &gui.Views.Suggestions, name: "suggestions"},
|
||||
{viewPtr: &gui.Views.Confirmation, name: "confirmation"},
|
||||
{viewPtr: &gui.Views.Limit, name: "limit"},
|
||||
{viewPtr: &gui.Views.Extras, name: "extras"},
|
||||
}
|
||||
|
||||
var err error
|
||||
for _, mapping := range viewNameMappings {
|
||||
*mapping.viewPtr, err = gui.prepareView(mapping.name)
|
||||
if err != nil && err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
gui.Views.Options.Frame = false
|
||||
gui.Views.Options.FgColor = theme.OptionsColor
|
||||
|
||||
gui.Views.SearchPrefix.BgColor = gocui.ColorDefault
|
||||
gui.Views.SearchPrefix.FgColor = gocui.ColorGreen
|
||||
gui.Views.SearchPrefix.Frame = false
|
||||
gui.setViewContent(gui.Views.SearchPrefix, SEARCH_PREFIX)
|
||||
|
||||
gui.Views.Stash.Title = gui.c.Tr.StashTitle
|
||||
gui.Views.Stash.FgColor = theme.GocuiDefaultTextColor
|
||||
|
||||
gui.Views.Commits.Title = gui.c.Tr.CommitsTitle
|
||||
gui.Views.Commits.FgColor = theme.GocuiDefaultTextColor
|
||||
|
||||
gui.Views.CommitFiles.Title = gui.c.Tr.CommitFiles
|
||||
gui.Views.CommitFiles.FgColor = theme.GocuiDefaultTextColor
|
||||
|
||||
gui.Views.Branches.Title = gui.c.Tr.BranchesTitle
|
||||
gui.Views.Branches.FgColor = theme.GocuiDefaultTextColor
|
||||
|
||||
gui.Views.Files.Highlight = true
|
||||
gui.Views.Files.Title = gui.c.Tr.FilesTitle
|
||||
gui.Views.Files.FgColor = theme.GocuiDefaultTextColor
|
||||
|
||||
gui.Views.Secondary.Title = gui.c.Tr.DiffTitle
|
||||
gui.Views.Secondary.Wrap = true
|
||||
gui.Views.Secondary.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Secondary.IgnoreCarriageReturns = true
|
||||
|
||||
gui.Views.Main.Title = gui.c.Tr.DiffTitle
|
||||
gui.Views.Main.Wrap = true
|
||||
gui.Views.Main.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Main.IgnoreCarriageReturns = true
|
||||
|
||||
gui.Views.Limit.Title = gui.c.Tr.NotEnoughSpace
|
||||
gui.Views.Limit.Wrap = true
|
||||
|
||||
gui.Views.Status.Title = gui.c.Tr.StatusTitle
|
||||
gui.Views.Status.FgColor = theme.GocuiDefaultTextColor
|
||||
|
||||
gui.Views.Search.BgColor = gocui.ColorDefault
|
||||
gui.Views.Search.FgColor = gocui.ColorGreen
|
||||
gui.Views.Search.Frame = false
|
||||
gui.Views.Search.Editable = true
|
||||
|
||||
gui.Views.AppStatus.BgColor = gocui.ColorDefault
|
||||
gui.Views.AppStatus.FgColor = gocui.ColorCyan
|
||||
gui.Views.AppStatus.Frame = false
|
||||
gui.Views.AppStatus.Visible = false
|
||||
|
||||
gui.Views.CommitMessage.Visible = false
|
||||
gui.Views.CommitMessage.Title = gui.c.Tr.CommitMessage
|
||||
gui.Views.CommitMessage.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.CommitMessage.Editable = true
|
||||
gui.Views.CommitMessage.Editor = gocui.EditorFunc(gui.commitMessageEditor)
|
||||
|
||||
gui.Views.Confirmation.Visible = false
|
||||
|
||||
gui.Views.Credentials.Visible = false
|
||||
gui.Views.Credentials.Title = gui.c.Tr.CredentialsUsername
|
||||
gui.Views.Credentials.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Credentials.Editable = true
|
||||
|
||||
gui.Views.Suggestions.Visible = false
|
||||
|
||||
gui.Views.Menu.Visible = false
|
||||
|
||||
gui.Views.Information.BgColor = gocui.ColorDefault
|
||||
gui.Views.Information.FgColor = gocui.ColorGreen
|
||||
gui.Views.Information.Frame = false
|
||||
|
||||
gui.Views.Extras.Title = gui.c.Tr.CommandLog
|
||||
gui.Views.Extras.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Extras.Autoscroll = true
|
||||
gui.Views.Extras.Wrap = true
|
||||
|
||||
gui.printCommandLogHeader()
|
||||
|
||||
if _, err := gui.g.SetCurrentView(gui.defaultSideContext().GetViewName()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// layout is called for every screen re-render e.g. when the screen is resized
|
||||
func (gui *Gui) layout(g *gocui.Gui) error {
|
||||
if !gui.ViewsSetup {
|
||||
if err := gui.createAllViews(); err != nil {
|
||||
gui.printCommandLogHeader()
|
||||
|
||||
if _, err := gui.g.SetCurrentView(gui.defaultSideContext().GetViewName()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ func (gui *Gui) menuListContext() types.IListContext {
|
||||
Key: "menu",
|
||||
Kind: types.PERSISTENT_POPUP,
|
||||
OnGetOptionsMap: gui.getMenuOptions,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return gui.Views.Menu.LinesHeight() },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Menu },
|
||||
@ -55,6 +56,7 @@ func (gui *Gui) branchesListContext() types.IListContext {
|
||||
WindowName: "branches",
|
||||
Key: context.LOCAL_BRANCHES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.Branches) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Branches },
|
||||
@ -80,6 +82,7 @@ func (gui *Gui) remotesListContext() types.IListContext {
|
||||
WindowName: "branches",
|
||||
Key: context.REMOTES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.Remotes) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Remotes },
|
||||
@ -105,6 +108,7 @@ func (gui *Gui) remoteBranchesListContext() types.IListContext {
|
||||
WindowName: "branches",
|
||||
Key: context.REMOTE_BRANCHES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.RemoteBranches) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.RemoteBranches },
|
||||
@ -155,6 +159,7 @@ func (gui *Gui) branchCommitsListContext() types.IListContext {
|
||||
WindowName: "commits",
|
||||
Key: context.BRANCH_COMMITS_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.Commits) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Commits },
|
||||
@ -201,6 +206,7 @@ func (gui *Gui) subCommitsListContext() types.IListContext {
|
||||
WindowName: "branches",
|
||||
Key: context.SUB_COMMITS_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.SubCommits) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.SubCommits },
|
||||
@ -265,6 +271,7 @@ func (gui *Gui) reflogCommitsListContext() types.IListContext {
|
||||
WindowName: "commits",
|
||||
Key: context.REFLOG_COMMITS_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.FilteredReflogCommits) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.ReflogCommits },
|
||||
@ -296,6 +303,7 @@ func (gui *Gui) stashListContext() types.IListContext {
|
||||
WindowName: "stash",
|
||||
Key: context.STASH_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.StashEntries) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Stash },
|
||||
@ -345,6 +353,7 @@ func (gui *Gui) submodulesListContext() types.IListContext {
|
||||
WindowName: "files",
|
||||
Key: context.SUBMODULES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Model.Submodules) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Submodules },
|
||||
@ -370,6 +379,7 @@ func (gui *Gui) suggestionsListContext() types.IListContext {
|
||||
WindowName: "suggestions",
|
||||
Key: context.SUGGESTIONS_CONTEXT_KEY,
|
||||
Kind: types.PERSISTENT_POPUP,
|
||||
Focusable: true,
|
||||
}),
|
||||
GetItemsLength: func() int { return len(gui.State.Suggestions) },
|
||||
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.Suggestions },
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"os/exec"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type viewUpdateOpts struct {
|
||||
@ -16,6 +17,8 @@ type viewUpdateOpts struct {
|
||||
highlight bool
|
||||
|
||||
task updateTask
|
||||
|
||||
context types.Context
|
||||
}
|
||||
|
||||
type refreshMainOpts struct {
|
||||
@ -100,6 +103,11 @@ func (gui *Gui) refreshMainView(opts *viewUpdateOpts, view *gocui.View) error {
|
||||
view.Title = opts.title
|
||||
view.Wrap = !opts.noWrap
|
||||
view.Highlight = opts.highlight
|
||||
context := opts.context
|
||||
if context == nil {
|
||||
context = gui.State.Contexts.Normal
|
||||
}
|
||||
gui.ViewContextMapSet(view.Name(), context)
|
||||
|
||||
if err := gui.runTaskForView(view, opts.task); err != nil {
|
||||
gui.c.Log.Error(err)
|
||||
|
@ -153,9 +153,10 @@ func (gui *Gui) renderConflicts(hasFocus bool) error {
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
title: gui.c.Tr.MergeConflictsTitle,
|
||||
task: NewRenderStringWithoutScrollTask(content),
|
||||
noWrap: true,
|
||||
title: gui.c.Tr.MergeConflictsTitle,
|
||||
task: NewRenderStringWithoutScrollTask(content),
|
||||
context: gui.State.Contexts.Merging,
|
||||
noWrap: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -136,6 +136,7 @@ func (gui *Gui) secondaryPatchPanelUpdateOpts() *viewUpdateOpts {
|
||||
title: "Custom Patch",
|
||||
noWrap: true,
|
||||
highlight: true,
|
||||
context: gui.State.Contexts.PatchBuilding,
|
||||
task: NewRenderStringWithoutScrollTask(patch),
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ type IBaseContext interface {
|
||||
GetWindowName() string
|
||||
SetWindowName(string)
|
||||
GetKey() ContextKey
|
||||
IsFocusable() bool
|
||||
|
||||
GetOptionsMap() map[string]string
|
||||
|
||||
|
2
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
2
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
@ -1441,7 +1441,7 @@ func (g *Gui) matchView(v *View, kb *keybinding) bool {
|
||||
return true
|
||||
}
|
||||
for _, context := range kb.contexts {
|
||||
if context == g.currentContext {
|
||||
if context == v.Context {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
2
vendor/github.com/jesseduffield/gocui/view.go
generated
vendored
2
vendor/github.com/jesseduffield/gocui/view.go
generated
vendored
@ -149,6 +149,8 @@ type View struct {
|
||||
// ParentView is the view which catches events bubbled up from the given view if there's no matching handler
|
||||
ParentView *View
|
||||
|
||||
Context string // this is for assigning keybindings to a view only in certain contexts
|
||||
|
||||
searcher *searcher
|
||||
|
||||
// KeybindOnEdit should be set to true when you want to execute keybindings even when the view is editable
|
||||
|
Loading…
x
Reference in New Issue
Block a user