diff --git a/docs/keybindings/Keybindings_en.md b/docs/keybindings/Keybindings_en.md index 5c56b6b83..7c6e48e43 100644 --- a/docs/keybindings/Keybindings_en.md +++ b/docs/keybindings/Keybindings_en.md @@ -18,6 +18,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct W: open diff menu ctrl+e: open diff menu @: open command log menu + ctrl+w: Toggle whether or not whitespace changes are shown in the diff view }: Increase the size of the context shown around changes in the diff view {: Decrease the size of the context shown around changes in the diff view :: execute custom command @@ -92,7 +93,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
ctrl+o: copy the file name to the clipboard - ctrl+w: Toggle whether or not whitespace changes are shown in the diff view d: view 'discard changes' options space: toggle staged ctrl+b: Filter files (staged/unstaged) diff --git a/docs/keybindings/Keybindings_ja.md b/docs/keybindings/Keybindings_ja.md index 2cf603abf..6a9f67b6c 100644 --- a/docs/keybindings/Keybindings_ja.md +++ b/docs/keybindings/Keybindings_ja.md @@ -18,6 +18,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct W: 差分メニューを開く ctrl+e: 差分メニューを開く @: コマンドログメニューを開く + ctrl+w: 空白文字の差分の表示有無を切り替え }: Increase the size of the context shown around changes in the diff view {: Decrease the size of the context shown around changes in the diff view :: カスタムコマンドを実行 @@ -152,7 +153,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n directctrl+o: ファイル名をクリップボードにコピー - ctrl+w: 空白文字の差分の表示有無を切り替え d: view 'discard changes' options space: ステージ/アンステージ ctrl+b: ファイルをフィルタ (ステージ/アンステージ) diff --git a/docs/keybindings/Keybindings_ko.md b/docs/keybindings/Keybindings_ko.md index f49e6eb78..151f49129 100644 --- a/docs/keybindings/Keybindings_ko.md +++ b/docs/keybindings/Keybindings_ko.md @@ -18,6 +18,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct W: Diff 메뉴 열기 ctrl+e: Diff 메뉴 열기 @: 명령어 로그 메뉴 열기 + ctrl+w: 공백문자를 Diff 뷰에서 표시 여부 전환 }: diff 보기의 변경 사항 주위에 표시되는 컨텍스트의 크기를 늘리기 {: diff 보기의 변경 사항 주위에 표시되는 컨텍스트 크기 줄이기 :: execute custom command @@ -271,7 +272,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n directctrl+o: 파일명을 클립보드에 복사 - ctrl+w: 공백문자를 Diff 뷰에서 표시 여부 전환 d: view 'discard changes' options space: Staged 전환 ctrl+b: 파일을 필터하기 (Staged/unstaged) diff --git a/docs/keybindings/Keybindings_nl.md b/docs/keybindings/Keybindings_nl.md index 01ea95417..bdb6b20f7 100644 --- a/docs/keybindings/Keybindings_nl.md +++ b/docs/keybindings/Keybindings_nl.md @@ -18,6 +18,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct W: open diff menu ctrl+e: open diff menu @: open command log menu + ctrl+w: Toggle whether or not whitespace changes are shown in the diff view }: Increase the size of the context shown around changes in the diff view {: Decrease the size of the context shown around changes in the diff view :: voer aangepaste commando uit @@ -45,7 +46,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n directctrl+o: kopieer de bestandsnaam naar het klembord - ctrl+w: Toggle whether or not whitespace changes are shown in the diff view d: bekijk 'veranderingen ongedaan maken' opties space: toggle staged ctrl+b: Filter files (staged/unstaged) diff --git a/docs/keybindings/Keybindings_pl.md b/docs/keybindings/Keybindings_pl.md index 23473ca2c..9f00b4cc0 100644 --- a/docs/keybindings/Keybindings_pl.md +++ b/docs/keybindings/Keybindings_pl.md @@ -18,6 +18,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct W: open diff menu ctrl+e: open diff menu @: open command log menu + ctrl+w: Toggle whether or not whitespace changes are shown in the diff view }: Increase the size of the context shown around changes in the diff view {: Decrease the size of the context shown around changes in the diff view :: wykonaj własną komendę @@ -115,7 +116,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n directctrl+o: copy the file name to the clipboard - ctrl+w: Toggle whether or not whitespace changes are shown in the diff view d: pokaż opcje porzucania zmian space: przełącz stan poczekalni ctrl+b: Filter files (staged/unstaged) diff --git a/docs/keybindings/Keybindings_zh.md b/docs/keybindings/Keybindings_zh.md index 6650d0f71..9bc663783 100644 --- a/docs/keybindings/Keybindings_zh.md +++ b/docs/keybindings/Keybindings_zh.md @@ -18,6 +18,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct W: 打开 diff 菜单 ctrl+e: 打开 diff 菜单 @: 打开命令日志菜单 + ctrl+w: 切换是否在差异视图中显示空白字符差异 }: 扩大差异视图中显示的上下文范围 {: 缩小差异视图中显示的上下文范围 :: 执行自定义命令 @@ -157,7 +158,6 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n directctrl+o: 将文件名复制到剪贴板 - ctrl+w: 切换是否在差异视图中显示空白字符差异 d: 查看'放弃更改'选项 space: 切换暂存状态 ctrl+b: Filter files (staged/unstaged) diff --git a/pkg/commands/git.go b/pkg/commands/git.go index ad3831b01..e2a31c009 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -118,7 +118,12 @@ func NewGitCommandAux( rebaseCommands := git_commands.NewRebaseCommands(gitCommon, commitCommands, workingTreeCommands) stashCommands := git_commands.NewStashCommands(gitCommon, fileLoader, workingTreeCommands) // TODO: have patch manager take workingTreeCommands in its entirety - patchManager := patch.NewPatchManager(cmn.Log, workingTreeCommands.ApplyPatch, workingTreeCommands.ShowFileDiff) + patchManager := patch.NewPatchManager(cmn.Log, workingTreeCommands.ApplyPatch, + func(from string, to string, reverse bool, filename string, plain bool) (string, error) { + // TODO: make patch manager take Gui.IgnoreWhitespaceInDiffView into + // account. For now we just pass false. + return workingTreeCommands.ShowFileDiff(from, to, reverse, filename, plain, false) + }) patchCommands := git_commands.NewPatchCommands(gitCommon, rebaseCommands, commitCommands, statusCommands, stashCommands, patchManager) bisectCommands := git_commands.NewBisectCommands(gitCommon) diff --git a/pkg/commands/git_commands/commit.go b/pkg/commands/git_commands/commit.go index b5293a2ff..0a162a6b6 100644 --- a/pkg/commands/git_commands/commit.go +++ b/pkg/commands/git_commands/commit.go @@ -149,14 +149,19 @@ func (self *CommitCommands) AmendHeadCmdObj() oscommands.ICmdObj { return self.cmd.New("git commit --amend --no-edit --allow-empty") } -func (self *CommitCommands) ShowCmdObj(sha string, filterPath string) oscommands.ICmdObj { +func (self *CommitCommands) ShowCmdObj(sha string, filterPath string, ignoreWhitespace bool) oscommands.ICmdObj { contextSize := self.UserConfig.Git.DiffContextSize filterPathArg := "" if filterPath != "" { filterPathArg = fmt.Sprintf(" -- %s", self.cmd.Quote(filterPath)) } + ignoreWhitespaceArg := "" + if ignoreWhitespace { + ignoreWhitespaceArg = " --ignore-all-space" + } - cmdStr := fmt.Sprintf("git show --submodule --color=%s --unified=%d --no-renames --stat -p %s %s", self.UserConfig.Git.Paging.ColorArg, contextSize, sha, filterPathArg) + cmdStr := fmt.Sprintf("git show --submodule --color=%s --unified=%d --no-renames --stat -p %s%s%s", + self.UserConfig.Git.Paging.ColorArg, contextSize, sha, ignoreWhitespaceArg, filterPathArg) return self.cmd.New(cmdStr).DontLog() } diff --git a/pkg/commands/git_commands/commit_test.go b/pkg/commands/git_commands/commit_test.go index 1d6bc7f8f..713c9fffa 100644 --- a/pkg/commands/git_commands/commit_test.go +++ b/pkg/commands/git_commands/commit_test.go @@ -177,30 +177,34 @@ func TestCommitCreateFixupCommit(t *testing.T) { func TestCommitShowCmdObj(t *testing.T) { type scenario struct { - testName string - filterPath string - contextSize int - expected string + testName string + filterPath string + contextSize int + ignoreWhitespace bool + expected string } scenarios := []scenario{ { - testName: "Default case without filter path", - filterPath: "", - contextSize: 3, - expected: "git show --submodule --color=always --unified=3 --no-renames --stat -p 1234567890 ", + testName: "Default case without filter path", + filterPath: "", + contextSize: 3, + ignoreWhitespace: false, + expected: "git show --submodule --color=always --unified=3 --no-renames --stat -p 1234567890", }, { - testName: "Default case with filter path", - filterPath: "file.txt", - contextSize: 3, - expected: `git show --submodule --color=always --unified=3 --no-renames --stat -p 1234567890 -- "file.txt"`, + testName: "Default case with filter path", + filterPath: "file.txt", + contextSize: 3, + ignoreWhitespace: true, + expected: `git show --submodule --color=always --unified=3 --no-renames --stat -p 1234567890 --ignore-all-space -- "file.txt"`, }, { - testName: "Show diff with custom context size", - filterPath: "", - contextSize: 77, - expected: "git show --submodule --color=always --unified=77 --no-renames --stat -p 1234567890 ", + testName: "Show diff with custom context size", + filterPath: "", + contextSize: 77, + ignoreWhitespace: false, + expected: "git show --submodule --color=always --unified=77 --no-renames --stat -p 1234567890", }, } @@ -212,7 +216,7 @@ func TestCommitShowCmdObj(t *testing.T) { instance := buildCommitCommands(commonDeps{userConfig: userConfig}) - cmdStr := instance.ShowCmdObj("1234567890", s.filterPath).ToString() + cmdStr := instance.ShowCmdObj("1234567890", s.filterPath, s.ignoreWhitespace).ToString() assert.Equal(t, s.expected, cmdStr) }) } diff --git a/pkg/commands/git_commands/working_tree.go b/pkg/commands/git_commands/working_tree.go index 7e08c348b..b7ebe0d30 100644 --- a/pkg/commands/git_commands/working_tree.go +++ b/pkg/commands/git_commands/working_tree.go @@ -287,11 +287,15 @@ func (self *WorkingTreeCommands) SaveTemporaryPatch(patch string) (string, error // ShowFileDiff get the diff of specified from and to. Typically this will be used for a single commit so it'll be 123abc^..123abc // but when we're in diff mode it could be any 'from' to any 'to'. The reverse flag is also here thanks to diff mode. -func (self *WorkingTreeCommands) ShowFileDiff(from string, to string, reverse bool, fileName string, plain bool) (string, error) { - return self.ShowFileDiffCmdObj(from, to, reverse, fileName, plain).RunWithOutput() +func (self *WorkingTreeCommands) ShowFileDiff(from string, to string, reverse bool, fileName string, plain bool, + ignoreWhitespace bool, +) (string, error) { + return self.ShowFileDiffCmdObj(from, to, reverse, fileName, plain, ignoreWhitespace).RunWithOutput() } -func (self *WorkingTreeCommands) ShowFileDiffCmdObj(from string, to string, reverse bool, fileName string, plain bool) oscommands.ICmdObj { +func (self *WorkingTreeCommands) ShowFileDiffCmdObj(from string, to string, reverse bool, fileName string, plain bool, + ignoreWhitespace bool, +) oscommands.ICmdObj { colorArg := self.UserConfig.Git.Paging.ColorArg contextSize := self.UserConfig.Git.DiffContextSize if plain { @@ -303,11 +307,16 @@ func (self *WorkingTreeCommands) ShowFileDiffCmdObj(from string, to string, reve reverseFlag = " -R" } + ignoreWhitespaceFlag := "" + if ignoreWhitespace { + ignoreWhitespaceFlag = " --ignore-all-space" + } + return self.cmd. New( fmt.Sprintf( - "git diff --submodule --no-ext-diff --unified=%d --no-renames --color=%s%s%s%s -- %s", - contextSize, colorArg, pad(from), pad(to), reverseFlag, self.cmd.Quote(fileName)), + "git diff --submodule --no-ext-diff --unified=%d --no-renames --color=%s%s%s%s%s -- %s", + contextSize, colorArg, pad(from), pad(to), reverseFlag, ignoreWhitespaceFlag, self.cmd.Quote(fileName)), ). DontLog() } diff --git a/pkg/commands/git_commands/working_tree_test.go b/pkg/commands/git_commands/working_tree_test.go index 049961541..ca2881efe 100644 --- a/pkg/commands/git_commands/working_tree_test.go +++ b/pkg/commands/git_commands/working_tree_test.go @@ -323,38 +323,52 @@ func TestWorkingTreeDiff(t *testing.T) { func TestWorkingTreeShowFileDiff(t *testing.T) { type scenario struct { - testName string - from string - to string - reverse bool - plain bool - contextSize int - runner *oscommands.FakeCmdObjRunner + testName string + from string + to string + reverse bool + plain bool + ignoreWhitespace bool + contextSize int + runner *oscommands.FakeCmdObjRunner } const expectedResult = "pretend this is an actual git diff" scenarios := []scenario{ { - testName: "Default case", - from: "1234567890", - to: "0987654321", - reverse: false, - plain: false, - contextSize: 3, + testName: "Default case", + from: "1234567890", + to: "0987654321", + reverse: false, + plain: false, + ignoreWhitespace: false, + contextSize: 3, runner: oscommands.NewFakeRunner(t). Expect(`git diff --submodule --no-ext-diff --unified=3 --no-renames --color=always 1234567890 0987654321 -- "test.txt"`, expectedResult, nil), }, { - testName: "Show diff with custom context size", - from: "1234567890", - to: "0987654321", - reverse: false, - plain: false, - contextSize: 123, + testName: "Show diff with custom context size", + from: "1234567890", + to: "0987654321", + reverse: false, + plain: false, + ignoreWhitespace: false, + contextSize: 123, runner: oscommands.NewFakeRunner(t). Expect(`git diff --submodule --no-ext-diff --unified=123 --no-renames --color=always 1234567890 0987654321 -- "test.txt"`, expectedResult, nil), }, + { + testName: "Default case (ignore whitespace)", + from: "1234567890", + to: "0987654321", + reverse: false, + plain: false, + ignoreWhitespace: true, + contextSize: 3, + runner: oscommands.NewFakeRunner(t). + Expect(`git diff --submodule --no-ext-diff --unified=3 --no-renames --color=always 1234567890 0987654321 --ignore-all-space -- "test.txt"`, expectedResult, nil), + }, } for _, s := range scenarios { @@ -365,7 +379,7 @@ func TestWorkingTreeShowFileDiff(t *testing.T) { instance := buildWorkingTreeCommands(commonDeps{runner: s.runner, userConfig: userConfig}) - result, err := instance.ShowFileDiff(s.from, s.to, s.reverse, "test.txt", s.plain) + result, err := instance.ShowFileDiff(s.from, s.to, s.reverse, "test.txt", s.plain, s.ignoreWhitespace) assert.NoError(t, err) assert.Equal(t, expectedResult, result) s.runner.CheckForMissingCalls() diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go index 0849ab310..d88b95495 100644 --- a/pkg/gui/commit_files_panel.go +++ b/pkg/gui/commit_files_panel.go @@ -15,7 +15,8 @@ func (gui *Gui) commitFilesRenderToMain() error { to := ref.RefName() from, reverse := gui.State.Modes.Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName()) - cmdObj := gui.git.WorkingTree.ShowFileDiffCmdObj(from, to, reverse, node.GetPath(), false) + cmdObj := gui.git.WorkingTree.ShowFileDiffCmdObj(from, to, reverse, node.GetPath(), false, + gui.IgnoreWhitespaceInDiffView) task := types.NewRunPtyTask(cmdObj.GetCmd()) pair := gui.c.MainViewPairs().Normal diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index 19434b9fb..2b297c90d 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -35,7 +35,8 @@ func (gui *Gui) branchCommitsRenderToMain() error { if commit == nil { task = types.NewRenderStringTask(gui.c.Tr.NoCommitsThisBranch) } else { - cmdObj := gui.git.Commit.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath()) + cmdObj := gui.git.Commit.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath(), + gui.IgnoreWhitespaceInDiffView) task = types.NewRunPtyTask(cmdObj.GetCmd()) } diff --git a/pkg/gui/diffing.go b/pkg/gui/diffing.go index f5fbde2a2..def73d2f1 100644 --- a/pkg/gui/diffing.go +++ b/pkg/gui/diffing.go @@ -95,6 +95,10 @@ func (gui *Gui) diffStr() string { output += " -R" } + if gui.IgnoreWhitespaceInDiffView { + output += " --ignore-all-space" + } + file := gui.currentlySelectedFilename() if file != "" { output += " -- " + file diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 383b52b32..ce935b661 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -356,7 +356,7 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi Description: self.c.Tr.LcCopySubmoduleNameToClipboard, }, { - ViewName: "files", + ViewName: "", Key: opts.GetKey(opts.Config.Universal.ToggleWhitespaceInDiffView), Handler: self.toggleWhitespaceInDiffView, Description: self.c.Tr.ToggleWhitespaceInDiffView, diff --git a/pkg/gui/reflog_panel.go b/pkg/gui/reflog_panel.go index cb84177da..6c5d0a68c 100644 --- a/pkg/gui/reflog_panel.go +++ b/pkg/gui/reflog_panel.go @@ -8,7 +8,8 @@ func (gui *Gui) reflogCommitsRenderToMain() error { if commit == nil { task = types.NewRenderStringTask("No reflog history") } else { - cmdObj := gui.git.Commit.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath()) + cmdObj := gui.git.Commit.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath(), + gui.IgnoreWhitespaceInDiffView) task = types.NewRunPtyTask(cmdObj.GetCmd()) } diff --git a/pkg/gui/refresh.go b/pkg/gui/refresh.go index 80a680582..d164e28aa 100644 --- a/pkg/gui/refresh.go +++ b/pkg/gui/refresh.go @@ -658,7 +658,8 @@ func (gui *Gui) refreshPatchBuildingPanel(opts types.OnFocusOpts) error { ref := gui.State.Contexts.CommitFiles.CommitFileTreeViewModel.GetRef() to := ref.RefName() from, reverse := gui.State.Modes.Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName()) - diff, err := gui.git.WorkingTree.ShowFileDiff(from, to, reverse, path, true) + diff, err := gui.git.WorkingTree.ShowFileDiff(from, to, reverse, path, true, + gui.IgnoreWhitespaceInDiffView) if err != nil { return err } diff --git a/pkg/gui/sub_commits_panel.go b/pkg/gui/sub_commits_panel.go index ae3f4e905..f68678008 100644 --- a/pkg/gui/sub_commits_panel.go +++ b/pkg/gui/sub_commits_panel.go @@ -10,7 +10,8 @@ func (gui *Gui) subCommitsRenderToMain() error { if commit == nil { task = types.NewRenderStringTask("No commits") } else { - cmdObj := gui.git.Commit.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath()) + cmdObj := gui.git.Commit.ShowCmdObj(commit.Sha, gui.State.Modes.Filtering.GetPath(), + gui.IgnoreWhitespaceInDiffView) task = types.NewRunPtyTask(cmdObj.GetCmd()) } diff --git a/pkg/gui/whitespace-toggle.go b/pkg/gui/whitespace-toggle.go index ad82bc036..b4ee798cc 100644 --- a/pkg/gui/whitespace-toggle.go +++ b/pkg/gui/whitespace-toggle.go @@ -1,5 +1,9 @@ package gui +import ( + "github.com/jesseduffield/lazygit/pkg/gui/types" +) + func (gui *Gui) toggleWhitespaceInDiffView() error { gui.IgnoreWhitespaceInDiffView = !gui.IgnoreWhitespaceInDiffView @@ -9,5 +13,5 @@ func (gui *Gui) toggleWhitespaceInDiffView() error { } gui.c.Toast(toastMessage) - return gui.refreshFilesAndSubmodules() + return gui.currentSideListContext().HandleFocus(types.OnFocusOpts{}) } diff --git a/pkg/integration/tests/diff/ignore_whitespace.go b/pkg/integration/tests/diff/ignore_whitespace.go new file mode 100644 index 000000000..e4c01963f --- /dev/null +++ b/pkg/integration/tests/diff/ignore_whitespace.go @@ -0,0 +1,33 @@ +package diff + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var IgnoreWhitespace = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "View diff with and without ignoring whitespace", + ExtraCmdArgs: "", + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.CreateFileAndAdd("file1", "first line\nsecond line\n") + shell.Commit("first commit") + // First line has a real change, second line changes only indentation: + shell.UpdateFileAndAdd("file1", "first line changed\n second line\n") + shell.Commit("second commit") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + Tap(func() { + // By default, both changes are shown in the diff: + t.Views().Main().Content(Contains("-first line\n-second line\n+first line changed\n+ second line\n")) + }). + Press(keys.Universal.ToggleWhitespaceInDiffView). + Tap(func() { + // After enabling ignore whitespace, only the real change remains: + t.Views().Main().Content(Contains("-first line\n+first line changed\n")) + }) + }, +}) diff --git a/pkg/integration/tests/tests.go b/pkg/integration/tests/tests.go index 59df0ef65..af3ef4050 100644 --- a/pkg/integration/tests/tests.go +++ b/pkg/integration/tests/tests.go @@ -68,6 +68,7 @@ var tests = []*components.IntegrationTest{ diff.Diff, diff.DiffAndApplyPatch, diff.DiffCommits, + diff.IgnoreWhitespace, sync.FetchPrune, sync.RenameBranchAndPull, filter_by_path.CliArg,