Repository: jesseduffield/lazygit
File: pkg/gui/controllers/helpers/diff_helper.go (Go)

Code before:

	return f()
}

func (self *DiffHelper) IgnoringWhitespaceSubTitle() string {
	if self.c.GetAppState().IgnoreWhitespaceInDiffView {
		return self.c.Tr.IgnoreWhitespaceDiffViewSubTitle
	}

	return ""
}

func (self *DiffHelper) DefaultOpenDiffTool(checkedOutRef types.Ref, selectedRef types.Ref) error {
	to := selectedRef.RefName()
	from, reverse := lo.Unpack2(lo.TernaryF(self.c.Modes().Diffing.Active(),
		func() lo.Tuple2[string, bool] {
			from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(selectedRef.ParentRefName())
			return lo.Tuple2[string, bool]{A: from, B: reverse}
		},
		func() lo.Tuple2[string, bool] { return lo.Tuple2[string, bool]{A: checkedOutRef.RefName(), B: false} }))
	_, err := self.c.RunSubprocess(self.c.Git().Diff.OpenDiffToolCmdObj(
		git_commands.DiffToolCmdOptions{
			Filepath:    ".",
			FromCommit:  from,
			ToCommit:    to,
			Reverse:     reverse,
			IsDirectory: true,
			Staged:      false,
		}))
	return err
}


Review comment (refactor):
This is close, but not quite the same as `git difftool <selectedRef>` on the command line does. You are diffing the selected ref against the checked-out branch, but `git difftool <selectedRef>` diffs it against the working tree. This is different when there are modified files in the working tree.

The easiest way to do this seems to be
```go
func (self *DiffHelper) DefaultOpenDiffTool(selectedRef types.Ref) error {
	to := selectedRef.RefName()
	from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff("")
	_, err := self.c.RunSubprocess(self.c.Git().Diff.OpenDiffToolCmdObj(
		git_commands.DiffToolCmdOptions{
			Filepath:    ".",
			FromCommit:  from,
			ToCommit:    to,
			Reverse:     reverse,
			IsDirectory: true,
			Staged:      false,
		}))
	return err
}
```

Side note: I'm usually a fan of ternaries, but when you have to use tuples to pack and unpack multiple return values, then that's taking it too far for my taste. Also, my preference for ternaries probably comes from C++ where it makes it possible to declare the variable as `const`, which is always nice; go doesn't have this concept, so there's not as much of a benefit. And the more go code I read, the more I get the feeling that
```go
x := "first choice"
if condition {
  x = "other choice"
}
```
is simply the idiomatic way of expressing this in go, so I'm probably going to reduce my use of `lo.Ternary`.

And finally: the name `DefaultOpenDiffTool` doesn't say much about what this is; how about `OpenDiffToolForRef`?

Code after:

	return f()
}

func (self *DiffHelper) IgnoringWhitespaceSubTitle() string {
	if self.c.GetAppState().IgnoreWhitespaceInDiffView {
		return self.c.Tr.IgnoreWhitespaceDiffViewSubTitle
	}

	return ""
}

func (self *DiffHelper) OpenDiffToolForRef(selectedRef types.Ref) error {
	to := selectedRef.RefName()
	from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff("")
	_, err := self.c.RunSubprocess(self.c.Git().Diff.OpenDiffToolCmdObj(
		git_commands.DiffToolCmdOptions{
			Filepath:    ".",
			FromCommit:  from,
			ToCommit:    to,
			Reverse:     reverse,
			IsDirectory: true,
			Staged:      false,
		}))
	return err
}