From 4ce8d77173c5fc0f2d75603637959c802548fc34 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Fri, 25 Sep 2026 14:49:45 +0200 Subject: [PATCH] Resolve the commands of all kinds of diff renderers in one place The getters for the stdin filter and the external diff command each take the values they fill in as parameters of their own, and each builds the placeholders for them. The next commit checks the commands when the config is loaded, and for that it needs to resolve a command whatever its kind. A value that both kinds can use comes after that. Co-Authored-By: Claude Opus 5.5 (1M context) --- pkg/config/diff_renderer_config_manager.go | 40 +++++++++++++------ .../diff_renderer_config_manager_test.go | 4 +- pkg/gui/main_view_render.go | 5 ++- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/pkg/config/diff_renderer_config_manager.go b/pkg/config/diff_renderer_config_manager.go index 80dee5830..be8fef166 100644 --- a/pkg/config/diff_renderer_config_manager.go +++ b/pkg/config/diff_renderer_config_manager.go @@ -60,19 +60,21 @@ func (self *DiffRendererConfigManager) GetDiffRendererType() DiffRendererType { return currentDiffRendererConfig.getType() } -func (self *DiffRendererConfigManager) GetStdinFilterCommand(width int) string { +// DiffRendererValues are what the command of a diff renderer can refer to. +type DiffRendererValues struct { + // The width of the view that the diff is rendered into + Width int + // The number of lines of context around each hunk + DiffContext uint64 +} + +func (self *DiffRendererConfigManager) GetStdinFilterCommand(values DiffRendererValues) string { currentDiffRendererConfig := self.currentDiffRendererConfig() if currentDiffRendererConfig == nil || currentDiffRendererConfig.getType() != DiffRendererType_StdinFilter { return "" } - templateValues := map[string]string{ - "width": strconv.Itoa(width), - "columnWidth": strconv.Itoa(width/2 - 6), - } - - commandTemplate := string(currentDiffRendererConfig.Command) - return utils.ResolvePlaceholderString(commandTemplate, templateValues) + return currentDiffRendererConfig.resolveCommand(values) } func (self *DiffRendererConfigManager) GetColorArg() string { @@ -88,18 +90,30 @@ func (self *DiffRendererConfigManager) GetColorArg() string { return colorArg } -func (self *DiffRendererConfigManager) GetExternalDiffCommand(diffContext uint64, width int) string { +func (self *DiffRendererConfigManager) GetExternalDiffCommand(values DiffRendererValues) string { currentDiffRendererConfig := self.currentDiffRendererConfig() if currentDiffRendererConfig == nil || currentDiffRendererConfig.getType() != DiffRendererType_ExtDiff { return "" } - templateValues := map[string]string{ - "diffContext": strconv.Itoa(int(diffContext)), - "width": strconv.Itoa(width), + return currentDiffRendererConfig.resolveCommand(values) +} + +// resolveCommand fills in the values that the renderer's command refers to. +func (self *DiffRendererConfig) resolveCommand(values DiffRendererValues) string { + placeholders := map[string]string{ + "width": strconv.Itoa(values.Width), + } + switch self.getType() { + case DiffRendererType_StdinFilter: + placeholders["columnWidth"] = strconv.Itoa(values.Width/2 - 6) + case DiffRendererType_ExtDiff: + placeholders["diffContext"] = strconv.Itoa(int(values.DiffContext)) + case DiffRendererType_RawGit: + // has no command } - return utils.ResolvePlaceholderString(string(currentDiffRendererConfig.Command), templateValues) + return utils.ResolvePlaceholderString(string(self.Command), placeholders) } func (self *DiffRendererConfigManager) GetRawGitArgs() []string { diff --git a/pkg/config/diff_renderer_config_manager_test.go b/pkg/config/diff_renderer_config_manager_test.go index e2d4a8e44..bcced5e5c 100644 --- a/pkg/config/diff_renderer_config_manager_test.go +++ b/pkg/config/diff_renderer_config_manager_test.go @@ -108,7 +108,7 @@ func TestGetStdinFilterCommand(t *testing.T) { userConfig.Git.DiffRenderers = []DiffRendererConfig{s.diffRendererConfig} config := NewDiffRendererConfigManager(func() *UserConfig { return userConfig }) - assert.Equal(t, s.expected, config.GetStdinFilterCommand(s.width)) + assert.Equal(t, s.expected, config.GetStdinFilterCommand(DiffRendererValues{Width: s.width})) }) } } @@ -147,7 +147,7 @@ func TestGetExternalDiffCommand(t *testing.T) { userConfig.Git.DiffRenderers = []DiffRendererConfig{s.diffRendererConfig} config := NewDiffRendererConfigManager(func() *UserConfig { return userConfig }) - assert.Equal(t, s.expected, config.GetExternalDiffCommand(3, 120)) + assert.Equal(t, s.expected, config.GetExternalDiffCommand(DiffRendererValues{Width: 120, DiffContext: 3})) }) } } diff --git a/pkg/gui/main_view_render.go b/pkg/gui/main_view_render.go index bfeba9b16..234f327f2 100644 --- a/pkg/gui/main_view_render.go +++ b/pkg/gui/main_view_render.go @@ -56,8 +56,9 @@ func (gui *Gui) newRenderTask(view *gocui.View, cmd *exec.Cmd, prefix string) er // width to render at known, and with it the renderer command. width := view.InnerWidth() diffRendererConfigManager := gui.stateAccessor.GetDiffRendererConfigManager() - stdinFilter := diffRendererConfigManager.GetStdinFilterCommand(width) - externalDiff := diffRendererConfigManager.GetExternalDiffCommand(gui.c.UserConfig().Git.DiffContextSize, width) + values := config.DiffRendererValues{Width: width, DiffContext: gui.c.UserConfig().Git.DiffContextSize} + stdinFilter := diffRendererConfigManager.GetStdinFilterCommand(values) + externalDiff := diffRendererConfigManager.GetExternalDiffCommand(values) cmdStr := strings.Join(cmd.Args, " ")