Let an external diff command be told the width it renders at

Like a stdin filter, an external diff program lays out its rendering to
the width it reads off the terminal, and a render through a pipe leaves
it nothing to read. difftastic in side-by-side mode is the case that
shows it.

Offer the width as the {{width}} template variable, the same name the
stdin filter command takes it by. Since difftastic supports the COLUMNS
variable, which we will set later in this branch, and I don't know of
any other external-diff renderer that doesn't, we don't document this.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Haller
2026-09-25 11:31:59 +02:00
co-authored by Claude Opus 5
parent f496f17452
commit ec3427fdcc
3 changed files with 42 additions and 2 deletions
+2 -1
View File
@@ -88,7 +88,7 @@ func (self *DiffRendererConfigManager) GetColorArg() string {
return colorArg
}
func (self *DiffRendererConfigManager) GetExternalDiffCommand(diffContext uint64) string {
func (self *DiffRendererConfigManager) GetExternalDiffCommand(diffContext uint64, width int) string {
currentDiffRendererConfig := self.currentDiffRendererConfig()
if currentDiffRendererConfig == nil || currentDiffRendererConfig.getType() != DiffRendererType_ExtDiff {
return ""
@@ -96,6 +96,7 @@ func (self *DiffRendererConfigManager) GetExternalDiffCommand(diffContext uint64
templateValues := map[string]string{
"diffContext": strconv.Itoa(int(diffContext)),
"width": strconv.Itoa(width),
}
return utils.ResolvePlaceholderString(string(currentDiffRendererConfig.Command), templateValues)
@@ -113,6 +113,45 @@ func TestGetStdinFilterCommand(t *testing.T) {
}
}
func TestGetExternalDiffCommand(t *testing.T) {
scenarios := []struct {
name string
diffRendererConfig DiffRendererConfig
expected string
}{
{
name: "a command without template variables is passed through",
diffRendererConfig: DiffRendererConfig{Type: "extDiff", Command: "difft --color=always"},
expected: "difft --color=always",
},
{
name: "the width the diff is rendered at",
diffRendererConfig: DiffRendererConfig{Type: "extDiff", Command: "difft --width={{width}}"},
expected: "difft --width=120",
},
{
name: "the width alongside the diff context size",
diffRendererConfig: DiffRendererConfig{Type: "extDiff", Command: "difft --width={{width}} --context={{diffContext}}"},
expected: "difft --width=120 --context=3",
},
{
name: "nothing is returned for a renderer of another type",
diffRendererConfig: DiffRendererConfig{Command: "delta --width={{width}}"},
expected: "",
},
}
for _, s := range scenarios {
t.Run(s.name, func(t *testing.T) {
userConfig := &UserConfig{}
userConfig.Git.DiffRenderers = []DiffRendererConfig{s.diffRendererConfig}
config := NewDiffRendererConfigManager(func() *UserConfig { return userConfig })
assert.Equal(t, s.expected, config.GetExternalDiffCommand(3, 120))
})
}
}
func TestCurrentDiffRendererNameWithoutDiffRenderers(t *testing.T) {
config := NewDiffRendererConfigManager(func() *UserConfig { return &UserConfig{} })
+1 -1
View File
@@ -89,7 +89,7 @@ func (gui *Gui) newPtyTask(view *gocui.View, cmd *exec.Cmd, prefix string) error
width = view.InnerWidth()
diffRendererConfigManager := gui.stateAccessor.GetDiffRendererConfigManager()
pager := diffRendererConfigManager.GetStdinFilterCommand(width)
externalDiff := diffRendererConfigManager.GetExternalDiffCommand(gui.c.UserConfig().Git.DiffContextSize)
externalDiff := diffRendererConfigManager.GetExternalDiffCommand(gui.c.UserConfig().Git.DiffContextSize, width)
cmdStr := strings.Join(cmd.Args, " ")