1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-02-07 13:42:01 +02:00

more efficient context diff size changing

This commit is contained in:
Jesse Duffield 2021-11-21 12:48:49 +11:00
parent de0e885c65
commit 1996eddd91
25 changed files with 255 additions and 159 deletions

View File

@ -120,6 +120,8 @@ func TestGitCommandShowCmdStr(t *testing.T) {
expected string
}
gitCmd := NewDummyGitCommand()
scenarios := []scenario{
{
testName: "Default case without filter path",
@ -131,7 +133,7 @@ func TestGitCommandShowCmdStr(t *testing.T) {
testName: "Default case with filter path",
filterPath: "file.txt",
contextSize: 3,
expected: "git show --submodule --color=always --unified=3 --no-renames --stat -p 1234567890 -- \"file.txt\"",
expected: "git show --submodule --color=always --unified=3 --no-renames --stat -p 1234567890 -- " + gitCmd.OSCommand.Quote("file.txt"),
},
{
testName: "Show diff with custom context size",
@ -143,7 +145,6 @@ func TestGitCommandShowCmdStr(t *testing.T) {
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
gitCmd := NewDummyGitCommand()
gitCmd.Config.GetUserConfig().Git.DiffContextSize = s.contextSize
cmdStr := gitCmd.ShowCmdStr("1234567890", s.filterPath)
assert.Equal(t, s.expected, cmdStr)

View File

@ -444,13 +444,13 @@ func TestGitCommandDiff(t *testing.T) {
// TestGitCommandShowFileDiff is a function.
func TestGitCommandShowFileDiff(t *testing.T) {
type scenario struct {
testName string
command func(string, ...string) *exec.Cmd
from string
to string
reverse bool
plain bool
contextSize int
testName string
command func(string, ...string) *exec.Cmd
from string
to string
reverse bool
plain bool
contextSize int
}
scenarios := []scenario{
@ -489,7 +489,7 @@ func TestGitCommandShowFileDiff(t *testing.T) {
gitCmd := NewDummyGitCommand()
gitCmd.OSCommand.Command = s.command
gitCmd.Config.GetUserConfig().Git.DiffContextSize = s.contextSize
gitCmd.ShowFileDiff(s.from, s.to, s.reverse, "test.txt", s.plain)
_, _ = gitCmd.ShowFileDiff(s.from, s.to, s.reverse, "test.txt", s.plain)
})
}
}

View File

@ -70,9 +70,9 @@ type GitConfig struct {
DisableForcePushing bool `yaml:"disableForcePushing"`
CommitPrefixes map[string]CommitPrefixConfig `yaml:"commitPrefixes"`
// this shoudl really be under 'gui', not 'git'
ParseEmoji bool `yaml:"parseEmoji"`
Log LogConfig `yaml:"log"`
DiffContextSize int `yaml:"diffContextSize"`
ParseEmoji bool `yaml:"parseEmoji"`
Log LogConfig `yaml:"log"`
DiffContextSize int `yaml:"diffContextSize"`
}
type PagingConfig struct {

View File

@ -1,9 +1,11 @@
package gui
type BasicContext struct {
OnFocus func() error
OnFocusLost func() error
OnRender func() error
OnFocus func(opts ...OnFocusOpts) error
OnFocusLost func() error
OnRender func() error
// this is for pushing some content to the main view
OnRenderToMain func(opts ...OnFocusOpts) error
Kind ContextKind
Key ContextKey
ViewName string
@ -15,63 +17,83 @@ type BasicContext struct {
hasParent bool
}
func (c *BasicContext) GetOptionsMap() map[string]string {
if c.OnGetOptionsMap != nil {
return c.OnGetOptionsMap()
func (self *BasicContext) GetOptionsMap() map[string]string {
if self.OnGetOptionsMap != nil {
return self.OnGetOptionsMap()
}
return nil
}
func (c *BasicContext) SetParentContext(context Context) {
c.ParentContext = context
c.hasParent = true
func (self *BasicContext) SetParentContext(context Context) {
self.ParentContext = context
self.hasParent = true
}
func (c *BasicContext) GetParentContext() (Context, bool) {
return c.ParentContext, c.hasParent
func (self *BasicContext) GetParentContext() (Context, bool) {
return self.ParentContext, self.hasParent
}
func (c *BasicContext) SetWindowName(windowName string) {
c.WindowName = windowName
func (self *BasicContext) SetWindowName(windowName string) {
self.WindowName = windowName
}
func (c *BasicContext) GetWindowName() string {
windowName := c.WindowName
func (self *BasicContext) GetWindowName() string {
windowName := self.WindowName
if windowName != "" {
return windowName
}
// TODO: actually set this for everything so we don't default to the view name
return c.ViewName
return self.ViewName
}
func (c *BasicContext) HandleRender() error {
if c.OnRender != nil {
return c.OnRender()
func (self *BasicContext) HandleRender() error {
if self.OnRender != nil {
return self.OnRender()
}
return nil
}
func (c *BasicContext) GetViewName() string {
return c.ViewName
func (self *BasicContext) GetViewName() string {
return self.ViewName
}
func (c *BasicContext) HandleFocus() error {
return c.OnFocus()
func (self *BasicContext) HandleFocus(opts ...OnFocusOpts) error {
if self.OnFocus != nil {
if err := self.OnFocus(opts...); err != nil {
return err
}
}
if self.OnRenderToMain != nil {
if err := self.OnRenderToMain(opts...); err != nil {
return err
}
}
return nil
}
func (c *BasicContext) HandleFocusLost() error {
if c.OnFocusLost != nil {
return c.OnFocusLost()
func (self *BasicContext) HandleFocusLost() error {
if self.OnFocusLost != nil {
return self.OnFocusLost()
}
return nil
}
func (c *BasicContext) GetKind() ContextKind {
return c.Kind
func (self *BasicContext) HandleRenderToMain() error {
if self.OnRenderToMain != nil {
return self.OnRenderToMain()
}
return nil
}
func (c *BasicContext) GetKey() ContextKey {
return c.Key
func (self *BasicContext) GetKind() ContextKind {
return self.Kind
}
func (self *BasicContext) GetKey() ContextKey {
return self.Key
}

View File

@ -25,7 +25,7 @@ func (gui *Gui) getSelectedBranch() *models.Branch {
return gui.State.Branches[selectedLine]
}
func (gui *Gui) handleBranchSelect() error {
func (gui *Gui) branchesRenderToMain() error {
var task updateTask
branch := gui.getSelectedBranch()
if branch == nil {

View File

@ -31,9 +31,12 @@ func (gui *Gui) getSelectedCommitFilePath() string {
return node.GetPath()
}
func (gui *Gui) handleCommitFileSelect() error {
func (gui *Gui) onCommitFileFocus() error {
gui.escapeLineByLinePanel()
return nil
}
func (gui *Gui) commitFilesRenderToMain() error {
node := gui.getSelectedCommitFileNode()
if node == nil {
return nil
@ -198,10 +201,10 @@ func (gui *Gui) startPatchManager() error {
}
func (gui *Gui) handleEnterCommitFile() error {
return gui.enterCommitFile(-1)
return gui.enterCommitFile(OnFocusOpts{ClickedViewName: "", ClickedViewLineIdx: -1})
}
func (gui *Gui) enterCommitFile(selectedLineIdx int) error {
func (gui *Gui) enterCommitFile(opts OnFocusOpts) error {
node := gui.getSelectedCommitFileNode()
if node == nil {
return nil
@ -211,17 +214,14 @@ func (gui *Gui) enterCommitFile(selectedLineIdx int) error {
return gui.handleToggleCommitFileDirCollapsed()
}
enterTheFile := func(selectedLineIdx int) error {
enterTheFile := func() error {
if !gui.GitCommand.PatchManager.Active() {
if err := gui.startPatchManager(); err != nil {
return err
}
}
if err := gui.pushContext(gui.State.Contexts.PatchBuilding); err != nil {
return err
}
return gui.handleRefreshPatchBuildingPanel(selectedLineIdx)
return gui.pushContext(gui.State.Contexts.PatchBuilding, opts)
}
if gui.GitCommand.PatchManager.Active() && gui.GitCommand.PatchManager.To != gui.State.CommitFileManager.GetParent() {
@ -231,7 +231,7 @@ func (gui *Gui) enterCommitFile(selectedLineIdx int) error {
handlersManageFocus: true,
handleConfirm: func() error {
gui.GitCommand.PatchManager.Reset()
return enterTheFile(selectedLineIdx)
return enterTheFile()
},
handleClose: func() error {
return gui.pushContext(gui.State.Contexts.CommitFiles)
@ -239,7 +239,7 @@ func (gui *Gui) enterCommitFile(selectedLineIdx int) error {
})
}
return enterTheFile(selectedLineIdx)
return enterTheFile()
}
func (gui *Gui) handleToggleCommitFileDirCollapsed() error {

View File

@ -24,7 +24,7 @@ func (gui *Gui) getSelectedLocalCommit() *models.Commit {
return gui.State.Commits[selectedLine]
}
func (gui *Gui) handleCommitSelect() error {
func (gui *Gui) onCommitFocus() error {
state := gui.State.Panels.Commits
if state.SelectedLineIdx > COMMIT_THRESHOLD && state.LimitCommits {
state.LimitCommits = false
@ -37,6 +37,10 @@ func (gui *Gui) handleCommitSelect() error {
gui.escapeLineByLinePanel()
return nil
}
func (gui *Gui) branchCommitsRenderToMain() error {
var task updateTask
commit := gui.getSelectedLocalCommit()
if commit == nil {

View File

@ -1,6 +1,7 @@
package gui
import (
"errors"
"fmt"
"github.com/jesseduffield/gocui"
@ -16,10 +17,16 @@ const (
EXTRAS_CONTEXT
)
type OnFocusOpts struct {
ClickedViewName string
ClickedViewLineIdx int
}
type Context interface {
HandleFocus() error
HandleFocus(opts ...OnFocusOpts) error
HandleFocusLost() error
HandleRender() error
HandleRenderToMain() error
GetKind() ContextKind
GetViewName() string
GetWindowName() string
@ -81,15 +88,20 @@ func (gui *Gui) replaceContext(c Context) error {
return nil
}
func (gui *Gui) pushContext(c Context) error {
func (gui *Gui) pushContext(c Context, opts ...OnFocusOpts) error {
// using triple dot but you should only ever pass one of these opt structs
if len(opts) > 1 {
return errors.New("cannot pass multiple opts to pushContext")
}
gui.g.Update(func(*gocui.Gui) error {
return gui.pushContextDirect(c)
return gui.pushContextDirect(c, opts...)
})
return nil
}
func (gui *Gui) pushContextDirect(c Context) error {
func (gui *Gui) pushContextDirect(c Context, opts ...OnFocusOpts) error {
gui.State.ContextManager.Lock()
// push onto stack
@ -114,7 +126,7 @@ func (gui *Gui) pushContextDirect(c Context) error {
gui.State.ContextManager.Unlock()
return gui.activateContext(c)
return gui.activateContext(c, opts...)
}
// asynchronous code idea: functions return an error via a channel, when done
@ -206,7 +218,7 @@ func (gui *Gui) postRefreshUpdate(c Context) error {
return nil
}
func (gui *Gui) activateContext(c Context) error {
func (gui *Gui) activateContext(c Context, opts ...OnFocusOpts) error {
viewName := c.GetViewName()
v, err := gui.g.View(viewName)
if err != nil {
@ -249,7 +261,7 @@ func (gui *Gui) activateContext(c Context) error {
}
gui.renderOptionsMap(optionsMap)
if err := c.HandleFocus(); err != nil {
if err := c.HandleFocus(opts...); err != nil {
return err
}

View File

@ -110,10 +110,10 @@ func (gui *Gui) allContexts() []Context {
func (gui *Gui) contextTree() ContextTree {
return ContextTree{
Status: &BasicContext{
OnFocus: gui.handleStatusSelect,
Kind: SIDE_CONTEXT,
ViewName: "status",
Key: STATUS_CONTEXT_KEY,
OnRenderToMain: OnFocusWrapper(gui.statusRenderToMain),
Kind: SIDE_CONTEXT,
ViewName: "status",
Key: STATUS_CONTEXT_KEY,
},
Files: gui.filesListContext(),
Submodules: gui.submodulesListContext(),
@ -128,7 +128,7 @@ func (gui *Gui) contextTree() ContextTree {
Tags: gui.tagsListContext(),
Stash: gui.stashListContext(),
Normal: &BasicContext{
OnFocus: func() error {
OnFocus: func(opts ...OnFocusOpts) error {
return nil // TODO: should we do something here? We should allow for scrolling the panel
},
Kind: MAIN_CONTEXT,
@ -136,65 +136,67 @@ func (gui *Gui) contextTree() ContextTree {
Key: MAIN_NORMAL_CONTEXT_KEY,
},
Staging: &BasicContext{
OnFocus: func() error {
return nil
// TODO: centralise the code here
// return gui.refreshStagingPanel(false, -1)
},
OnRender: func() error {
return gui.handleRefreshStagingPanel(false, -1)
OnRenderToMain: func(opts ...OnFocusOpts) error {
forceSecondaryFocused := false
selectedLineIdx := -1
if len(opts) > 0 && opts[0].ClickedViewName != "" {
if opts[0].ClickedViewName == "main" || opts[0].ClickedViewName == "secondary" {
selectedLineIdx = opts[0].ClickedViewLineIdx
}
if opts[0].ClickedViewName == "secondary" {
forceSecondaryFocused = true
}
}
return gui.handleRefreshStagingPanel(forceSecondaryFocused, selectedLineIdx)
},
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)
},
OnRender: func() error {
return gui.handleRefreshPatchBuildingPanel(-1)
OnRenderToMain: func(opts ...OnFocusOpts) error {
selectedLineIdx := -1
if len(opts) > 0 && (opts[0].ClickedViewName == "main" || opts[0].ClickedViewName == "secondary") {
selectedLineIdx = opts[0].ClickedViewLineIdx
}
return gui.handleRefreshPatchBuildingPanel(selectedLineIdx)
},
Kind: MAIN_CONTEXT,
ViewName: "main",
Key: MAIN_PATCH_BUILDING_CONTEXT_KEY,
},
Merging: &BasicContext{
OnFocus: gui.refreshMergePanelWithLock,
OnFocus: OnFocusWrapper(gui.refreshMergePanelWithLock),
Kind: MAIN_CONTEXT,
ViewName: "main",
Key: MAIN_MERGING_CONTEXT_KEY,
OnGetOptionsMap: gui.getMergingOptions,
},
Credentials: &BasicContext{
OnFocus: gui.handleCredentialsViewFocused,
OnFocus: OnFocusWrapper(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,
OnFocus: OnFocusWrapper(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,
},
CommandLog: &BasicContext{
OnFocus: func() error { return nil },
Kind: EXTRAS_CONTEXT,
ViewName: "extras",
Key: COMMAND_LOG_CONTEXT_KEY,
@ -207,6 +209,14 @@ func (gui *Gui) contextTree() ContextTree {
}
}
// using this wrapper for when an onFocus function doesn't care about any potential
// props that could be passed
func OnFocusWrapper(f func() error) func(opts ...OnFocusOpts) error {
return func(opts ...OnFocusOpts) error {
return f()
}
}
func (tree ContextTree) initialViewContextMap() map[string]Context {
return map[string]Context{
"status": tree.Status,

View File

@ -1,5 +1,9 @@
package gui
import (
"errors"
)
func isShowingDiff(gui *Gui) bool {
key := gui.currentStaticContext().GetKey()
@ -8,8 +12,12 @@ func isShowingDiff(gui *Gui) bool {
func (gui *Gui) IncreaseContextInDiffView() error {
if isShowingDiff(gui) {
if err := gui.CheckCanChangeContext(); err != nil {
return gui.surfaceError(err)
}
gui.Config.GetUserConfig().Git.DiffContextSize = gui.Config.GetUserConfig().Git.DiffContextSize + 1
return gui.postRefreshUpdate(gui.currentStaticContext())
return gui.currentStaticContext().HandleRenderToMain()
}
return nil
@ -19,8 +27,20 @@ func (gui *Gui) DecreaseContextInDiffView() error {
old_size := gui.Config.GetUserConfig().Git.DiffContextSize
if isShowingDiff(gui) && old_size > 1 {
if err := gui.CheckCanChangeContext(); err != nil {
return gui.surfaceError(err)
}
gui.Config.GetUserConfig().Git.DiffContextSize = old_size - 1
return gui.postRefreshUpdate(gui.currentStaticContext())
return gui.currentStaticContext().HandleRenderToMain()
}
return nil
}
func (gui *Gui) CheckCanChangeContext() error {
if gui.GitCommand.PatchManager.Active() {
return errors.New(gui.Tr.CantChangeContextSizeError)
}
return nil

View File

@ -28,11 +28,11 @@ func setupGuiForTest(gui *Gui) {
gui.Views.Main, _ = gui.prepareView("main")
gui.Views.Secondary, _ = gui.prepareView("secondary")
gui.GitCommand.PatchManager = &patch.PatchManager{}
gui.refreshLineByLinePanel(diffForTest, "", false, 11)
gui.refreshLineByLinePanel(diffForTest, "", false, 11)
}
func TestIncreasesContextInDiffViewByOneInContextWithDiff(t *testing.T) {
contexts := []func(gui *Gui) Context {
contexts := []func(gui *Gui) Context{
func(gui *Gui) Context { return gui.State.Contexts.Files },
func(gui *Gui) Context { return gui.State.Contexts.BranchCommits },
func(gui *Gui) Context { return gui.State.Contexts.CommitFiles },
@ -56,7 +56,7 @@ func TestIncreasesContextInDiffViewByOneInContextWithDiff(t *testing.T) {
}
func TestDoesntIncreaseContextInDiffViewInContextWithoutDiff(t *testing.T) {
contexts := []func(gui *Gui) Context {
contexts := []func(gui *Gui) Context{
func(gui *Gui) Context { return gui.State.Contexts.Status },
func(gui *Gui) Context { return gui.State.Contexts.Submodules },
func(gui *Gui) Context { return gui.State.Contexts.Remotes },
@ -82,7 +82,7 @@ func TestDoesntIncreaseContextInDiffViewInContextWithoutDiff(t *testing.T) {
}
func TestDecreasesContextInDiffViewByOneInContextWithDiff(t *testing.T) {
contexts := []func(gui *Gui) Context {
contexts := []func(gui *Gui) Context{
func(gui *Gui) Context { return gui.State.Contexts.Files },
func(gui *Gui) Context { return gui.State.Contexts.BranchCommits },
func(gui *Gui) Context { return gui.State.Contexts.CommitFiles },
@ -106,7 +106,7 @@ func TestDecreasesContextInDiffViewByOneInContextWithDiff(t *testing.T) {
}
func TestDoesntDecreaseContextInDiffViewInContextWithoutDiff(t *testing.T) {
contexts := []func(gui *Gui) Context {
contexts := []func(gui *Gui) Context{
func(gui *Gui) Context { return gui.State.Contexts.Status },
func(gui *Gui) Context { return gui.State.Contexts.Submodules },
func(gui *Gui) Context { return gui.State.Contexts.Remotes },
@ -119,7 +119,7 @@ func TestDoesntDecreaseContextInDiffViewInContextWithoutDiff(t *testing.T) {
}
for _, c := range contexts {
gui := NewDummyGui()
gui := NewDummyGui()
context := c(gui)
setupGuiForTest(gui)
gui.Config.GetUserConfig().Git.DiffContextSize = 2
@ -131,6 +131,30 @@ func TestDoesntDecreaseContextInDiffViewInContextWithoutDiff(t *testing.T) {
}
}
func TestDoesntIncreaseContextInDiffViewInContextWhenInPatchBuildingMode(t *testing.T) {
gui := NewDummyGui()
setupGuiForTest(gui)
gui.Config.GetUserConfig().Git.DiffContextSize = 2
gui.pushContextDirect(gui.State.Contexts.CommitFiles)
gui.GitCommand.PatchManager.Start("from", "to", false, false)
gui.IncreaseContextInDiffView()
assert.Equal(t, 2, gui.Config.GetUserConfig().Git.DiffContextSize)
}
func TestDoesntDecreaseContextInDiffViewInContextWhenInPatchBuildingMode(t *testing.T) {
gui := NewDummyGui()
setupGuiForTest(gui)
gui.Config.GetUserConfig().Git.DiffContextSize = 2
gui.pushContextDirect(gui.State.Contexts.CommitFiles)
gui.GitCommand.PatchManager.Start("from", "to", false, false)
gui.DecreaseContextInDiffView()
assert.Equal(t, 2, gui.Config.GetUserConfig().Git.DiffContextSize)
}
func TestDecreasesContextInDiffViewNoFurtherThanOne(t *testing.T) {
gui := NewDummyGui()
setupGuiForTest(gui)

View File

@ -42,9 +42,7 @@ func (gui *Gui) getSelectedPath() string {
return node.GetPath()
}
func (gui *Gui) selectFile(alreadySelected bool) error {
gui.Views.Files.FocusPoint(0, gui.State.Panels.Files.SelectedLineIdx)
func (gui *Gui) filesRenderToMain() error {
node := gui.getSelectedFileNode()
if node == nil {
@ -56,10 +54,6 @@ func (gui *Gui) selectFile(alreadySelected bool) error {
})
}
if !alreadySelected {
gui.takeOverMergeConflictScrolling()
}
if node.File != nil && node.File.HasInlineMergeConflicts {
return gui.refreshMergePanelWithLock()
}
@ -121,9 +115,12 @@ func (gui *Gui) refreshFilesAndSubmodules() error {
if gui.currentContext().GetKey() == FILES_CONTEXT_KEY || (g.CurrentView() == gui.Views.Main && ContextKey(g.CurrentView().Context) == MAIN_MERGING_CONTEXT_KEY) {
newSelectedPath := gui.getSelectedPath()
alreadySelected := selectedPath != "" && newSelectedPath == selectedPath
if err := gui.selectFile(alreadySelected); err != nil {
return err
if !alreadySelected {
gui.takeOverMergeConflictScrolling()
}
gui.Views.Files.FocusPoint(0, gui.State.Panels.Files.SelectedLineIdx)
return gui.filesRenderToMain()
}
return nil
@ -166,10 +163,10 @@ func (gui *Gui) stageSelectedFile() error {
}
func (gui *Gui) handleEnterFile() error {
return gui.enterFile(false, -1)
return gui.enterFile(OnFocusOpts{ClickedViewName: "", ClickedViewLineIdx: -1})
}
func (gui *Gui) enterFile(forceSecondaryFocused bool, selectedLineIdx int) error {
func (gui *Gui) enterFile(opts OnFocusOpts) error {
node := gui.getSelectedFileNode()
if node == nil {
return nil
@ -193,9 +190,8 @@ func (gui *Gui) enterFile(forceSecondaryFocused bool, selectedLineIdx int) error
if file.HasMergeConflicts {
return gui.createErrorPanel(gui.Tr.FileStagingRequirements)
}
_ = gui.pushContext(gui.State.Contexts.Staging)
return gui.handleRefreshStagingPanel(forceSecondaryFocused, selectedLineIdx) // TODO: check if this is broken, try moving into context code
return gui.pushContext(gui.State.Contexts.Staging, opts)
}
func (gui *Gui) handleFilePress() error {
@ -243,7 +239,7 @@ func (gui *Gui) handleFilePress() error {
return err
}
return gui.selectFile(true)
return gui.State.Contexts.Files.HandleFocus()
}
func (gui *Gui) allFilesStaged() bool {
@ -255,8 +251,9 @@ func (gui *Gui) allFilesStaged() bool {
return true
}
func (gui *Gui) focusAndSelectFile() error {
return gui.selectFile(false)
func (gui *Gui) onFocusFile() error {
gui.takeOverMergeConflictScrolling()
return nil
}
func (gui *Gui) handleStageAll() error {
@ -274,7 +271,7 @@ func (gui *Gui) handleStageAll() error {
return err
}
return gui.selectFile(false)
return gui.State.Contexts.Files.HandleFocus()
}
func (gui *Gui) handleIgnoreFile() error {

View File

@ -189,9 +189,9 @@ func (gui *Gui) handleMouseDownMain() error {
// set filename, set primary/secondary selected, set line number, then switch context
// I'll need to know it was changed though.
// Could I pass something along to the context change?
return gui.enterFile(false, gui.Views.Main.SelectedLineIdx())
return gui.enterFile(OnFocusOpts{ClickedViewName: "main", ClickedViewLineIdx: gui.Views.Main.SelectedLineIdx()})
case gui.State.Contexts.CommitFiles:
return gui.enterCommitFile(gui.Views.Main.SelectedLineIdx())
return gui.enterCommitFile(OnFocusOpts{ClickedViewName: "main", ClickedViewLineIdx: gui.Views.Main.SelectedLineIdx()})
}
return nil
@ -204,7 +204,7 @@ func (gui *Gui) handleMouseDownSecondary() error {
switch gui.g.CurrentView() {
case gui.Views.Files:
return gui.enterFile(true, gui.Views.Secondary.SelectedLineIdx())
return gui.enterFile(OnFocusOpts{ClickedViewName: "secondary", ClickedViewLineIdx: gui.Views.Secondary.SelectedLineIdx()})
}
return nil

View File

@ -9,7 +9,8 @@ import (
type ListContext struct {
GetItemsLength func() int
GetDisplayStrings func(startIdx int, length int) [][]string
OnFocus func() error
OnFocus func(...OnFocusOpts) error
OnRenderToMain func(...OnFocusOpts) error
OnFocusLost func() error
OnClickSelectedItem func() error
@ -29,7 +30,6 @@ type ListContext struct {
type IListContext interface {
GetSelectedItem() (ListItem, bool)
GetSelectedItemId() string
OnRender() error
handlePrevLine() error
handleNextLine() error
handleScrollLeft() error
@ -42,6 +42,7 @@ type IListContext interface {
handleClick() error
onSearchSelect(selectedLineIdx int) error
FocusLine()
HandleRenderToMain() error
GetPanelState() IListPanelState
@ -101,7 +102,7 @@ func (self *ListContext) GetSelectedItemId() string {
}
// OnFocus assumes that the content of the context has already been rendered to the view. OnRender is the function which actually renders the content to the view
func (self *ListContext) OnRender() error {
func (self *ListContext) HandleRender() error {
view, err := self.Gui.g.View(self.ViewName)
if err != nil {
return nil
@ -131,7 +132,7 @@ func (self *ListContext) HandleFocusLost() error {
return nil
}
func (self *ListContext) HandleFocus() error {
func (self *ListContext) HandleFocus(opts ...OnFocusOpts) error {
if self.Gui.popupPanelFocused() {
return nil
}
@ -143,16 +144,20 @@ func (self *ListContext) HandleFocus() error {
}
if self.OnFocus != nil {
return self.OnFocus()
if err := self.OnFocus(opts...); err != nil {
return err
}
}
if self.OnRenderToMain != nil {
if err := self.OnRenderToMain(opts...); err != nil {
return err
}
}
return nil
}
func (self *ListContext) HandleRender() error {
return self.OnRender()
}
func (self *ListContext) handlePrevLine() error {
return self.handleLineChange(-1)
}
@ -268,3 +273,11 @@ func (self *ListContext) onSearchSelect(selectedLineIdx int) error {
self.GetPanelState().SetSelectedLineIdx(selectedLineIdx)
return self.HandleFocus()
}
func (self *ListContext) HandleRenderToMain() error {
if self.OnRenderToMain != nil {
return self.OnRenderToMain()
}
return nil
}

View File

@ -18,7 +18,6 @@ func (gui *Gui) menuListContext() IListContext {
},
GetItemsLength: func() int { return gui.Views.Menu.LinesHeight() },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Menu },
OnFocus: gui.handleMenuSelect,
OnClickSelectedItem: gui.onMenuPress,
Gui: gui,
@ -36,7 +35,8 @@ func (gui *Gui) filesListContext() IListContext {
},
GetItemsLength: func() int { return gui.State.FileManager.GetItemsLength() },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Files },
OnFocus: gui.focusAndSelectFile,
OnFocus: OnFocusWrapper(gui.onFocusFile),
OnRenderToMain: OnFocusWrapper(gui.filesRenderToMain),
OnClickSelectedItem: gui.handleFilePress,
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
@ -65,7 +65,7 @@ func (gui *Gui) branchesListContext() IListContext {
},
GetItemsLength: func() int { return len(gui.State.Branches) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Branches },
OnFocus: gui.handleBranchSelect,
OnRenderToMain: OnFocusWrapper(gui.branchesRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetBranchListDisplayStrings(gui.State.Branches, gui.State.ScreenMode != SCREEN_NORMAL, gui.State.Modes.Diffing.Ref)
@ -87,7 +87,7 @@ func (gui *Gui) remotesListContext() IListContext {
},
GetItemsLength: func() int { return len(gui.State.Remotes) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Remotes },
OnFocus: gui.handleRemoteSelect,
OnRenderToMain: OnFocusWrapper(gui.remotesRenderToMain),
OnClickSelectedItem: gui.handleRemoteEnter,
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
@ -110,7 +110,7 @@ func (gui *Gui) remoteBranchesListContext() IListContext {
},
GetItemsLength: func() int { return len(gui.State.RemoteBranches) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.RemoteBranches },
OnFocus: gui.handleRemoteBranchSelect,
OnRenderToMain: OnFocusWrapper(gui.remoteBranchesRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetRemoteBranchListDisplayStrings(gui.State.RemoteBranches, gui.State.Modes.Diffing.Ref)
@ -132,7 +132,7 @@ func (gui *Gui) tagsListContext() IListContext {
},
GetItemsLength: func() int { return len(gui.State.Tags) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Tags },
OnFocus: gui.handleTagSelect,
OnRenderToMain: OnFocusWrapper(gui.tagsRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetTagListDisplayStrings(gui.State.Tags, gui.State.Modes.Diffing.Ref)
@ -155,7 +155,8 @@ func (gui *Gui) branchCommitsListContext() IListContext {
},
GetItemsLength: func() int { return len(gui.State.Commits) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Commits },
OnFocus: gui.handleCommitSelect,
OnFocus: OnFocusWrapper(gui.onCommitFocus),
OnRenderToMain: OnFocusWrapper(gui.branchCommitsRenderToMain),
OnClickSelectedItem: gui.handleViewCommitFiles,
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
@ -197,7 +198,7 @@ func (gui *Gui) subCommitsListContext() IListContext {
},
GetItemsLength: func() int { return len(gui.State.SubCommits) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.SubCommits },
OnFocus: gui.handleSubCommitSelect,
OnRenderToMain: OnFocusWrapper(gui.subCommitsRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
selectedCommitSha := ""
@ -253,7 +254,7 @@ func (gui *Gui) reflogCommitsListContext() IListContext {
},
GetItemsLength: func() int { return len(gui.State.FilteredReflogCommits) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.ReflogCommits },
OnFocus: gui.handleReflogCommitSelect,
OnRenderToMain: OnFocusWrapper(gui.reflogCommitsRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetReflogCommitListDisplayStrings(
@ -281,7 +282,7 @@ func (gui *Gui) stashListContext() IListContext {
},
GetItemsLength: func() int { return len(gui.State.StashEntries) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Stash },
OnFocus: gui.handleStashEntrySelect,
OnRenderToMain: OnFocusWrapper(gui.stashRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetStashEntryListDisplayStrings(gui.State.StashEntries, gui.State.Modes.Diffing.Ref)
@ -303,7 +304,8 @@ func (gui *Gui) commitFilesListContext() IListContext {
},
GetItemsLength: func() int { return gui.State.CommitFileManager.GetItemsLength() },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.CommitFiles },
OnFocus: gui.handleCommitFileSelect,
OnFocus: OnFocusWrapper(gui.onCommitFileFocus),
OnRenderToMain: OnFocusWrapper(gui.commitFilesRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
if gui.State.CommitFileManager.GetItemsLength() == 0 {
@ -335,7 +337,7 @@ func (gui *Gui) submodulesListContext() IListContext {
},
GetItemsLength: func() int { return len(gui.State.Submodules) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Submodules },
OnFocus: gui.handleSubmoduleSelect,
OnRenderToMain: OnFocusWrapper(gui.submodulesRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetSubmoduleListDisplayStrings(gui.State.Submodules)
@ -357,7 +359,6 @@ func (gui *Gui) suggestionsListContext() IListContext {
},
GetItemsLength: func() int { return len(gui.State.Suggestions) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Suggestions },
OnFocus: func() error { return nil },
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetSuggestionListDisplayStrings(gui.State.Suggestions)

View File

@ -5,7 +5,6 @@ import (
"fmt"
"strings"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/theme"
"github.com/jesseduffield/lazygit/pkg/utils"
)
@ -27,12 +26,6 @@ func (i *menuItem) ID() string {
return strings.Join(i.displayStrings, "-")
}
// list panel functions
func (gui *Gui) handleMenuSelect() error {
return nil
}
// specific functions
func (gui *Gui) getMenuOptions() map[string]string {
@ -95,10 +88,7 @@ func (gui *Gui) createMenu(title string, items []*menuItem, createMenuOptions cr
menuView.SetContent(list)
gui.State.Panels.Menu.SelectedLineIdx = 0
gui.g.Update(func(g *gocui.Gui) error {
return gui.pushContext(gui.State.Contexts.Menu)
})
return nil
return gui.pushContext(gui.State.Contexts.Menu)
}
func (gui *Gui) onMenuPress() error {

View File

@ -16,7 +16,7 @@ func (gui *Gui) getSelectedReflogCommit() *models.Commit {
return reflogComits[selectedLine]
}
func (gui *Gui) handleReflogCommitSelect() error {
func (gui *Gui) reflogCommitsRenderToMain() error {
commit := gui.getSelectedReflogCommit()
var task updateTask
if commit == nil {

View File

@ -18,7 +18,7 @@ func (gui *Gui) getSelectedRemoteBranch() *models.RemoteBranch {
return gui.State.RemoteBranches[selectedLine]
}
func (gui *Gui) handleRemoteBranchSelect() error {
func (gui *Gui) remoteBranchesRenderToMain() error {
var task updateTask
remoteBranch := gui.getSelectedRemoteBranch()
if remoteBranch == nil {

View File

@ -20,7 +20,7 @@ func (gui *Gui) getSelectedRemote() *models.Remote {
return gui.State.Remotes[selectedLine]
}
func (gui *Gui) handleRemoteSelect() error {
func (gui *Gui) remotesRenderToMain() error {
var task updateTask
remote := gui.getSelectedRemote()
if remote == nil {

View File

@ -16,7 +16,7 @@ func (gui *Gui) getSelectedStashEntry() *models.StashEntry {
return gui.State.StashEntries[selectedLine]
}
func (gui *Gui) handleStashEntrySelect() error {
func (gui *Gui) stashRenderToMain() error {
var task updateTask
stashEntry := gui.getSelectedStashEntry()
if stashEntry == nil {

View File

@ -86,10 +86,10 @@ func (gui *Gui) handleStatusClick() error {
}
}
return gui.handleStatusSelect()
return nil
}
func (gui *Gui) handleStatusSelect() error {
func (gui *Gui) statusRenderToMain() error {
// TODO: move into some abstraction (status is currently not a listViewContext where a lot of this code lives)
if gui.popupPanelFocused() {
return nil

View File

@ -17,7 +17,7 @@ func (gui *Gui) getSelectedSubCommit() *models.Commit {
return commits[selectedLine]
}
func (gui *Gui) handleSubCommitSelect() error {
func (gui *Gui) subCommitsRenderToMain() error {
commit := gui.getSelectedSubCommit()
var task updateTask
if commit == nil {

View File

@ -19,7 +19,7 @@ func (gui *Gui) getSelectedSubmodule() *models.SubmoduleConfig {
return gui.State.Submodules[selectedLine]
}
func (gui *Gui) handleSubmoduleSelect() error {
func (gui *Gui) submodulesRenderToMain() error {
var task updateTask
submodule := gui.getSelectedSubmodule()
if submodule == nil {

View File

@ -40,9 +40,7 @@ func (gui *Gui) handleCreateTag() error {
})
}
// tag-specific handlers
// view model would need to raise an event called 'tag selected', perhaps containing a tag. The listener would _be_ the main view, or the main context, and it would be able to render to itself.
func (gui *Gui) handleTagSelect() error {
func (gui *Gui) tagsRenderToMain() error {
var task updateTask
tag := gui.getSelectedTag()
if tag == nil {
@ -85,6 +83,8 @@ func (gui *Gui) withSelectedTag(f func(tag *models.Tag) error) func() error {
}
}
// tag-specific handlers
func (gui *Gui) handleCheckoutTag(tag *models.Tag) error {
if err := gui.handleCheckoutRef(tag.Name, handleCheckoutRefOptions{span: gui.Tr.Spans.CheckoutTag}); err != nil {
return err

View File

@ -449,6 +449,7 @@ type TranslationSet struct {
ToggleShowGitGraphAll string
ShowGitGraph string
SortCommits string
CantChangeContextSizeError string
Spans Spans
}
@ -991,6 +992,7 @@ func englishTranslationSet() TranslationSet {
ToggleShowGitGraphAll: "toggle show whole git graph (pass the `--all` flag to `git log`)",
ShowGitGraph: "show git graph",
SortCommits: "commit sort order",
CantChangeContextSizeError: "Cannot change context while in patch building mode because we were too lazy to support it when releasing the feature. If you really want it, please let us know!",
Spans: Spans{
// TODO: combine this with the original keybinding descriptions (those are all in lowercase atm)
CheckoutCommit: "Checkout commit",