From 68e49efba2c568fcb5740f46a68b8fa53e4ce412 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sun, 8 Dec 2024 13:10:25 +0100 Subject: [PATCH 1/9] [gocui] Fix FocusPoint when Wrap is true --- vendor/github.com/jesseduffield/gocui/view.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go index 70cbd9735e4..598e85f8924 100644 --- a/vendor/github.com/jesseduffield/gocui/view.go +++ b/vendor/github.com/jesseduffield/gocui/view.go @@ -326,7 +326,11 @@ func (v *View) IsSearching() bool { } func (v *View) FocusPoint(cx int, cy int) { - lineCount := len(v.lines) + v.writeMutex.Lock() + defer v.writeMutex.Unlock() + + v.refreshViewLinesIfNeeded() + lineCount := len(v.viewLines) if cy < 0 || cy > lineCount { return } From 1b6bbe2378c668af4937193af1fe3f3d8de233cc Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Wed, 26 Mar 2025 13:08:45 +0100 Subject: [PATCH 2/9] [gocui] Add PreviousX/PreviousY to ViewMouseBindingOpts This is useful for detecting double-clicks. --- vendor/github.com/jesseduffield/gocui/gui.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/vendor/github.com/jesseduffield/gocui/gui.go b/vendor/github.com/jesseduffield/gocui/gui.go index c3dddd590e4..a62e70c3407 100644 --- a/vendor/github.com/jesseduffield/gocui/gui.go +++ b/vendor/github.com/jesseduffield/gocui/gui.go @@ -95,6 +95,12 @@ type ViewMouseBinding struct { type ViewMouseBindingOpts struct { X int // i.e. origin x + cursor x Y int // i.e. origin y + cursor y + + // the previous cursor right before the click; useful because by the time + // the event is dispatched to handlers, gocui has already set the cursor to + // the new position. This is useful for detecting double clicks. + PreviousX int + PreviousY int } type GuiMutexes struct { @@ -1363,6 +1369,8 @@ func (g *Gui) onKey(ev *GocuiEvent) error { newCx = lastCharForLine - v.ox } } + previousX := v.cx + v.ox + previousY := v.cy + v.oy if !IsMouseScrollKey(ev.Key) { v.SetCursor(newCx, newCy) if v.Editable { @@ -1385,7 +1393,7 @@ func (g *Gui) onKey(ev *GocuiEvent) error { } if IsMouseKey(ev.Key) { - opts := ViewMouseBindingOpts{X: newX, Y: newY} + opts := ViewMouseBindingOpts{X: newX, Y: newY, PreviousX: previousX, PreviousY: previousY} matched, err := g.execMouseKeybindings(v, ev, opts) if err != nil { return err From 2a7578574d411e86c7517e7b671f1fac5a1da311 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Tue, 1 Apr 2025 16:14:10 +0200 Subject: [PATCH 3/9] Add user config gui.showSelectionInFocusedMainView --- docs/Config.md | 3 ++ pkg/config/user_config.go | 39 ++++++++++--------- pkg/gui/context/base_context.go | 4 ++ pkg/gui/context/main_context.go | 2 +- pkg/gui/controllers/main_view_controller.go | 4 ++ .../controllers/view_selection_controller.go | 30 +++++++++++--- pkg/gui/gui.go | 5 +++ schema/config.json | 5 +++ 8 files changed, 68 insertions(+), 24 deletions(-) diff --git a/docs/Config.md b/docs/Config.md index b165239c0f0..392bcf9244d 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -116,6 +116,9 @@ gui: # paragraphs of markdown text. wrapLinesInStagingView: true + # If true, show a selection when the main view is focused. + showSelectionInFocusedMainView: false + # One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru' language: auto diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index f97bb33cec0..8eaea59ec9d 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -107,6 +107,8 @@ type GuiConfig struct { // makes it much easier to work with diffs that have long lines, e.g. // paragraphs of markdown text. WrapLinesInStagingView bool `yaml:"wrapLinesInStagingView"` + // If true, show a selection when the main view is focused. + ShowSelectionInFocusedMainView bool `yaml:"showSelectionInFocusedMainView"` // One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru' Language string `yaml:"language" jsonschema:"enum=auto,enum=en,enum=zh-TW,enum=zh-CN,enum=pl,enum=nl,enum=ja,enum=ko,enum=ru"` // Format used when displaying time e.g. commit time. @@ -730,24 +732,25 @@ type IconProperties struct { func GetDefaultConfig() *UserConfig { return &UserConfig{ Gui: GuiConfig{ - ScrollHeight: 2, - ScrollPastBottom: true, - ScrollOffMargin: 2, - ScrollOffBehavior: "margin", - TabWidth: 4, - MouseEvents: true, - SkipAmendWarning: false, - SkipDiscardChangeWarning: false, - SkipStashWarning: false, - SidePanelWidth: 0.3333, - ExpandFocusedSidePanel: false, - ExpandedSidePanelWeight: 2, - MainPanelSplitMode: "flexible", - EnlargedSideViewLocation: "left", - WrapLinesInStagingView: true, - Language: "auto", - TimeFormat: "02 Jan 06", - ShortTimeFormat: time.Kitchen, + ScrollHeight: 2, + ScrollPastBottom: true, + ScrollOffMargin: 2, + ScrollOffBehavior: "margin", + TabWidth: 4, + MouseEvents: true, + SkipAmendWarning: false, + SkipDiscardChangeWarning: false, + SkipStashWarning: false, + SidePanelWidth: 0.3333, + ExpandFocusedSidePanel: false, + ExpandedSidePanelWeight: 2, + MainPanelSplitMode: "flexible", + EnlargedSideViewLocation: "left", + WrapLinesInStagingView: true, + ShowSelectionInFocusedMainView: false, + Language: "auto", + TimeFormat: "02 Jan 06", + ShortTimeFormat: time.Kitchen, Theme: ThemeConfig{ ActiveBorderColor: []string{"green", "bold"}, SearchingActiveBorderColor: []string{"cyan", "bold"}, diff --git a/pkg/gui/context/base_context.go b/pkg/gui/context/base_context.go index b72374392d9..5c1fd05b044 100644 --- a/pkg/gui/context/base_context.go +++ b/pkg/gui/context/base_context.go @@ -228,3 +228,7 @@ func (self *BaseContext) Title() string { func (self *BaseContext) TotalContentHeight() int { return self.view.ViewLinesHeight() } + +func (self *BaseContext) SetHighlightOnFocus(value bool) { + self.highlightOnFocus = value +} diff --git a/pkg/gui/context/main_context.go b/pkg/gui/context/main_context.go index 66babac0362..a0189ef0e9a 100644 --- a/pkg/gui/context/main_context.go +++ b/pkg/gui/context/main_context.go @@ -26,7 +26,7 @@ func NewMainContext( WindowName: windowName, Key: key, Focusable: true, - HighlightOnFocus: false, + HighlightOnFocus: c.UserConfig().Gui.ShowSelectionInFocusedMainView, })), SearchTrait: NewSearchTrait(c), } diff --git a/pkg/gui/controllers/main_view_controller.go b/pkg/gui/controllers/main_view_controller.go index 5dfdb3233ac..8327ca08266 100644 --- a/pkg/gui/controllers/main_view_controller.go +++ b/pkg/gui/controllers/main_view_controller.go @@ -88,6 +88,10 @@ func (self *MainViewController) escape() error { } func (self *MainViewController) onClickInAlreadyFocusedView(opts gocui.ViewMouseBindingOpts) error { + if self.context.GetView().Highlight && opts.Y != opts.PreviousY { + return nil + } + sidePanelContext := self.c.Context().NextInStack(self.context) if sidePanelContext != nil && sidePanelContext.GetOnClickFocusedMainView() != nil { return sidePanelContext.GetOnClickFocusedMainView()(self.context.GetViewName(), opts.Y) diff --git a/pkg/gui/controllers/view_selection_controller.go b/pkg/gui/controllers/view_selection_controller.go index 638c46ba608..2f7f3b17283 100644 --- a/pkg/gui/controllers/view_selection_controller.go +++ b/pkg/gui/controllers/view_selection_controller.go @@ -3,6 +3,7 @@ package controllers import ( "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/samber/lo" ) type ViewSelectionControllerFactory struct { @@ -61,10 +62,21 @@ func (self *ViewSelectionController) handleLineChange(delta int) { } v := self.Context().GetView() - if delta < 0 { - v.ScrollUp(-delta) + if self.context.GetView().Highlight { + lineIdxBefore := v.CursorY() + v.OriginY() + lineIdxAfter := lo.Clamp(lineIdxBefore+delta, 0, v.ViewLinesHeight()-1) + if delta == -1 { + checkScrollUp(self.Context().GetViewTrait(), self.c.UserConfig(), lineIdxBefore, lineIdxAfter) + } else if delta == 1 { + checkScrollDown(self.Context().GetViewTrait(), self.c.UserConfig(), lineIdxBefore, lineIdxAfter) + } + v.FocusPoint(0, lineIdxAfter) } else { - v.ScrollDown(delta) + if delta < 0 { + v.ScrollUp(-delta) + } else { + v.ScrollDown(delta) + } } } @@ -90,7 +102,11 @@ func (self *ViewSelectionController) handleNextPage() error { func (self *ViewSelectionController) handleGotoTop() error { v := self.Context().GetView() - self.handleLineChange(-v.ViewLinesHeight()) + if self.context.GetView().Highlight { + v.FocusPoint(0, 0) + } else { + self.handleLineChange(-v.ViewLinesHeight()) + } return nil } @@ -99,7 +115,11 @@ func (self *ViewSelectionController) handleGotoBottom() error { manager.ReadToEnd(func() { self.c.OnUIThread(func() error { v := self.Context().GetView() - self.handleLineChange(v.ViewLinesHeight()) + if self.context.GetView().Highlight { + v.FocusPoint(0, v.ViewLinesHeight()-1) + } else { + self.handleLineChange(v.ViewLinesHeight()) + } return nil }) }) diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 49643791ee3..5382a2dfb8f 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -446,6 +446,11 @@ func (gui *Gui) onUserConfigLoaded() error { gui.g.Mouse = userConfig.Gui.MouseEvents + if gui.State != nil { + gui.Contexts().Normal.SetHighlightOnFocus(userConfig.Gui.ShowSelectionInFocusedMainView) + gui.Contexts().NormalSecondary.SetHighlightOnFocus(userConfig.Gui.ShowSelectionInFocusedMainView) + } + // originally we could only hide the command log permanently via the config // but now we do it via state. So we need to still support the config for the // sake of backwards compatibility. We're making use of short circuiting here diff --git a/schema/config.json b/schema/config.json index 5b33dfd0117..1098f265d9b 100644 --- a/schema/config.json +++ b/schema/config.json @@ -530,6 +530,11 @@ "description": "If true, wrap lines in the staging view to the width of the view. This\nmakes it much easier to work with diffs that have long lines, e.g.\nparagraphs of markdown text.", "default": true }, + "showSelectionInFocusedMainView": { + "type": "boolean", + "description": "If true, show a selection when the main view is focused.", + "default": false + }, "language": { "type": "string", "enum": [ From e0fdec1c1dc63aa012f66567ffa8a339dc37b7f7 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Tue, 1 Apr 2025 23:03:55 +0200 Subject: [PATCH 4/9] Press enter in focused main view when user config is on --- pkg/gui/controllers/main_view_controller.go | 21 +++++++++++++++++++++ pkg/i18n/english.go | 2 ++ 2 files changed, 23 insertions(+) diff --git a/pkg/gui/controllers/main_view_controller.go b/pkg/gui/controllers/main_view_controller.go index 8327ca08266..48d9a5e1a34 100644 --- a/pkg/gui/controllers/main_view_controller.go +++ b/pkg/gui/controllers/main_view_controller.go @@ -30,6 +30,13 @@ func NewMainViewController( } func (self *MainViewController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding { + var goIntoDescription string + // We only want to show the "enter" menu item if the user config is true; + // leaving the description empty causes it to be hidden + if self.c.UserConfig().Gui.ShowSelectionInFocusedMainView { + goIntoDescription = self.c.Tr.EnterStaging + } + return []*types.Binding{ { Key: opts.GetKey(opts.Config.Universal.TogglePanel), @@ -43,6 +50,11 @@ func (self *MainViewController) GetKeybindings(opts types.KeybindingsOpts) []*ty Handler: self.escape, Description: self.c.Tr.ExitFocusedMainView, }, + { + Key: opts.GetKey(opts.Config.Universal.GoInto), + Handler: self.enter, + Description: goIntoDescription, + }, { // overriding this because we want to read all of the task's output before we start searching Key: opts.GetKey(opts.Config.Universal.StartSearch), @@ -87,6 +99,15 @@ func (self *MainViewController) escape() error { return nil } +func (self *MainViewController) enter() error { + parentCtx := self.context.GetParentContext() + if parentCtx.GetOnClickFocusedMainView() != nil { + return parentCtx.GetOnClickFocusedMainView()( + self.context.GetViewName(), self.context.GetView().SelectedLineIdx()) + } + return nil +} + func (self *MainViewController) onClickInAlreadyFocusedView(opts gocui.ViewMouseBindingOpts) error { if self.context.GetView().Highlight && opts.Y != opts.PreviousY { return nil diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 36a119c3657..18e98c715d7 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -521,6 +521,7 @@ type TranslationSet struct { EmptyPatchError string EnterCommitFile string EnterCommitFileTooltip string + EnterStaging string ExitCustomPatchBuilder string ExitFocusedMainView string EnterUpstream string @@ -1613,6 +1614,7 @@ func EnglishTranslationSet() *TranslationSet { EmptyPatchError: "Patch is still empty. Add some files or lines to your patch first.", EnterCommitFile: "Enter file / Toggle directory collapsed", EnterCommitFileTooltip: "If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory.", + EnterStaging: "Enter staging/patch building", ExitCustomPatchBuilder: `Exit custom patch builder`, ExitFocusedMainView: "Exit back to side panel", EnterUpstream: `Enter upstream as ' '`, From 3a578d1e94a798068ac35cd0eb22cda558a228f8 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Tue, 25 Mar 2025 15:01:16 +0100 Subject: [PATCH 5/9] Select line that is in the middle of the screen --- pkg/gui/controllers/main_view_controller.go | 8 ++++++++ .../switch_to_focused_main_view_controller.go | 19 ++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/pkg/gui/controllers/main_view_controller.go b/pkg/gui/controllers/main_view_controller.go index 48d9a5e1a34..4720c9c4d20 100644 --- a/pkg/gui/controllers/main_view_controller.go +++ b/pkg/gui/controllers/main_view_controller.go @@ -86,6 +86,14 @@ func (self *MainViewController) Context() types.Context { return self.context } +func (self *MainViewController) GetOnFocus() func(types.OnFocusOpts) { + return func(opts types.OnFocusOpts) { + if opts.ClickedWindowName != "" { + self.context.GetView().FocusPoint(0, opts.ClickedViewLineIdx) + } + } +} + func (self *MainViewController) togglePanel() error { if self.otherContext.GetView().Visible { self.c.Context().Push(self.otherContext, types.OnFocusOpts{}) diff --git a/pkg/gui/controllers/switch_to_focused_main_view_controller.go b/pkg/gui/controllers/switch_to_focused_main_view_controller.go index 1973e3d6338..a26da49b521 100644 --- a/pkg/gui/controllers/switch_to_focused_main_view_controller.go +++ b/pkg/gui/controllers/switch_to_focused_main_view_controller.go @@ -3,6 +3,7 @@ package controllers import ( "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/samber/lo" ) // This controller is for all contexts that can focus their main view. @@ -60,21 +61,29 @@ func (self *SwitchToFocusedMainViewController) Context() types.Context { } func (self *SwitchToFocusedMainViewController) onClickMain(opts gocui.ViewMouseBindingOpts) error { - return self.focusMainView(self.c.Contexts().Normal) + return self.focusMainView(self.c.Contexts().Normal, opts.Y) } func (self *SwitchToFocusedMainViewController) onClickSecondary(opts gocui.ViewMouseBindingOpts) error { - return self.focusMainView(self.c.Contexts().NormalSecondary) + return self.focusMainView(self.c.Contexts().NormalSecondary, opts.Y) } func (self *SwitchToFocusedMainViewController) handleFocusMainView() error { - return self.focusMainView(self.c.Contexts().Normal) + return self.focusMainView(self.c.Contexts().Normal, -1) } -func (self *SwitchToFocusedMainViewController) focusMainView(mainViewContext types.Context) error { +func (self *SwitchToFocusedMainViewController) focusMainView(mainViewContext types.Context, clickedViewLineIdx int) error { if context, ok := mainViewContext.(types.ISearchableContext); ok { context.ClearSearchString() } - self.c.Context().Push(mainViewContext, types.OnFocusOpts{}) + onFocusOpts := types.OnFocusOpts{ClickedWindowName: mainViewContext.GetWindowName()} + if clickedViewLineIdx >= 0 { + onFocusOpts.ClickedViewLineIdx = clickedViewLineIdx + } else { + mainView := mainViewContext.GetView() + lineIdx := mainView.OriginY() + mainView.Height()/2 + onFocusOpts.ClickedViewLineIdx = lo.Clamp(lineIdx, 0, mainView.LinesHeight()-1) + } + self.c.Context().Push(mainViewContext, onFocusOpts) return nil } From 305238aa17dd641bac2862b01429d92e2ef463cf Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Mon, 16 Sep 2024 20:38:22 +0200 Subject: [PATCH 6/9] Press enter in main view of files/commitFiles to enter staging/patch-building This was already possible, but only when a file was selected, and it woudln't always land on the right line when a pager was used. Now it's also possible to do this for directories, and it jumps to the right line. At the moment this is a hack that relies on delta's hyperlinks, so it only works on lines that have hyperlinks (added and context). The implementation is very hacky for other reasons too (e.g. the addition of the weirdly named ClickedViewRealLineIdx to OnFocusOpts). --- pkg/commands/patch/patch.go | 32 +++++++++++++++++ pkg/gui/controllers.go | 4 +-- .../controllers/commits_files_controller.go | 32 ++++++++++++++--- pkg/gui/controllers/files_controller.go | 33 ++++++++++++++--- .../helpers/patch_building_helper.go | 4 ++- pkg/gui/controllers/helpers/staging_helper.go | 35 ++++++++++++++++--- .../controllers/patch_explorer_controller.go | 10 ++++-- pkg/gui/patch_exploring/state.go | 6 +++- pkg/gui/types/context.go | 3 ++ vendor/github.com/jesseduffield/gocui/view.go | 14 ++++++++ 10 files changed, 154 insertions(+), 19 deletions(-) diff --git a/pkg/commands/patch/patch.go b/pkg/commands/patch/patch.go index 5e4f9a84665..68c8e609b53 100644 --- a/pkg/commands/patch/patch.go +++ b/pkg/commands/patch/patch.go @@ -104,6 +104,38 @@ func (self *Patch) LineNumberOfLine(idx int) int { return hunk.newStart + offset } +// Takes a line number in the new file and returns the line index in the patch. +// This is the opposite of LineNumberOfLine. +// If the line number is not contained in any of the hunks, it returns the +// closest position. +func (self *Patch) PatchLineForLineNumber(lineNumber int) int { + if len(self.hunks) == 0 { + return len(self.header) + } + + for hunkIdx, hunk := range self.hunks { + if lineNumber <= hunk.newStart { + return self.HunkStartIdx(hunkIdx) + } + + if lineNumber < hunk.newStart+hunk.newLength() { + lines := hunk.bodyLines + offset := lineNumber - hunk.newStart + for i, line := range lines { + if offset == 0 { + return self.HunkStartIdx(hunkIdx) + i + 1 + } + + if line.Kind == ADDITION || line.Kind == CONTEXT { + offset-- + } + } + } + } + + return self.LineCount() - 1 +} + // Returns hunk index containing the line at the given patch line index func (self *Patch) HunkContainingLine(idx int) int { for hunkIdx, hunk := range self.hunks { diff --git a/pkg/gui/controllers.go b/pkg/gui/controllers.go index abbb621551a..560e570ebf8 100644 --- a/pkg/gui/controllers.go +++ b/pkg/gui/controllers.go @@ -54,8 +54,9 @@ func (gui *Gui) resetHelpersAndControllers() { gpgHelper := helpers.NewGpgHelper(helperCommon) viewHelper := helpers.NewViewHelper(helperCommon, gui.State.Contexts) + windowHelper := helpers.NewWindowHelper(helperCommon, viewHelper) patchBuildingHelper := helpers.NewPatchBuildingHelper(helperCommon) - stagingHelper := helpers.NewStagingHelper(helperCommon) + stagingHelper := helpers.NewStagingHelper(helperCommon, windowHelper) mergeConflictsHelper := helpers.NewMergeConflictsHelper(helperCommon) searchHelper := helpers.NewSearchHelper(helperCommon) @@ -75,7 +76,6 @@ func (gui *Gui) resetHelpersAndControllers() { rebaseHelper, ) bisectHelper := helpers.NewBisectHelper(helperCommon) - windowHelper := helpers.NewWindowHelper(helperCommon, viewHelper) modeHelper := helpers.NewModeHelper( helperCommon, diffHelper, diff --git a/pkg/gui/controllers/commits_files_controller.go b/pkg/gui/controllers/commits_files_controller.go index 8beeb6ff268..3e4dd52c425 100644 --- a/pkg/gui/controllers/commits_files_controller.go +++ b/pkg/gui/controllers/commits_files_controller.go @@ -470,7 +470,7 @@ func (self *CommitFilesController) currentFromToReverseForPatchBuilding() (strin } func (self *CommitFilesController) enter(node *filetree.CommitFileNode) error { - return self.enterCommitFile(node, types.OnFocusOpts{ClickedWindowName: "", ClickedViewLineIdx: -1}) + return self.enterCommitFile(node, types.OnFocusOpts{ClickedWindowName: "", ClickedViewLineIdx: -1, ClickedViewRealLineIdx: -1}) } func (self *CommitFilesController) enterCommitFile(node *filetree.CommitFileNode, opts types.OnFocusOpts) error { @@ -545,11 +545,35 @@ func (self *CommitFilesController) expandAll() error { func (self *CommitFilesController) GetOnClickFocusedMainView() func(mainViewName string, clickedLineIdx int) error { return func(mainViewName string, clickedLineIdx int) error { + clickedFile, line, ok := self.c.Helpers().Staging.GetFileAndLineForClickedDiffLine(mainViewName, clickedLineIdx) + if !ok { + line = -1 + } + node := self.getSelectedItem() - if node != nil && node.File != nil { - return self.enterCommitFile(node, types.OnFocusOpts{ClickedWindowName: mainViewName, ClickedViewLineIdx: clickedLineIdx}) + if node == nil { + return nil } - return nil + + if !node.IsFile() && ok { + relativePath, err := filepath.Rel(self.c.Git().RepoPaths.RepoPath(), clickedFile) + if err != nil { + return err + } + relativePath = "./" + relativePath + self.context().CommitFileTreeViewModel.ExpandToPath(relativePath) + self.c.PostRefreshUpdate(self.context()) + + idx, ok := self.context().CommitFileTreeViewModel.GetIndexForPath(relativePath) + if ok { + self.context().SetSelectedLineIdx(idx) + self.context().GetViewTrait().FocusPoint( + self.context().ModelIndexToViewIndex(idx)) + node = self.context().GetSelected() + } + } + + return self.enterCommitFile(node, types.OnFocusOpts{ClickedWindowName: "main", ClickedViewLineIdx: line, ClickedViewRealLineIdx: line}) } } diff --git a/pkg/gui/controllers/files_controller.go b/pkg/gui/controllers/files_controller.go index d10d4726a1d..4318f0152ad 100644 --- a/pkg/gui/controllers/files_controller.go +++ b/pkg/gui/controllers/files_controller.go @@ -325,11 +325,34 @@ func (self *FilesController) GetOnClick() func() error { func (self *FilesController) GetOnClickFocusedMainView() func(mainViewName string, clickedLineIdx int) error { return func(mainViewName string, clickedLineIdx int) error { - node := self.getSelectedItem() - if node != nil && node.File != nil { - return self.EnterFile(types.OnFocusOpts{ClickedWindowName: mainViewName, ClickedViewLineIdx: clickedLineIdx}) + clickedFile, line, ok := self.c.Helpers().Staging.GetFileAndLineForClickedDiffLine(mainViewName, clickedLineIdx) + if !ok { + line = -1 } - return nil + + node := self.context().GetSelected() + if node == nil { + return nil + } + + if !node.IsFile() && ok { + relativePath, err := filepath.Rel(self.c.Git().RepoPaths.RepoPath(), clickedFile) + if err != nil { + return err + } + relativePath = "./" + relativePath + self.context().FileTreeViewModel.ExpandToPath(relativePath) + self.c.PostRefreshUpdate(self.context()) + + idx, ok := self.context().FileTreeViewModel.GetIndexForPath(relativePath) + if ok { + self.context().SetSelectedLineIdx(idx) + self.context().GetViewTrait().FocusPoint( + self.context().ModelIndexToViewIndex(idx)) + } + } + + return self.EnterFile(types.OnFocusOpts{ClickedWindowName: mainViewName, ClickedViewLineIdx: line, ClickedViewRealLineIdx: line}) } } @@ -511,7 +534,7 @@ func (self *FilesController) getSelectedFile() *models.File { } func (self *FilesController) enter() error { - return self.EnterFile(types.OnFocusOpts{ClickedWindowName: "", ClickedViewLineIdx: -1}) + return self.EnterFile(types.OnFocusOpts{ClickedWindowName: "", ClickedViewLineIdx: -1, ClickedViewRealLineIdx: -1}) } func (self *FilesController) collapseAll() error { diff --git a/pkg/gui/controllers/helpers/patch_building_helper.go b/pkg/gui/controllers/helpers/patch_building_helper.go index 73d0fb608b6..931c3347fa4 100644 --- a/pkg/gui/controllers/helpers/patch_building_helper.go +++ b/pkg/gui/controllers/helpers/patch_building_helper.go @@ -53,8 +53,10 @@ func (self *PatchBuildingHelper) Reset() error { func (self *PatchBuildingHelper) RefreshPatchBuildingPanel(opts types.OnFocusOpts) { selectedLineIdx := -1 + selectedRealLineIdx := -1 if opts.ClickedWindowName == "main" { selectedLineIdx = opts.ClickedViewLineIdx + selectedRealLineIdx = opts.ClickedViewRealLineIdx } if !self.c.Git().Patch.PatchBuilder.Active() { @@ -86,7 +88,7 @@ func (self *PatchBuildingHelper) RefreshPatchBuildingPanel(opts types.OnFocusOpt oldState := context.GetState() - state := patch_exploring.NewState(diff, selectedLineIdx, context.GetView(), oldState) + state := patch_exploring.NewState(diff, selectedLineIdx, selectedRealLineIdx, context.GetView(), oldState) context.SetState(state) if state == nil { self.Escape() diff --git a/pkg/gui/controllers/helpers/staging_helper.go b/pkg/gui/controllers/helpers/staging_helper.go index 3d976254171..8ab4ce418e8 100644 --- a/pkg/gui/controllers/helpers/staging_helper.go +++ b/pkg/gui/controllers/helpers/staging_helper.go @@ -1,20 +1,26 @@ package helpers import ( + "regexp" + "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/patch_exploring" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/jesseduffield/lazygit/pkg/utils" ) type StagingHelper struct { - c *HelperCommon + c *HelperCommon + windowHelper *WindowHelper } func NewStagingHelper( c *HelperCommon, + windowHelper *WindowHelper, ) *StagingHelper { return &StagingHelper{ - c: c, + c: c, + windowHelper: windowHelper, } } @@ -30,12 +36,16 @@ func (self *StagingHelper) RefreshStagingPanel(focusOpts types.OnFocusOpts) { } mainSelectedLineIdx := -1 + mainSelectedRealLineIdx := -1 secondarySelectedLineIdx := -1 + secondarySelectedRealLineIdx := -1 if focusOpts.ClickedViewLineIdx > 0 { if secondaryFocused { secondarySelectedLineIdx = focusOpts.ClickedViewLineIdx + secondarySelectedRealLineIdx = focusOpts.ClickedViewRealLineIdx } else { mainSelectedLineIdx = focusOpts.ClickedViewLineIdx + mainSelectedRealLineIdx = focusOpts.ClickedViewRealLineIdx } } @@ -63,11 +73,11 @@ func (self *StagingHelper) RefreshStagingPanel(focusOpts types.OnFocusOpts) { secondaryContext.GetMutex().Lock() mainContext.SetState( - patch_exploring.NewState(mainDiff, mainSelectedLineIdx, mainContext.GetView(), mainContext.GetState()), + patch_exploring.NewState(mainDiff, mainSelectedLineIdx, mainSelectedRealLineIdx, mainContext.GetView(), mainContext.GetState()), ) secondaryContext.SetState( - patch_exploring.NewState(secondaryDiff, secondarySelectedLineIdx, secondaryContext.GetView(), secondaryContext.GetState()), + patch_exploring.NewState(secondaryDiff, secondarySelectedLineIdx, secondarySelectedRealLineIdx, secondaryContext.GetView(), secondaryContext.GetState()), ) mainState := mainContext.GetState() @@ -124,3 +134,20 @@ func (self *StagingHelper) secondaryStagingFocused() bool { func (self *StagingHelper) mainStagingFocused() bool { return self.c.Context().CurrentStatic().GetKey() == self.c.Contexts().Staging.GetKey() } + +func (self *StagingHelper) GetFileAndLineForClickedDiffLine(windowName string, lineIdx int) (string, int, bool) { + v, _ := self.c.GocuiGui().View(self.windowHelper.GetViewNameForWindow(windowName)) + hyperlink, ok := v.HyperLinkInLine(lineIdx, "lazygit-edit:") + if !ok { + return "", 0, false + } + + re := regexp.MustCompile(`^lazygit-edit://(.+?):(\d+)$`) + matches := re.FindStringSubmatch(hyperlink) + if matches == nil { + return "", 0, false + } + filepath := matches[1] + lineNumber := utils.MustConvertToInt(matches[2]) + return filepath, lineNumber, true +} diff --git a/pkg/gui/controllers/patch_explorer_controller.go b/pkg/gui/controllers/patch_explorer_controller.go index 5b832c80d34..cd225b10a5e 100644 --- a/pkg/gui/controllers/patch_explorer_controller.go +++ b/pkg/gui/controllers/patch_explorer_controller.go @@ -163,9 +163,15 @@ func (self *PatchExplorerController) GetMouseKeybindings(opts types.KeybindingsO return self.withRenderAndFocus(self.HandleMouseDown)() } + _, line, ok := self.c.Helpers().Staging.GetFileAndLineForClickedDiffLine(self.context.GetWindowName(), opts.Y) + if !ok { + line = -1 + } + self.c.Context().Push(self.context, types.OnFocusOpts{ - ClickedWindowName: self.context.GetWindowName(), - ClickedViewLineIdx: opts.Y, + ClickedWindowName: self.context.GetWindowName(), + ClickedViewLineIdx: opts.Y, + ClickedViewRealLineIdx: line, }) return nil diff --git a/pkg/gui/patch_exploring/state.go b/pkg/gui/patch_exploring/state.go index 73ce0a756b6..7520a0c5a65 100644 --- a/pkg/gui/patch_exploring/state.go +++ b/pkg/gui/patch_exploring/state.go @@ -39,7 +39,7 @@ const ( HUNK ) -func NewState(diff string, selectedLineIdx int, view *gocui.View, oldState *State) *State { +func NewState(diff string, selectedLineIdx int, selectedRealLineIdx int, view *gocui.View, oldState *State) *State { if oldState != nil && diff == oldState.diff && selectedLineIdx == -1 { // if we're here then we can return the old state. If selectedLineIdx was not -1 // then that would mean we were trying to click and potentially drag a range, which @@ -55,6 +55,10 @@ func NewState(diff string, selectedLineIdx int, view *gocui.View, oldState *Stat viewLineIndices, patchLineIndices := wrapPatchLines(diff, view) + if selectedRealLineIdx != -1 { + selectedLineIdx = patch.PatchLineForLineNumber(selectedRealLineIdx) + } + rangeStartLineIdx := 0 if oldState != nil { rangeStartLineIdx = oldState.rangeStartLineIdx diff --git a/pkg/gui/types/context.go b/pkg/gui/types/context.go index 1c9759486d2..7473e869312 100644 --- a/pkg/gui/types/context.go +++ b/pkg/gui/types/context.go @@ -222,6 +222,9 @@ type IViewTrait interface { type OnFocusOpts struct { ClickedWindowName string ClickedViewLineIdx int + + // If not -1, takes precedence over ClickedViewLineIdx. + ClickedViewRealLineIdx int } type OnFocusLostOpts struct { diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go index 598e85f8924..e2e53529afc 100644 --- a/vendor/github.com/jesseduffield/gocui/view.go +++ b/vendor/github.com/jesseduffield/gocui/view.go @@ -1460,6 +1460,20 @@ func (v *View) Word(x, y int) (string, bool) { return str[nl:nr], true } +func (v *View) HyperLinkInLine(y int, urlScheme string) (string, bool) { + if y < 0 || y >= len(v.viewLines) { + return "", false + } + + for _, c := range v.lines[v.viewLines[y].linesY] { + if strings.HasPrefix(c.hyperlink, urlScheme) { + return c.hyperlink, true + } + } + + return "", false +} + // indexFunc allows to split lines by words taking into account spaces // and 0. func indexFunc(r rune) bool { From 12edbc04f6acd334d02d9eefc0e75245f2161032 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Fri, 11 Oct 2024 18:09:17 +0200 Subject: [PATCH 7/9] Extract some functions from CommitFilesController to a new CommitFilesHelper --- pkg/gui/controllers.go | 1 + .../controllers/commits_files_controller.go | 72 +-------------- .../helpers/commit_files_helper.go | 87 +++++++++++++++++++ pkg/gui/controllers/helpers/helpers.go | 2 + 4 files changed, 94 insertions(+), 68 deletions(-) create mode 100644 pkg/gui/controllers/helpers/commit_files_helper.go diff --git a/pkg/gui/controllers.go b/pkg/gui/controllers.go index 560e570ebf8..78657c69d6b 100644 --- a/pkg/gui/controllers.go +++ b/pkg/gui/controllers.go @@ -115,6 +115,7 @@ func (gui *Gui) resetHelpersAndControllers() { AmendHelper: helpers.NewAmendHelper(helperCommon, gpgHelper), FixupHelper: helpers.NewFixupHelper(helperCommon), Commits: commitsHelper, + CommitFiles: helpers.NewCommitFilesHelper(helperCommon), Snake: helpers.NewSnakeHelper(helperCommon), Diff: diffHelper, Repos: reposHelper, diff --git a/pkg/gui/controllers/commits_files_controller.go b/pkg/gui/controllers/commits_files_controller.go index 3e4dd52c425..b7f5f72c5e6 100644 --- a/pkg/gui/controllers/commits_files_controller.go +++ b/pkg/gui/controllers/commits_files_controller.go @@ -390,7 +390,7 @@ func (self *CommitFilesController) toggleForPatch(selectedNodes []*filetree.Comm toggle := func() error { return self.c.WithWaitingStatus(self.c.Tr.UpdatingPatch, func(gocui.Task) error { if !self.c.Git().Patch.PatchBuilder.Active() { - if err := self.startPatchBuilder(); err != nil { + if err := self.c.Helpers().CommitFiles.StartPatchBuilder(); err != nil { return err } } @@ -429,7 +429,7 @@ func (self *CommitFilesController) toggleForPatch(selectedNodes []*filetree.Comm }) } - from, to, reverse := self.currentFromToReverseForPatchBuilding() + from, to, reverse := self.c.Helpers().CommitFiles.CurrentFromToReverseForPatchBuilding() if self.c.Git().Patch.PatchBuilder.Active() && self.c.Git().Patch.PatchBuilder.NewPatchRequired(from, to, reverse) { self.c.Confirm(types.ConfirmOpts{ Title: self.c.Tr.DiscardPatch, @@ -451,72 +451,8 @@ func (self *CommitFilesController) toggleAllForPatch(_ *filetree.CommitFileNode) return self.toggleForPatch([]*filetree.CommitFileNode{root}) } -func (self *CommitFilesController) startPatchBuilder() error { - commitFilesContext := self.context() - - canRebase := commitFilesContext.GetCanRebase() - from, to, reverse := self.currentFromToReverseForPatchBuilding() - - self.c.Git().Patch.PatchBuilder.Start(from, to, reverse, canRebase) - return nil -} - -func (self *CommitFilesController) currentFromToReverseForPatchBuilding() (string, string, bool) { - commitFilesContext := self.context() - - from, to := commitFilesContext.GetFromAndToForDiff() - from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from) - return from, to, reverse -} - func (self *CommitFilesController) enter(node *filetree.CommitFileNode) error { - return self.enterCommitFile(node, types.OnFocusOpts{ClickedWindowName: "", ClickedViewLineIdx: -1, ClickedViewRealLineIdx: -1}) -} - -func (self *CommitFilesController) enterCommitFile(node *filetree.CommitFileNode, opts types.OnFocusOpts) error { - if node.File == nil { - return self.handleToggleCommitFileDirCollapsed(node) - } - - if self.c.AppState.DiffContextSize == 0 { - return fmt.Errorf(self.c.Tr.Actions.NotEnoughContextToStage, - keybindings.Label(self.c.UserConfig().Keybinding.Universal.IncreaseContextInDiffView)) - } - - enterTheFile := func() error { - if !self.c.Git().Patch.PatchBuilder.Active() { - if err := self.startPatchBuilder(); err != nil { - return err - } - } - - self.c.Context().Push(self.c.Contexts().CustomPatchBuilder, opts) - return nil - } - - from, to, reverse := self.currentFromToReverseForPatchBuilding() - if self.c.Git().Patch.PatchBuilder.Active() && self.c.Git().Patch.PatchBuilder.NewPatchRequired(from, to, reverse) { - self.c.Confirm(types.ConfirmOpts{ - Title: self.c.Tr.DiscardPatch, - Prompt: self.c.Tr.DiscardPatchConfirm, - HandleConfirm: func() error { - self.c.Git().Patch.PatchBuilder.Reset() - return enterTheFile() - }, - }) - - return nil - } - - return enterTheFile() -} - -func (self *CommitFilesController) handleToggleCommitFileDirCollapsed(node *filetree.CommitFileNode) error { - self.context().CommitFileTreeViewModel.ToggleCollapsed(node.GetInternalPath()) - - self.c.PostRefreshUpdate(self.context()) - - return nil + return self.c.Helpers().CommitFiles.EnterCommitFile(node, types.OnFocusOpts{ClickedWindowName: "", ClickedViewLineIdx: -1, ClickedViewRealLineIdx: -1}) } // NOTE: this is very similar to handleToggleFileTreeView, could be DRY'd with generics @@ -573,7 +509,7 @@ func (self *CommitFilesController) GetOnClickFocusedMainView() func(mainViewName } } - return self.enterCommitFile(node, types.OnFocusOpts{ClickedWindowName: "main", ClickedViewLineIdx: line, ClickedViewRealLineIdx: line}) + return self.c.Helpers().CommitFiles.EnterCommitFile(node, types.OnFocusOpts{ClickedWindowName: "main", ClickedViewLineIdx: line, ClickedViewRealLineIdx: line}) } } diff --git a/pkg/gui/controllers/helpers/commit_files_helper.go b/pkg/gui/controllers/helpers/commit_files_helper.go new file mode 100644 index 00000000000..03cc494f16d --- /dev/null +++ b/pkg/gui/controllers/helpers/commit_files_helper.go @@ -0,0 +1,87 @@ +package helpers + +import ( + "fmt" + + "github.com/jesseduffield/lazygit/pkg/gui/context" + "github.com/jesseduffield/lazygit/pkg/gui/filetree" + "github.com/jesseduffield/lazygit/pkg/gui/keybindings" + "github.com/jesseduffield/lazygit/pkg/gui/types" +) + +type CommitFilesHelper struct { + c *HelperCommon +} + +func NewCommitFilesHelper(c *HelperCommon) *CommitFilesHelper { + return &CommitFilesHelper{ + c: c, + } +} + +func (self *CommitFilesHelper) EnterCommitFile(node *filetree.CommitFileNode, opts types.OnFocusOpts) error { + if node.File == nil { + self.handleToggleCommitFileDirCollapsed(node) + return nil + } + + if self.c.AppState.DiffContextSize == 0 { + return fmt.Errorf(self.c.Tr.Actions.NotEnoughContextToStage, + keybindings.Label(self.c.UserConfig().Keybinding.Universal.IncreaseContextInDiffView)) + } + + enterTheFile := func() error { + if !self.c.Git().Patch.PatchBuilder.Active() { + if err := self.StartPatchBuilder(); err != nil { + return err + } + } + + self.c.Context().Push(self.c.Contexts().CustomPatchBuilder, opts) + return nil + } + + from, to, reverse := self.CurrentFromToReverseForPatchBuilding() + if self.c.Git().Patch.PatchBuilder.Active() && self.c.Git().Patch.PatchBuilder.NewPatchRequired(from, to, reverse) { + self.c.Confirm(types.ConfirmOpts{ + Title: self.c.Tr.DiscardPatch, + Prompt: self.c.Tr.DiscardPatchConfirm, + HandleConfirm: func() error { + self.c.Git().Patch.PatchBuilder.Reset() + return enterTheFile() + }, + }) + + return nil + } + + return enterTheFile() +} + +func (self *CommitFilesHelper) context() *context.CommitFilesContext { + return self.c.Contexts().CommitFiles +} + +func (self *CommitFilesHelper) handleToggleCommitFileDirCollapsed(node *filetree.CommitFileNode) { + self.context().CommitFileTreeViewModel.ToggleCollapsed(node.GetInternalPath()) + + self.c.PostRefreshUpdate(self.context()) +} + +func (self *CommitFilesHelper) StartPatchBuilder() error { + commitFilesContext := self.context() + + canRebase := commitFilesContext.GetCanRebase() + from, to, reverse := self.CurrentFromToReverseForPatchBuilding() + + self.c.Git().Patch.PatchBuilder.Start(from, to, reverse, canRebase) + return nil +} + +func (self *CommitFilesHelper) CurrentFromToReverseForPatchBuilding() (string, string, bool) { + commitFilesContext := self.context() + + from, to := commitFilesContext.GetFromAndToForDiff() + from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from) + return from, to, reverse +} diff --git a/pkg/gui/controllers/helpers/helpers.go b/pkg/gui/controllers/helpers/helpers.go index 1f1050dc974..ddfe0170c26 100644 --- a/pkg/gui/controllers/helpers/helpers.go +++ b/pkg/gui/controllers/helpers/helpers.go @@ -35,6 +35,7 @@ type Helpers struct { AmendHelper *AmendHelper FixupHelper *FixupHelper Commits *CommitsHelper + CommitFiles *CommitFilesHelper Snake *SnakeHelper // lives in context package because our contexts need it to render to main Diff *DiffHelper @@ -73,6 +74,7 @@ func NewStubHelpers() *Helpers { AmendHelper: &AmendHelper{}, FixupHelper: &FixupHelper{}, Commits: &CommitsHelper{}, + CommitFiles: &CommitFilesHelper{}, Snake: &SnakeHelper{}, Diff: &DiffHelper{}, Repos: &ReposHelper{}, From e829b61807e14b9bbfa9ace855d094477c15d06b Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Fri, 11 Oct 2024 16:44:59 +0200 Subject: [PATCH 8/9] Press enter in main view of commits panel to enter patch building for clicked line This involves first switching to the commit files view, and then entering the clicked file from there. --- .../switch_to_diff_files_controller.go | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/pkg/gui/controllers/switch_to_diff_files_controller.go b/pkg/gui/controllers/switch_to_diff_files_controller.go index fc764ca7edd..ec6c2d7a7f5 100644 --- a/pkg/gui/controllers/switch_to_diff_files_controller.go +++ b/pkg/gui/controllers/switch_to_diff_files_controller.go @@ -1,6 +1,9 @@ package controllers import ( + "path/filepath" + + "github.com/jesseduffield/lazygit/pkg/gui/filetree" "github.com/jesseduffield/lazygit/pkg/gui/types" ) @@ -47,6 +50,41 @@ func (self *SwitchToDiffFilesController) GetKeybindings(opts types.KeybindingsOp return bindings } +func (self *SwitchToDiffFilesController) GetOnClickFocusedMainView() func(mainViewName string, clickedLineIdx int) error { + return func(mainViewName string, clickedLineIdx int) error { + clickedFile, line, ok := self.c.Helpers().Staging.GetFileAndLineForClickedDiffLine(mainViewName, clickedLineIdx) + if !ok { + return nil + } + + if err := self.enter(); err != nil { + return err + } + + context := self.c.Contexts().CommitFiles + var node *filetree.CommitFileNode + + relativePath, err := filepath.Rel(self.c.Git().RepoPaths.RepoPath(), clickedFile) + if err != nil { + return err + } + relativePath = "./" + relativePath + context.CommitFileTreeViewModel.ExpandToPath(relativePath) + self.c.PostRefreshUpdate(context) + + idx, ok := context.CommitFileTreeViewModel.GetIndexForPath(relativePath) + if !ok { + return nil + } + + context.SetSelectedLineIdx(idx) + context.GetViewTrait().FocusPoint( + context.ModelIndexToViewIndex(idx)) + node = context.GetSelected() + return self.c.Helpers().CommitFiles.EnterCommitFile(node, types.OnFocusOpts{ClickedWindowName: "main", ClickedViewLineIdx: line, ClickedViewRealLineIdx: line}) + } +} + func (self *SwitchToDiffFilesController) Context() types.Context { return self.context } From cc822bccd50aa33c608f68cbaf6c2a8b4b4deef1 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sat, 29 Mar 2025 16:52:55 +0100 Subject: [PATCH 9/9] WIP After going straight to patch building from main view, esc goes all the way back out I *think* I like it better this way, but it needs more testing. --- pkg/gui/controllers/helpers/patch_building_helper.go | 6 +++++- pkg/gui/controllers/switch_to_diff_files_controller.go | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/gui/controllers/helpers/patch_building_helper.go b/pkg/gui/controllers/helpers/patch_building_helper.go index 931c3347fa4..6b41c241afc 100644 --- a/pkg/gui/controllers/helpers/patch_building_helper.go +++ b/pkg/gui/controllers/helpers/patch_building_helper.go @@ -29,7 +29,11 @@ func (self *PatchBuildingHelper) ValidateNormalWorkingTreeState() (bool, error) // takes us from the patch building panel back to the commit files panel func (self *PatchBuildingHelper) Escape() { - self.c.Context().Pop() + if parentCtx := self.c.Contexts().CustomPatchBuilder.GetParentContext(); parentCtx != nil { + self.c.Context().Push(parentCtx, types.OnFocusOpts{}) + } else { + self.c.Context().Pop() + } } // kills the custom patch and returns us back to the commit files panel if needed diff --git a/pkg/gui/controllers/switch_to_diff_files_controller.go b/pkg/gui/controllers/switch_to_diff_files_controller.go index ec6c2d7a7f5..f8e7d314831 100644 --- a/pkg/gui/controllers/switch_to_diff_files_controller.go +++ b/pkg/gui/controllers/switch_to_diff_files_controller.go @@ -81,6 +81,7 @@ func (self *SwitchToDiffFilesController) GetOnClickFocusedMainView() func(mainVi context.GetViewTrait().FocusPoint( context.ModelIndexToViewIndex(idx)) node = context.GetSelected() + self.c.Contexts().CustomPatchBuilder.SetParentContext(self.context) return self.c.Helpers().CommitFiles.EnterCommitFile(node, types.OnFocusOpts{ClickedWindowName: "main", ClickedViewLineIdx: line, ClickedViewRealLineIdx: line}) } }