diff --git a/pkg/gui/main_view_render.go b/pkg/gui/main_view_render.go index fdaf73798..7b9b75c23 100644 --- a/pkg/gui/main_view_render.go +++ b/pkg/gui/main_view_render.go @@ -36,6 +36,16 @@ type renderSpec struct { // user has configured. The renderer lays its rendering out to the width of the // view, which only the layout settles, so the task is created after it. func (gui *Gui) newRenderTask(view *gocui.View, cmd *exec.Cmd, prefix string) error { + // Ask whatever renders the diff to state, in an OSC 1717 record per line, + // which line of which file it is rendering. This lets us act on the line the + // user is pointing at even when the rendering no longer looks like a diff. + // The variable names the protocol versions we understand, and a renderer + // that doesn't understand it ignores it, so we can set it always. It has to + // be set before the plain path below, since on that path git renders the + // diff itself, and git speaks the protocol too, for its word-diff formats, + // whose markup we could not otherwise resolve. + cmd.Env = append(cmd.Env, "OSC1717=V1") + if gui.stateAccessor.GetDiffRendererConfigManager().GetDiffRendererType() == config.DiffRendererType_RawGit { // If we're not using a custom diff renderer, then we don't need to use a pty return gui.newCmdTask(view, cmd, prefix) diff --git a/pkg/integration/tests/diff/diff_renderer_metadata.go b/pkg/integration/tests/diff/diff_renderer_metadata.go new file mode 100644 index 000000000..ff211717d --- /dev/null +++ b/pkg/integration/tests/diff/diff_renderer_metadata.go @@ -0,0 +1,50 @@ +package diff + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var DiffRendererMetadata = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "A diff renderer is told that we understand the OSC 1717 metadata protocol, and the records it emits don't show up in the rendered diff", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(cfg *config.AppConfig) { + // A fake conforming renderer: it announces the protocol with a + // version-only record, reports the protocol versions it was offered, and + // then passes the diff through with a per-line record in front of every + // line. + cfg.GetUserConfig().Git.DiffRenderers = []config.DiffRendererConfig{ + {Command: `printf '\033]1717;1\007'; ` + + `printf 'OFFERED:%s\n' "$OSC1717"; ` + + `while IFS= read -r line; do printf '\033]1717;1;c;1;;file1\007%s\n' "$line"; done`}, + } + }, + SetupRepo: func(shell *Shell) { + shell.CreateFileAndAdd("file1", "one\ntwo\n") + shell.Commit("one") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + Lines( + Contains("one").IsSelected(), + ) + + t.Views().Main(). + // The renderer was offered the protocol version we understand. + Content(Contains("OFFERED:V1")). + // Its records are escape sequences, so none of them reaches the + // screen; the diff reads exactly as the renderer wrote it. + ContainsLines( + Equals("diff --git a/file1 b/file1"), + Contains("new file mode"), + Contains("index "), + Equals("--- /dev/null"), + Equals("+++ b/file1"), + Equals("@@ -0,0 +1,2 @@"), + Equals("+one"), + Equals("+two"), + ) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 372b82c8f..e9cd5946d 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -228,6 +228,7 @@ var tests = []*components.IntegrationTest{ diff.DiffAndApplyPatch, diff.DiffCommits, diff.DiffNonStickyRange, + diff.DiffRendererMetadata, diff.IgnoreWhitespace, diff.RenameSimilarityThresholdChange, diff.RenderThroughAPipe,