diff --git a/go.mod b/go.mod index 69546555d..bc8009a98 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/integrii/flaggy v1.4.0 github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d - github.com/jesseduffield/gocui v0.3.1-0.20240623124136-ce5274be521d + github.com/jesseduffield/gocui v0.3.1-0.20240628061234-aed9e133e65b github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e diff --git a/go.sum b/go.sum index dae59e807..e575afcad 100644 --- a/go.sum +++ b/go.sum @@ -188,8 +188,8 @@ github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 h1:EQP2Tv8T github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk= github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d h1:bO+OmbreIv91rCe8NmscRwhFSqkDJtzWCPV4Y+SQuXE= github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o= -github.com/jesseduffield/gocui v0.3.1-0.20240623124136-ce5274be521d h1:I6rViLB+ZW5SnS8P7ZE0FdY6lMfx803qZ9ZYEYCvfro= -github.com/jesseduffield/gocui v0.3.1-0.20240623124136-ce5274be521d/go.mod h1:XtEbqCbn45keRXEu+OMZkjN5gw6AEob59afsgHjokZ8= +github.com/jesseduffield/gocui v0.3.1-0.20240628061234-aed9e133e65b h1:oxCq0DvR2GMGf4UaoaASb0nQK/fJMQW3c3PNCLWCjS8= +github.com/jesseduffield/gocui v0.3.1-0.20240628061234-aed9e133e65b/go.mod h1:XtEbqCbn45keRXEu+OMZkjN5gw6AEob59afsgHjokZ8= github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 h1:jmpr7KpX2+2GRiE91zTgfq49QvgiqB0nbmlwZ8UnOx0= github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10/go.mod h1:aA97kHeNA+sj2Hbki0pvLslmE4CbDyhBeSSTUUnOuVo= github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY= diff --git a/pkg/gui/context.go b/pkg/gui/context.go index 28ecf2405..5dc6df6a0 100644 --- a/pkg/gui/context.go +++ b/pkg/gui/context.go @@ -391,3 +391,12 @@ func (self *ContextMgr) ContextForKey(key types.ContextKey) types.Context { return nil } + +func (self *ContextMgr) PopupContexts() []types.Context { + self.RLock() + defer self.RUnlock() + + return lo.Filter(self.ContextStack, func(context types.Context, _ int) bool { + return context.GetKind() == types.TEMPORARY_POPUP || context.GetKind() == types.PERSISTENT_POPUP + }) +} diff --git a/pkg/gui/context/commit_message_context.go b/pkg/gui/context/commit_message_context.go index f69b7ef74..402f9b12e 100644 --- a/pkg/gui/context/commit_message_context.go +++ b/pkg/gui/context/commit_message_context.go @@ -116,6 +116,8 @@ func (self *CommitMessageContext) SetPanelState( "togglePanelKeyBinding": keybindings.Label(self.c.UserConfig.Keybinding.Universal.TogglePanel), "commitMenuKeybinding": keybindings.Label(self.c.UserConfig.Keybinding.CommitMessage.CommitMenu), }) + + self.c.Views().CommitDescription.Visible = true } func (self *CommitMessageContext) RenderCommitLength() { diff --git a/pkg/gui/controllers.go b/pkg/gui/controllers.go index d6ac5a268..ba39fef5a 100644 --- a/pkg/gui/controllers.go +++ b/pkg/gui/controllers.go @@ -404,7 +404,6 @@ func (gui *Gui) getCommitMessageSetTextareaTextFn(getView func() *gocui.View) fu view := getView() view.ClearTextArea() view.TextArea.TypeString(text) - gui.helpers.Confirmation.ResizeCommitMessagePanels() view.RenderTextArea() } } diff --git a/pkg/gui/controllers/commit_description_controller.go b/pkg/gui/controllers/commit_description_controller.go index 0c078382b..80608fff5 100644 --- a/pkg/gui/controllers/commit_description_controller.go +++ b/pkg/gui/controllers/commit_description_controller.go @@ -53,7 +53,7 @@ func (self *CommitDescriptionController) context() *context.CommitMessageContext } func (self *CommitDescriptionController) switchToCommitMessage() error { - return self.c.PushContext(self.c.Contexts().CommitMessage) + return self.c.ReplaceContext(self.c.Contexts().CommitMessage) } func (self *CommitDescriptionController) close() error { diff --git a/pkg/gui/controllers/commit_message_controller.go b/pkg/gui/controllers/commit_message_controller.go index 4012dc950..5c37b4da9 100644 --- a/pkg/gui/controllers/commit_message_controller.go +++ b/pkg/gui/controllers/commit_message_controller.go @@ -85,7 +85,7 @@ func (self *CommitMessageController) handleNextCommit() error { } func (self *CommitMessageController) switchToCommitDescription() error { - if err := self.c.PushContext(self.c.Contexts().CommitDescription); err != nil { + if err := self.c.ReplaceContext(self.c.Contexts().CommitDescription); err != nil { return err } return nil diff --git a/pkg/gui/controllers/custom_patch_options_menu_action.go b/pkg/gui/controllers/custom_patch_options_menu_action.go index f24607597..867e4528a 100644 --- a/pkg/gui/controllers/custom_patch_options_menu_action.go +++ b/pkg/gui/controllers/custom_patch_options_menu_action.go @@ -214,7 +214,7 @@ func (self *CustomPatchOptionsMenuAction) handlePullPatchIntoNewCommit() error { PreserveMessage: false, OnConfirm: func(summary string, description string) error { return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(gocui.Task) error { - _ = self.c.Helpers().Commits.PopCommitMessageContexts() + _ = self.c.Helpers().Commits.CloseCommitMessagePanel() self.c.LogAction(self.c.Tr.Actions.MovePatchIntoNewCommit) err := self.c.Git().Patch.PullPatchIntoNewCommit(self.c.Model().Commits, commitIndex, summary, description) if err := self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err); err != nil { diff --git a/pkg/gui/controllers/helpers/commits_helper.go b/pkg/gui/controllers/helpers/commits_helper.go index 216f55f8e..be3a36e8d 100644 --- a/pkg/gui/controllers/helpers/commits_helper.go +++ b/pkg/gui/controllers/helpers/commits_helper.go @@ -154,7 +154,7 @@ func (self *CommitsHelper) OpenCommitMessagePanel(opts *OpenCommitMessagePanelOp self.UpdateCommitPanelView(opts.InitialMessage) - return self.pushCommitMessageContexts() + return self.c.PushContext(self.c.Contexts().CommitMessage) } func (self *CommitsHelper) OnCommitSuccess() { @@ -190,28 +190,10 @@ func (self *CommitsHelper) CloseCommitMessagePanel() error { self.c.Contexts().CommitMessage.SetHistoryMessage("") - return self.PopCommitMessageContexts() -} + self.c.Views().CommitMessage.Visible = false + self.c.Views().CommitDescription.Visible = false -func (self *CommitsHelper) PopCommitMessageContexts() error { - return self.c.RemoveContexts(self.commitMessageContexts()) -} - -func (self *CommitsHelper) pushCommitMessageContexts() error { - for _, context := range self.commitMessageContexts() { - if err := self.c.PushContext(context); err != nil { - return err - } - } - - return nil -} - -func (self *CommitsHelper) commitMessageContexts() []types.Context { - return []types.Context{ - self.c.Contexts().CommitDescription, - self.c.Contexts().CommitMessage, - } + return self.c.PopContext() } func (self *CommitsHelper) OpenCommitMenu(suggestionFunc func(string) []*types.Suggestion) error { diff --git a/pkg/gui/controllers/helpers/confirmation_helper.go b/pkg/gui/controllers/helpers/confirmation_helper.go index 8f7c60b5a..c0fb5bafb 100644 --- a/pkg/gui/controllers/helpers/confirmation_helper.go +++ b/pkg/gui/controllers/helpers/confirmation_helper.go @@ -5,8 +5,6 @@ import ( "fmt" "strings" - "github.com/jesseduffield/gocui" - "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/theme" @@ -118,21 +116,23 @@ func wrapMessageToWidth(wrap bool, message string, width int) []string { return wrappedLines } -func (self *ConfirmationHelper) getPopupPanelDimensions(wrap bool, prompt string) (int, int, int, int) { - panelWidth := self.getPopupPanelWidth() - panelHeight := getMessageHeight(wrap, prompt, panelWidth) - return self.getPopupPanelDimensionsAux(panelWidth, panelHeight) +func (self *ConfirmationHelper) getPopupPanelDimensionsForContentHeight(panelWidth, contentHeight int, parentPopupContext types.Context) (int, int, int, int) { + return self.getPopupPanelDimensionsAux(panelWidth, contentHeight, parentPopupContext) } -func (self *ConfirmationHelper) getPopupPanelDimensionsForContentHeight(panelWidth, contentHeight int) (int, int, int, int) { - return self.getPopupPanelDimensionsAux(panelWidth, contentHeight) -} - -func (self *ConfirmationHelper) getPopupPanelDimensionsAux(panelWidth int, panelHeight int) (int, int, int, int) { +func (self *ConfirmationHelper) getPopupPanelDimensionsAux(panelWidth int, panelHeight int, parentPopupContext types.Context) (int, int, int, int) { width, height := self.c.GocuiGui().Size() if panelHeight > height*3/4 { panelHeight = height * 3 / 4 } + if parentPopupContext != nil { + // If there's already a popup on the screen, offset the new one from its + // parent so that it's clearly distinguished from the parent + x0, y0, _, _ := parentPopupContext.GetView().Dimensions() + x0 += 2 + y0 += 1 + return x0, y0, x0 + panelWidth, y0 + panelHeight + 1 + } return width/2 - panelWidth/2, height/2 - panelHeight/2 - panelHeight%2 - 1, width/2 + panelWidth/2, @@ -177,7 +177,6 @@ func (self *ConfirmationHelper) prepareConfirmationPanel( suggestionsView.Subtitle = "" } - self.ResizeConfirmationPanel() return nil } @@ -227,7 +226,6 @@ func (self *ConfirmationHelper) CreatePopupPanel(ctx goContext.Context, opts typ textArea := confirmationView.TextArea textArea.Clear() textArea.TypeString(opts.Prompt) - self.ResizeConfirmationPanel() confirmationView.RenderTextArea() } else { self.c.ResetViewOrigin(confirmationView) @@ -325,49 +323,23 @@ func (self *ConfirmationHelper) getSelectedSuggestionValue() string { return "" } -func (self *ConfirmationHelper) ResizeConfirmationPanel() { - suggestionsViewHeight := 0 - if self.c.Views().Suggestions.Visible { - suggestionsViewHeight = 11 - } - panelWidth := self.getPopupPanelWidth() - prompt := self.c.Views().Confirmation.Buffer() - wrap := true - if self.c.Views().Confirmation.Editable { - prompt = self.c.Views().Confirmation.TextArea.GetContent() - wrap = false - } - panelHeight := getMessageHeight(wrap, prompt, panelWidth) + suggestionsViewHeight - x0, y0, x1, y1 := self.getPopupPanelDimensionsAux(panelWidth, panelHeight) - confirmationViewBottom := y1 - suggestionsViewHeight - _, _ = self.c.GocuiGui().SetView(self.c.Views().Confirmation.Name(), x0, y0, x1, confirmationViewBottom, 0) +func (self *ConfirmationHelper) ResizeCurrentPopupPanels() { + var parentPopupContext types.Context + for _, c := range self.c.CurrentPopupContexts() { + switch c { + case self.c.Contexts().Menu: + self.resizeMenu(parentPopupContext) + case self.c.Contexts().Confirmation, self.c.Contexts().Suggestions: + self.resizeConfirmationPanel(parentPopupContext) + case self.c.Contexts().CommitMessage, self.c.Contexts().CommitDescription: + self.ResizeCommitMessagePanels(parentPopupContext) + } - suggestionsViewTop := confirmationViewBottom + 1 - _, _ = self.c.GocuiGui().SetView(self.c.Views().Suggestions.Name(), x0, suggestionsViewTop, x1, suggestionsViewTop+suggestionsViewHeight, 0) + parentPopupContext = c + } } -func (self *ConfirmationHelper) ResizeCurrentPopupPanel() error { - c := self.c.CurrentContext() - - switch c { - case self.c.Contexts().Menu: - self.resizeMenu() - case self.c.Contexts().Confirmation, self.c.Contexts().Suggestions: - self.resizeConfirmationPanel() - case self.c.Contexts().CommitMessage, self.c.Contexts().CommitDescription: - self.ResizeCommitMessagePanels() - } - - return nil -} - -func (self *ConfirmationHelper) ResizePopupPanel(v *gocui.View, content string) error { - x0, y0, x1, y1 := self.getPopupPanelDimensions(v.Wrap, content) - _, err := self.c.GocuiGui().SetView(v.Name(), x0, y0, x1, y1, 0) - return err -} - -func (self *ConfirmationHelper) resizeMenu() { +func (self *ConfirmationHelper) resizeMenu(parentPopupContext types.Context) { // we want the unfiltered length here so that if we're filtering we don't // resize the window itemCount := self.c.Contexts().Menu.UnfilteredLen() @@ -375,7 +347,7 @@ func (self *ConfirmationHelper) resizeMenu() { panelWidth := self.getPopupPanelWidth() contentWidth := panelWidth - 2 // minus 2 for the frame promptLinesCount := self.layoutMenuPrompt(contentWidth) - x0, y0, x1, y1 := self.getPopupPanelDimensionsForContentHeight(panelWidth, itemCount+offset+promptLinesCount) + x0, y0, x1, y1 := self.getPopupPanelDimensionsForContentHeight(panelWidth, itemCount+offset+promptLinesCount, parentPopupContext) menuBottom := y1 - offset _, _ = self.c.GocuiGui().SetView(self.c.Views().Menu.Name(), x0, y0, x1, menuBottom, 0) @@ -418,7 +390,7 @@ func (self *ConfirmationHelper) layoutMenuPrompt(contentWidth int) int { return len(promptLines) } -func (self *ConfirmationHelper) resizeConfirmationPanel() { +func (self *ConfirmationHelper) resizeConfirmationPanel(parentPopupContext types.Context) { suggestionsViewHeight := 0 if self.c.Views().Suggestions.Visible { suggestionsViewHeight = 11 @@ -431,7 +403,7 @@ func (self *ConfirmationHelper) resizeConfirmationPanel() { wrap = false } panelHeight := getMessageHeight(wrap, prompt, panelWidth) + suggestionsViewHeight - x0, y0, x1, y1 := self.getPopupPanelDimensionsAux(panelWidth, panelHeight) + x0, y0, x1, y1 := self.getPopupPanelDimensionsAux(panelWidth, panelHeight, parentPopupContext) confirmationViewBottom := y1 - suggestionsViewHeight _, _ = self.c.GocuiGui().SetView(self.c.Views().Confirmation.Name(), x0, y0, x1, confirmationViewBottom, 0) @@ -439,7 +411,7 @@ func (self *ConfirmationHelper) resizeConfirmationPanel() { _, _ = self.c.GocuiGui().SetView(self.c.Views().Suggestions.Name(), x0, suggestionsViewTop, x1, suggestionsViewTop+suggestionsViewHeight, 0) } -func (self *ConfirmationHelper) ResizeCommitMessagePanels() { +func (self *ConfirmationHelper) ResizeCommitMessagePanels(parentPopupContext types.Context) { panelWidth := self.getPopupPanelWidth() content := self.c.Views().CommitDescription.TextArea.GetContent() summaryViewHeight := 3 @@ -448,18 +420,18 @@ func (self *ConfirmationHelper) ResizeCommitMessagePanels() { if panelHeight < minHeight { panelHeight = minHeight } - x0, y0, x1, y1 := self.getPopupPanelDimensionsAux(panelWidth, panelHeight) + x0, y0, x1, y1 := self.getPopupPanelDimensionsAux(panelWidth, panelHeight, parentPopupContext) _, _ = self.c.GocuiGui().SetView(self.c.Views().CommitMessage.Name(), x0, y0, x1, y0+summaryViewHeight-1, 0) _, _ = self.c.GocuiGui().SetView(self.c.Views().CommitDescription.Name(), x0, y0+summaryViewHeight, x1, y1+summaryViewHeight, 0) } -func (self *ConfirmationHelper) IsPopupPanel(viewName string) bool { - return viewName == "commitMessage" || viewName == "confirmation" || viewName == "menu" +func (self *ConfirmationHelper) IsPopupPanel(context types.Context) bool { + return context.GetKind() == types.PERSISTENT_POPUP || context.GetKind() == types.TEMPORARY_POPUP } func (self *ConfirmationHelper) IsPopupPanelFocused() bool { - return self.IsPopupPanel(self.c.CurrentContext().GetViewName()) + return self.IsPopupPanel(self.c.CurrentContext()) } func (self *ConfirmationHelper) TooltipForMenuItem(menuItem *types.MenuItem) string { diff --git a/pkg/gui/gui_common.go b/pkg/gui/gui_common.go index 434f4b38b..8a537f2ca 100644 --- a/pkg/gui/gui_common.go +++ b/pkg/gui/gui_common.go @@ -73,6 +73,10 @@ func (self *guiCommon) CurrentSideContext() types.Context { return self.gui.State.ContextMgr.CurrentSide() } +func (self *guiCommon) CurrentPopupContexts() []types.Context { + return self.gui.State.ContextMgr.PopupContexts() +} + func (self *guiCommon) IsCurrentContext(c types.Context) bool { return self.gui.State.ContextMgr.IsCurrent(c) } diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go index 861bb0bd1..3bf6a7c35 100644 --- a/pkg/gui/layout.go +++ b/pkg/gui/layout.go @@ -173,9 +173,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { // if you run `lazygit --logs` // this will let you see these branches as prettified json // gui.c.Log.Info(utils.AsJson(gui.State.Model.Branches[0:4])) - if err := gui.helpers.Confirmation.ResizeCurrentPopupPanel(); err != nil { - return err - } + gui.helpers.Confirmation.ResizeCurrentPopupPanels() gui.renderContextOptionsMap() diff --git a/pkg/gui/types/common.go b/pkg/gui/types/common.go index 61c27de49..c6885d717 100644 --- a/pkg/gui/types/common.go +++ b/pkg/gui/types/common.go @@ -67,6 +67,7 @@ type IGuiCommon interface { CurrentContext() Context CurrentStaticContext() Context CurrentSideContext() Context + CurrentPopupContexts() []Context IsCurrentContext(Context) bool // TODO: replace the above context-based methods with just using Context() e.g. replace PushContext() with Context().Push() Context() IContextMgr diff --git a/vendor/github.com/jesseduffield/gocui/gui.go b/vendor/github.com/jesseduffield/gocui/gui.go index e2593b985..0c64e6925 100644 --- a/vendor/github.com/jesseduffield/gocui/gui.go +++ b/vendor/github.com/jesseduffield/gocui/gui.go @@ -307,14 +307,26 @@ func (g *Gui) SetView(name string, x0, y0, x1, y1 int, overlaps byte) (*View, er } if v, err := g.View(name); err == nil { - if v.x0 != x0 || v.x1 != x1 || v.y0 != y0 || v.y1 != y1 { - v.clearViewLines() - } + sizeChanged := v.x0 != x0 || v.x1 != x1 || v.y0 != y0 || v.y1 != y1 v.x0 = x0 v.y0 = y0 v.x1 = x1 v.y1 = y1 + + if sizeChanged { + v.clearViewLines() + + if v.Editable { + cursorX, cursorY := v.TextArea.GetCursorXY() + newViewCursorX, newOriginX := updatedCursorAndOrigin(0, v.InnerWidth(), cursorX) + newViewCursorY, newOriginY := updatedCursorAndOrigin(0, v.InnerHeight(), cursorY) + + _ = v.SetCursor(newViewCursorX, newViewCursorY) + _ = v.SetOrigin(newOriginX, newOriginY) + } + } + return v, nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index c7d601a93..6b34633e2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -172,7 +172,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem github.com/jesseduffield/go-git/v5/utils/merkletrie/index github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame github.com/jesseduffield/go-git/v5/utils/merkletrie/noder -# github.com/jesseduffield/gocui v0.3.1-0.20240623124136-ce5274be521d +# github.com/jesseduffield/gocui v0.3.1-0.20240628061234-aed9e133e65b ## explicit; go 1.12 github.com/jesseduffield/gocui # github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10