diff --git a/pkg/gui/controllers/commits_files_controller.go b/pkg/gui/controllers/commits_files_controller.go index 50de22093..c303933c1 100644 --- a/pkg/gui/controllers/commits_files_controller.go +++ b/pkg/gui/controllers/commits_files_controller.go @@ -176,8 +176,9 @@ func (self *CommitFilesController) GetOnRenderToMain() func() { from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from) paths := self.pathsForDiff(node) - cmdObj := self.c.Git().WorkingTree.ShowFileDiffCmdObj(from, to, reverse, paths, false, false) - task := types.NewRunPtyTask(cmdObj.GetCmd()) + renderRaw := self.c.Helpers().Staging.DiffMainViewShouldRenderRaw() + cmdObj := self.c.Git().WorkingTree.ShowFileDiffCmdObj(from, to, reverse, paths, false, renderRaw) + task := types.NewMainViewDiffTask(renderRaw, cmdObj.GetCmd()) // Keep the inclusion gutter in step with the content as this diff (re-)renders. // It's a no-op unless the main view is focused and a patch is being built (see diff --git a/pkg/gui/controllers/helpers/diff_helper.go b/pkg/gui/controllers/helpers/diff_helper.go index e8d3a7a70..899ad96f4 100644 --- a/pkg/gui/controllers/helpers/diff_helper.go +++ b/pkg/gui/controllers/helpers/diff_helper.go @@ -52,7 +52,11 @@ func (self *DiffHelper) DiffArgs() []string { // and the refRange for a range selection. If the refRange is nil (meaning that // either there's no range, or it can't be diffed for some reason), then we want // to fall back to rendering the diff for the single commit. -func (self *DiffHelper) GetUpdateTaskForRenderingCommitsDiff(commit *models.Commit, refRange *types.RefRange) types.UpdateTask { +// GetUpdateTaskForRenderingCommitsDiff builds the task for showing a commit's (or a +// commit range's) diff in the main view. renderRaw bypasses the pager for the focused +// main view's raw-diff fallback (see StagingHelper.DiffMainViewShouldRenderRaw); the +// calling panel computes it, since this helper can't reach the staging helper. +func (self *DiffHelper) GetUpdateTaskForRenderingCommitsDiff(commit *models.Commit, refRange *types.RefRange, renderRaw bool) types.UpdateTask { if refRange != nil { from, to := refRange.From, refRange.To args := []string{from.ParentRefName(), to.RefName(), "--stat", "-p"} @@ -72,13 +76,13 @@ func (self *DiffHelper) GetUpdateTaskForRenderingCommitsDiff(commit *models.Comm args = append(args, filterPath) } } - cmdObj := self.c.Git().Diff.DiffCmdObj(args, false) + cmdObj := self.c.Git().Diff.DiffCmdObj(args, renderRaw) prefix := style.FgYellow.Sprintf("%s %s-%s\n\n", self.c.Tr.ShowingDiffForRange, from.ShortRefName(), to.ShortRefName()) - return types.NewRunPtyTaskWithPrefix(cmdObj.GetCmd(), prefix) + return types.NewMainViewDiffTaskWithPrefix(renderRaw, cmdObj.GetCmd(), prefix) } - cmdObj := self.c.Git().Commit.ShowCmdObj(commit.Hash(), self.FilterPathsForCommit(commit), false) - return types.NewRunPtyTask(cmdObj.GetCmd()) + cmdObj := self.c.Git().Commit.ShowCmdObj(commit.Hash(), self.FilterPathsForCommit(commit), renderRaw) + return types.NewMainViewDiffTask(renderRaw, cmdObj.GetCmd()) } func (self *DiffHelper) FilterPathsForCommit(commit *models.Commit) []string { diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go index c9d1601ee..40c88fa46 100644 --- a/pkg/gui/controllers/local_commits_controller.go +++ b/pkg/gui/controllers/local_commits_controller.go @@ -703,7 +703,8 @@ func (self *LocalCommitsController) GetOnRenderToMain() func() { self.c.Tr.ExecCommandHere + "\n\n" + commit.Name) } else { refRange := self.context().GetSelectedRefRangeForDiffFiles() - task = self.c.Helpers().Diff.GetUpdateTaskForRenderingCommitsDiff(commit, refRange) + renderRaw := self.c.Helpers().Staging.DiffMainViewShouldRenderRaw() + task = self.c.Helpers().Diff.GetUpdateTaskForRenderingCommitsDiff(commit, refRange, renderRaw) } // Keep the inclusion gutter in step with the content as this diff diff --git a/pkg/gui/controllers/reflog_commits_controller.go b/pkg/gui/controllers/reflog_commits_controller.go index a4115878a..197b2f008 100644 --- a/pkg/gui/controllers/reflog_commits_controller.go +++ b/pkg/gui/controllers/reflog_commits_controller.go @@ -45,9 +45,10 @@ func (self *ReflogCommitsController) GetOnRenderToMain() func() { if commit == nil { task = types.NewRenderStringTask("No reflog history") } else { - cmdObj := self.c.Git().Commit.ShowCmdObj(commit.Hash(), self.c.Helpers().Diff.FilterPathsForCommit(commit), false) + renderRaw := self.c.Helpers().Staging.DiffMainViewShouldRenderRaw() + cmdObj := self.c.Git().Commit.ShowCmdObj(commit.Hash(), self.c.Helpers().Diff.FilterPathsForCommit(commit), renderRaw) - task = types.NewRunPtyTask(cmdObj.GetCmd()) + task = types.NewMainViewDiffTask(renderRaw, cmdObj.GetCmd()) } self.c.RenderToMainViews(types.RefreshMainOpts{ diff --git a/pkg/gui/controllers/stash_controller.go b/pkg/gui/controllers/stash_controller.go index 095bc8a75..adcaebea5 100644 --- a/pkg/gui/controllers/stash_controller.go +++ b/pkg/gui/controllers/stash_controller.go @@ -93,8 +93,10 @@ func (self *StashController) GetOnRenderToMain() func() { task = types.NewRenderStringTask(self.c.Tr.NoStashEntries) } else { prefix := style.FgYellow.Sprintf("%s\n\n", stashEntry.Description()) - task = types.NewRunPtyTaskWithPrefix( - self.c.Git().Stash.ShowStashEntryCmdObj(stashEntry.Index, false).GetCmd(), + renderRaw := self.c.Helpers().Staging.DiffMainViewShouldRenderRaw() + task = types.NewMainViewDiffTaskWithPrefix( + renderRaw, + self.c.Git().Stash.ShowStashEntryCmdObj(stashEntry.Index, renderRaw).GetCmd(), prefix, ) } diff --git a/pkg/gui/controllers/sub_commits_controller.go b/pkg/gui/controllers/sub_commits_controller.go index f2333765d..131047597 100644 --- a/pkg/gui/controllers/sub_commits_controller.go +++ b/pkg/gui/controllers/sub_commits_controller.go @@ -46,7 +46,8 @@ func (self *SubCommitsController) GetOnRenderToMain() func() { task = types.NewRenderStringTask("No commits") } else { refRange := self.context().GetSelectedRefRangeForDiffFiles() - task = self.c.Helpers().Diff.GetUpdateTaskForRenderingCommitsDiff(commit, refRange) + renderRaw := self.c.Helpers().Staging.DiffMainViewShouldRenderRaw() + task = self.c.Helpers().Diff.GetUpdateTaskForRenderingCommitsDiff(commit, refRange, renderRaw) } // Keep the inclusion gutter in step with the content as this diff diff --git a/pkg/integration/tests/patch_building/build_from_main_view_with_unsupported_pager.go b/pkg/integration/tests/patch_building/build_from_main_view_with_unsupported_pager.go new file mode 100644 index 000000000..1014e083c --- /dev/null +++ b/pkg/integration/tests/patch_building/build_from_main_view_with_unsupported_pager.go @@ -0,0 +1,62 @@ +package patch_building + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var BuildFromMainViewWithUnsupportedPager = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Build a custom patch from a commit's focused main view under a pager that restructures the diff without emitting metadata; it falls back to the raw diff so the selection is still toggleable", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(cfg *config.AppConfig) { + cfg.GetUserConfig().Gui.UseHunkModeInStagingView = false + // `cat -n` numbers every line, which the buffer parser can't resolve, and cat + // emits no metadata, so the focused main view must fall back to the raw diff. + cfg.GetUserConfig().Git.DiffRenderers = []config.DiffRendererConfig{ + {Command: "cat -n"}, + } + }, + SetupRepo: func(shell *Shell) { + shell.CreateFileAndAdd("file1", "one\ntwo\nthree\nfour\nfive\n") + shell.Commit("first commit") + + shell.UpdateFileAndAdd("file1", "one\ntwo\nTHREE\nfour\nfive\n") + shell.Commit("update") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + Lines( + Contains("update").IsSelected(), + Contains("first commit"), + ) + + // While browsing, the main view shows the pager's output (numbered lines). + t.Views().Main().Content(Contains(" +THREE")) + + // Focusing the main view falls back to the raw diff, so the change line is + // resolved and the selection is toggleable into a custom patch. + t.Views().Commits().Press(keys.Universal.FocusMainView) + + t.Views().Main(). + IsFocused(). + SelectedLines( + Contains("-three"), + ). + Press(keys.Main.ToggleSelectHunk). + SelectedLines( + Contains("-three"), + Contains("+THREE"), + ). + PressPrimaryAction() + + t.Views().Information().Content(Contains("Building patch")) + + t.Views().Secondary(). + ContainsLines( + Contains("-three"), + Contains("+THREE"), + ) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 78ea9132f..a35b221f2 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -362,6 +362,7 @@ var tests = []*components.IntegrationTest{ patch_building.ApplyWithModifiedFileConflict, patch_building.ApplyWithModifiedFileNoConflict, patch_building.BuildFromMainView, + patch_building.BuildFromMainViewWithUnsupportedPager, patch_building.BuildFromWholeCommitMainView, patch_building.BuildMultiFileFromWholeCommitMainView, patch_building.CopyRenamedFileDiff,