From ab14e818be648bf3de05b50d5720559308ffe649 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 28 Jul 2025 14:14:11 +0800 Subject: [PATCH] refactor: simplify the invocation of external merge/diff tool Signed-off-by: leo --- src/Commands/DiffTool.cs | 25 +++----- src/Commands/MergeTool.cs | 26 +++----- src/Models/ExternalMerger.cs | 100 ++++++++++++++---------------- src/Models/ExternalTool.cs | 10 +-- src/Native/OS.cs | 39 ++++++++++++ src/ViewModels/CommitDetail.cs | 5 +- src/ViewModels/DiffContext.cs | 4 +- src/ViewModels/Preferences.cs | 33 +++++----- src/ViewModels/RevisionCompare.cs | 4 +- src/ViewModels/StashesPage.cs | 4 +- src/ViewModels/WorkingCopy.cs | 10 +-- src/Views/BranchCompare.axaml.cs | 7 +-- src/Views/Preferences.axaml.cs | 2 +- 13 files changed, 133 insertions(+), 136 deletions(-) diff --git a/src/Commands/DiffTool.cs b/src/Commands/DiffTool.cs index b80f5595..6fbb2c24 100644 --- a/src/Commands/DiffTool.cs +++ b/src/Commands/DiffTool.cs @@ -1,47 +1,36 @@ -using System.IO; - -namespace SourceGit.Commands +namespace SourceGit.Commands { public class DiffTool : Command { - public DiffTool(string repo, int type, string exec, Models.DiffOption option) + public DiffTool(string repo, Models.DiffOption option) { WorkingDirectory = repo; Context = repo; - - _merger = Models.ExternalMerger.Supported.Find(x => x.Type == type); - _exec = exec; _option = option; } public void Open() { - if (_merger == null) + var tool = Native.OS.GetDiffMergeTool(true); + if (tool == null) { App.RaiseException(Context, "Invalid merge tool in preference setting!"); return; } - if (_merger.Type == 0) + if (string.IsNullOrEmpty(tool.Cmd)) { Args = $"difftool -g --no-prompt {_option}"; } - else if (File.Exists(_exec)) - { - var cmd = $"{_exec.Quoted()} {_merger.DiffCmd}"; - Args = $"-c difftool.sourcegit.cmd={cmd.Quoted()} difftool --tool=sourcegit --no-prompt {_option}"; - } else { - App.RaiseException(Context, $"Can NOT find external diff tool in '{_exec}'!"); - return; + var cmd = $"{tool.Exec.Quoted()} {tool.Cmd}"; + Args = $"-c difftool.sourcegit.cmd={cmd.Quoted()} difftool --tool=sourcegit --no-prompt {_option}"; } Exec(); } - private Models.ExternalMerger _merger; - private string _exec; private Models.DiffOption _option; } } diff --git a/src/Commands/MergeTool.cs b/src/Commands/MergeTool.cs index c2262c69..e3da590d 100644 --- a/src/Commands/MergeTool.cs +++ b/src/Commands/MergeTool.cs @@ -1,48 +1,38 @@ -using System.IO; -using System.Threading.Tasks; +using System.Threading.Tasks; namespace SourceGit.Commands { public class MergeTool : Command { - public MergeTool(string repo, int type, string exec, string file) + public MergeTool(string repo, string file) { WorkingDirectory = repo; - Context = exec; - - _merger = Models.ExternalMerger.Supported.Find(x => x.Type == type); - _exec = exec; + Context = repo; _file = string.IsNullOrEmpty(file) ? string.Empty : file.Quoted(); } public async Task OpenAsync() { - if (_merger == null) + var tool = Native.OS.GetDiffMergeTool(false); + if (tool == null) { App.RaiseException(Context, "Invalid merge tool in preference setting!"); return false; } - if (_merger.Type == 0) + if (string.IsNullOrEmpty(tool.Cmd)) { Args = $"mergetool {_file}"; } - else if (File.Exists(_exec)) - { - var cmd = $"{_exec.Quoted()} {_merger.Cmd}"; - Args = $"-c mergetool.sourcegit.cmd={cmd.Quoted()} -c mergetool.writeToTemp=true -c mergetool.keepBackup=false -c mergetool.trustExitCode=true mergetool --tool=sourcegit {_file}"; - } else { - App.RaiseException(Context, $"Can NOT find external merge tool in '{_exec}'!"); - return false; + var cmd = $"{tool.Exec.Quoted()} {tool.Cmd}"; + Args = $"-c mergetool.sourcegit.cmd={cmd.Quoted()} -c mergetool.writeToTemp=true -c mergetool.keepBackup=false -c mergetool.trustExitCode=true mergetool --tool=sourcegit {_file}"; } return await ExecAsync().ConfigureAwait(false); } - private Models.ExternalMerger _merger; - private string _exec; private string _file; } } diff --git a/src/Models/ExternalMerger.cs b/src/Models/ExternalMerger.cs index ed9b9b08..ce90a7d4 100644 --- a/src/Models/ExternalMerger.cs +++ b/src/Models/ExternalMerger.cs @@ -7,14 +7,13 @@ using Avalonia.Platform; namespace SourceGit.Models { - public class ExternalMerger + public class ExternalMerger(string icon, string name, string finder, string mergeCmd, string diffCmd) { - public int Type { get; set; } - public string Icon { get; set; } - public string Name { get; set; } - public string Exec { get; set; } - public string Cmd { get; set; } - public string DiffCmd { get; set; } + public string Icon { get; } = icon; + public string Name { get; } = name; + public string Finder { get; } = finder; + public string MergeCmd { get; } = mergeCmd; + public string DiffCmd { get; } = diffCmd; public Bitmap IconImage { @@ -32,74 +31,69 @@ namespace SourceGit.Models if (OperatingSystem.IsWindows()) { Supported = new List() { - new ExternalMerger(0, "git", "Use Git Settings", "", "", ""), - new ExternalMerger(1, "vscode", "Visual Studio Code", "Code.exe", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(2, "vscode_insiders", "Visual Studio Code - Insiders", "Code - Insiders.exe", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(3, "vs", "Visual Studio", "vsDiffMerge.exe", "\"$REMOTE\" \"$LOCAL\" \"$BASE\" \"$MERGED\" /m", "\"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(4, "tortoise_merge", "Tortoise Merge", "TortoiseMerge.exe;TortoiseGitMerge.exe", "-base:\"$BASE\" -theirs:\"$REMOTE\" -mine:\"$LOCAL\" -merged:\"$MERGED\"", "-base:\"$LOCAL\" -theirs:\"$REMOTE\""), - new ExternalMerger(5, "kdiff3", "KDiff3", "kdiff3.exe", "\"$REMOTE\" -b \"$BASE\" \"$LOCAL\" -o \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(6, "beyond_compare", "Beyond Compare", "BComp.exe", "\"$REMOTE\" \"$LOCAL\" \"$BASE\" \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(7, "win_merge", "WinMerge", "WinMergeU.exe", "\"$MERGED\"", "-u -e -sw \"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(8, "codium", "VSCodium", "VSCodium.exe", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(9, "p4merge", "P4Merge", "p4merge.exe", "-tw 4 \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"", "-tw 4 \"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(10, "plastic_merge", "Plastic SCM", "mergetool.exe", "-s=\"$REMOTE\" -b=\"$BASE\" -d=\"$LOCAL\" -r=\"$MERGED\" --automatic", "-s=\"$LOCAL\" -d=\"$REMOTE\""), - new ExternalMerger(11, "meld", "Meld", "Meld.exe", "\"$LOCAL\" \"$BASE\" \"$REMOTE\" --output \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(12, "cursor", "Cursor", "Cursor.exe", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("git", "Use Git Settings", "", "", ""), + new ExternalMerger("vscode", "Visual Studio Code", "Code.exe", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("vscode_insiders", "Visual Studio Code - Insiders", "Code - Insiders.exe", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("vs", "Visual Studio", "vsDiffMerge.exe", "\"$REMOTE\" \"$LOCAL\" \"$BASE\" \"$MERGED\" /m", "\"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("tortoise_merge", "Tortoise Merge", "TortoiseMerge.exe;TortoiseGitMerge.exe", "-base:\"$BASE\" -theirs:\"$REMOTE\" -mine:\"$LOCAL\" -merged:\"$MERGED\"", "-base:\"$LOCAL\" -theirs:\"$REMOTE\""), + new ExternalMerger("kdiff3", "KDiff3", "kdiff3.exe", "\"$REMOTE\" -b \"$BASE\" \"$LOCAL\" -o \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("beyond_compare", "Beyond Compare", "BComp.exe", "\"$REMOTE\" \"$LOCAL\" \"$BASE\" \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("win_merge", "WinMerge", "WinMergeU.exe", "\"$MERGED\"", "-u -e -sw \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("codium", "VSCodium", "VSCodium.exe", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("p4merge", "P4Merge", "p4merge.exe", "-tw 4 \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"", "-tw 4 \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("plastic_merge", "Plastic SCM", "mergetool.exe", "-s=\"$REMOTE\" -b=\"$BASE\" -d=\"$LOCAL\" -r=\"$MERGED\" --automatic", "-s=\"$LOCAL\" -d=\"$REMOTE\""), + new ExternalMerger("meld", "Meld", "Meld.exe", "\"$LOCAL\" \"$BASE\" \"$REMOTE\" --output \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("cursor", "Cursor", "Cursor.exe", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), }; } else if (OperatingSystem.IsMacOS()) { Supported = new List() { - new ExternalMerger(0, "git", "Use Git Settings", "", "", ""), - new ExternalMerger(1, "xcode", "FileMerge", "/usr/bin/opendiff", "\"$BASE\" \"$LOCAL\" \"$REMOTE\" -ancestor \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(2, "vscode", "Visual Studio Code", "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(3, "vscode_insiders", "Visual Studio Code - Insiders", "/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(4, "kdiff3", "KDiff3", "/Applications/kdiff3.app/Contents/MacOS/kdiff3", "\"$REMOTE\" -b \"$BASE\" \"$LOCAL\" -o \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(5, "beyond_compare", "Beyond Compare", "/Applications/Beyond Compare.app/Contents/MacOS/bcomp", "\"$REMOTE\" \"$LOCAL\" \"$BASE\" \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(6, "codium", "VSCodium", "/Applications/VSCodium.app/Contents/Resources/app/bin/codium", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(7, "p4merge", "P4Merge", "/Applications/p4merge.app/Contents/Resources/launchp4merge", "-tw 4 \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"", "-tw 4 \"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(8, "cursor", "Cursor", "/Applications/Cursor.app/Contents/Resources/app/bin/cursor", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("git", "Use Git Settings", "", "", ""), + new ExternalMerger("xcode", "FileMerge", "/usr/bin/opendiff", "\"$BASE\" \"$LOCAL\" \"$REMOTE\" -ancestor \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("vscode", "Visual Studio Code", "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("vscode_insiders", "Visual Studio Code - Insiders", "/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("kdiff3", "KDiff3", "/Applications/kdiff3.app/Contents/MacOS/kdiff3", "\"$REMOTE\" -b \"$BASE\" \"$LOCAL\" -o \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("beyond_compare", "Beyond Compare", "/Applications/Beyond Compare.app/Contents/MacOS/bcomp", "\"$REMOTE\" \"$LOCAL\" \"$BASE\" \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("codium", "VSCodium", "/Applications/VSCodium.app/Contents/Resources/app/bin/codium", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("p4merge", "P4Merge", "/Applications/p4merge.app/Contents/Resources/launchp4merge", "-tw 4 \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"", "-tw 4 \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("cursor", "Cursor", "/Applications/Cursor.app/Contents/Resources/app/bin/cursor", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), }; } else if (OperatingSystem.IsLinux()) { Supported = new List() { - new ExternalMerger(0, "git", "Use Git Settings", "", "", ""), - new ExternalMerger(1, "vscode", "Visual Studio Code", "/usr/share/code/code", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(2, "vscode_insiders", "Visual Studio Code - Insiders", "/usr/share/code-insiders/code-insiders", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(3, "kdiff3", "KDiff3", "/usr/bin/kdiff3", "\"$REMOTE\" -b \"$BASE\" \"$LOCAL\" -o \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(4, "beyond_compare", "Beyond Compare", "/usr/bin/bcomp", "\"$REMOTE\" \"$LOCAL\" \"$BASE\" \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(5, "meld", "Meld", "/usr/bin/meld", "\"$LOCAL\" \"$BASE\" \"$REMOTE\" --output \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(6, "codium", "VSCodium", "/usr/share/codium/bin/codium", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(7, "p4merge", "P4Merge", "/usr/local/bin/p4merge", "-tw 4 \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"", "-tw 4 \"$LOCAL\" \"$REMOTE\""), - new ExternalMerger(8, "cursor", "Cursor", "cursor", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("git", "Use Git Settings", "", "", ""), + new ExternalMerger("vscode", "Visual Studio Code", "/usr/share/code/code", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("vscode_insiders", "Visual Studio Code - Insiders", "/usr/share/code-insiders/code-insiders", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("kdiff3", "KDiff3", "/usr/bin/kdiff3", "\"$REMOTE\" -b \"$BASE\" \"$LOCAL\" -o \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("beyond_compare", "Beyond Compare", "/usr/bin/bcomp", "\"$REMOTE\" \"$LOCAL\" \"$BASE\" \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("meld", "Meld", "/usr/bin/meld", "\"$LOCAL\" \"$BASE\" \"$REMOTE\" --output \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("codium", "VSCodium", "/usr/share/codium/bin/codium", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("p4merge", "P4Merge", "/usr/local/bin/p4merge", "-tw 4 \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"", "-tw 4 \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger("cursor", "Cursor", "cursor", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), }; } else { Supported = new List() { - new ExternalMerger(0, "git", "Use Git Settings", "", "", ""), + new ExternalMerger("git", "Use Git Settings", "", "", ""), }; } } - public ExternalMerger(int type, string icon, string name, string exec, string cmd, string diffCmd) - { - Type = type; - Icon = icon; - Name = name; - Exec = exec; - Cmd = cmd; - DiffCmd = diffCmd; - } - - public string[] GetPatterns() + public string[] GetPatternsToFindExecFile() { if (OperatingSystem.IsWindows()) - return Exec.Split(';'); + return Finder.Split(';', StringSplitOptions.RemoveEmptyEntries); - var choices = Exec.Split(';', StringSplitOptions.RemoveEmptyEntries); - return Array.ConvertAll(choices, Path.GetFileName); + return [Path.GetFileName(Finder)]; } } + + public class DiffMergeTool(string exec, string cmd) + { + public string Exec { get; } = exec; + public string Cmd { get; } = cmd; + } } diff --git a/src/Models/ExternalTool.cs b/src/Models/ExternalTool.cs index 377eba2f..f453c08f 100644 --- a/src/Models/ExternalTool.cs +++ b/src/Models/ExternalTool.cs @@ -12,13 +12,14 @@ namespace SourceGit.Models { public class ExternalTool { - public string Name { get; private set; } - public Bitmap IconImage { get; private set; } = null; + public string Name { get; } + public string ExecFile { get; } + public Bitmap IconImage { get; } public ExternalTool(string name, string icon, string execFile, Func execArgsGenerator = null) { Name = name; - _execFile = execFile; + ExecFile = execFile; _execArgsGenerator = execArgsGenerator ?? (repo => repo.Quoted()); try @@ -38,13 +39,12 @@ namespace SourceGit.Models Process.Start(new ProcessStartInfo() { WorkingDirectory = repo, - FileName = _execFile, + FileName = ExecFile, Arguments = _execArgsGenerator.Invoke(repo), UseShellExecute = false, }); } - private string _execFile = string.Empty; private Func _execArgsGenerator = null; } diff --git a/src/Native/OS.cs b/src/Native/OS.cs index df72aff8..f991bca7 100644 --- a/src/Native/OS.cs +++ b/src/Native/OS.cs @@ -76,6 +76,18 @@ namespace SourceGit.Native set; } = []; + public static int ExternalMergerType + { + get; + set; + } = 0; + + public static string ExternalMergerExecFile + { + get; + set; + } = string.Empty; + public static bool UseSystemWindowFrame { get => OperatingSystem.IsLinux() && _enableSystemWindowFrame; @@ -158,6 +170,33 @@ namespace SourceGit.Native ShellOrTerminal = _backend.FindTerminal(shell); } + public static Models.DiffMergeTool GetDiffMergeTool(bool onlyDiff) + { + if (ExternalMergerType < 0 || ExternalMergerType >= Models.ExternalMerger.Supported.Count) + return null; + + if (ExternalMergerType != 0 && (string.IsNullOrEmpty(ExternalMergerExecFile) || !File.Exists(ExternalMergerExecFile))) + return null; + + var tool = Models.ExternalMerger.Supported[ExternalMergerType]; + return new Models.DiffMergeTool(ExternalMergerExecFile, onlyDiff ? tool.DiffCmd : tool.MergeCmd); + } + + public static void AutoSelectExternalMergeToolExecFile() + { + if (ExternalMergerType >= 0 && ExternalMergerType < Models.ExternalMerger.Supported.Count) + { + var merger = Models.ExternalMerger.Supported[ExternalMergerType]; + var externalTool = ExternalTools.Find(x => x.Name.Equals(merger.Name, StringComparison.Ordinal)); + if (externalTool != null) + ExternalMergerExecFile = externalTool.ExecFile; + else if (!OperatingSystem.IsWindows() && File.Exists(merger.Finder)) + ExternalMergerExecFile = merger.Finder; + else + ExternalMergerExecFile = string.Empty; + } + } + public static void OpenInFileManager(string path, bool select = false) { _backend.OpenInFileManager(path, select); diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index fbf0d4aa..14ccc77b 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -207,10 +207,7 @@ namespace SourceGit.ViewModels public void OpenChangeInMergeTool(Models.Change c) { - var toolType = Preferences.Instance.ExternalMergeToolType; - var toolPath = Preferences.Instance.ExternalMergeToolPath; - var opt = new Models.DiffOption(_commit, c); - new Commands.DiffTool(_repo.FullPath, toolType, toolPath, opt).Open(); + new Commands.DiffTool(_repo.FullPath, new Models.DiffOption(_commit, c)).Open(); } public async Task SaveChangesAsPatchAsync(List changes, string saveTo) diff --git a/src/ViewModels/DiffContext.cs b/src/ViewModels/DiffContext.cs index 025ceddd..e5ee18ca 100644 --- a/src/ViewModels/DiffContext.cs +++ b/src/ViewModels/DiffContext.cs @@ -95,9 +95,7 @@ namespace SourceGit.ViewModels public void OpenExternalMergeTool() { - var toolType = Preferences.Instance.ExternalMergeToolType; - var toolPath = Preferences.Instance.ExternalMergeToolPath; - new Commands.DiffTool(_repo, toolType, toolPath, _option).Open(); + new Commands.DiffTool(_repo, _option).Open(); } private void LoadDiffContent() diff --git a/src/ViewModels/Preferences.cs b/src/ViewModels/Preferences.cs index 05be0601..1a836426 100644 --- a/src/ViewModels/Preferences.cs +++ b/src/ViewModels/Preferences.cs @@ -356,25 +356,34 @@ namespace SourceGit.ViewModels public int ExternalMergeToolType { - get => _externalMergeToolType; + get => Native.OS.ExternalMergerType; set { - var changed = SetProperty(ref _externalMergeToolType, value); - if (changed && !OperatingSystem.IsWindows() && value > 0 && value < Models.ExternalMerger.Supported.Count) + if (Native.OS.ExternalMergerType != value) { - var tool = Models.ExternalMerger.Supported[value]; - if (File.Exists(tool.Exec)) - ExternalMergeToolPath = tool.Exec; - else - ExternalMergeToolPath = string.Empty; + Native.OS.ExternalMergerType = value; + OnPropertyChanged(); + + if (!_isLoading) + { + Native.OS.AutoSelectExternalMergeToolExecFile(); + OnPropertyChanged(nameof(ExternalMergeToolPath)); + } } } } public string ExternalMergeToolPath { - get => _externalMergeToolPath; - set => SetProperty(ref _externalMergeToolPath, value); + get => Native.OS.ExternalMergerExecFile; + set + { + if (!Native.OS.ExternalMergerExecFile.Equals(value, StringComparison.Ordinal)) + { + Native.OS.ExternalMergerExecFile = value; + OnPropertyChanged(); + } + } } public uint StatisticsSampleColor @@ -716,11 +725,7 @@ namespace SourceGit.ViewModels private Models.ChangeViewMode _stashChangeViewMode = Models.ChangeViewMode.List; private string _gitDefaultCloneDir = string.Empty; - private int _shellOrTerminal = -1; - private int _externalMergeToolType = 0; - private string _externalMergeToolPath = string.Empty; - private uint _statisticsSampleColor = 0xFF00FF00; } } diff --git a/src/ViewModels/RevisionCompare.cs b/src/ViewModels/RevisionCompare.cs index 1d4350a1..1634a454 100644 --- a/src/ViewModels/RevisionCompare.cs +++ b/src/ViewModels/RevisionCompare.cs @@ -100,9 +100,7 @@ namespace SourceGit.ViewModels public void OpenChangeWithExternalDiffTool(Models.Change change) { var opt = new Models.DiffOption(GetSHA(_startPoint), GetSHA(_endPoint), change); - var toolType = Preferences.Instance.ExternalMergeToolType; - var toolPath = Preferences.Instance.ExternalMergeToolPath; - new Commands.DiffTool(_repo, toolType, toolPath, opt).Open(); + new Commands.DiffTool(_repo, opt).Open(); } public void NavigateTo(string commitSHA) diff --git a/src/ViewModels/StashesPage.cs b/src/ViewModels/StashesPage.cs index 53c699e1..6dde16bf 100644 --- a/src/ViewModels/StashesPage.cs +++ b/src/ViewModels/StashesPage.cs @@ -193,9 +193,7 @@ namespace SourceGit.ViewModels else opt = new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, change); - var toolType = Preferences.Instance.ExternalMergeToolType; - var toolPath = Preferences.Instance.ExternalMergeToolPath; - new Commands.DiffTool(_repo.FullPath, toolType, toolPath, opt).Open(); + new Commands.DiffTool(_repo.FullPath, opt).Open(); } public async Task CheckoutSingleFileAsync(Models.Change change) diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 28a2a78f..f784c811 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -531,18 +531,12 @@ namespace SourceGit.ViewModels public async Task UseExternalMergeToolAsync(Models.Change change) { - var toolType = Preferences.Instance.ExternalMergeToolType; - var toolPath = Preferences.Instance.ExternalMergeToolPath; - var file = change?.Path; - return await new Commands.MergeTool(_repo.FullPath, toolType, toolPath, file).OpenAsync(); + return await new Commands.MergeTool(_repo.FullPath, change?.Path).OpenAsync(); } public void UseExternalDiffTool(Models.Change change, bool isUnstaged) { - var toolType = Preferences.Instance.ExternalMergeToolType; - var toolPath = Preferences.Instance.ExternalMergeToolPath; - var opt = new Models.DiffOption(change, isUnstaged); - new Commands.DiffTool(_repo.FullPath, toolType, toolPath, opt).Open(); + new Commands.DiffTool(_repo.FullPath, new Models.DiffOption(change, isUnstaged)).Open(); } public async Task ContinueMergeAsync() diff --git a/src/Views/BranchCompare.axaml.cs b/src/Views/BranchCompare.axaml.cs index 5a614311..dbd014c8 100644 --- a/src/Views/BranchCompare.axaml.cs +++ b/src/Views/BranchCompare.axaml.cs @@ -28,12 +28,7 @@ namespace SourceGit.Views openWithMerger.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+D" : "Ctrl+Shift+D"; openWithMerger.Click += (_, ev) => { - var pref = ViewModels.Preferences.Instance; - var toolType = pref.ExternalMergeToolType; - var toolPath = pref.ExternalMergeToolPath; - var opt = new Models.DiffOption(vm.Base.Head, vm.To.Head, change); - - new Commands.DiffTool(repo, toolType, toolPath, opt).Open(); + new Commands.DiffTool(repo, new Models.DiffOption(vm.Base.Head, vm.To.Head, change)).Open(); ev.Handled = true; }; menu.Items.Add(openWithMerger); diff --git a/src/Views/Preferences.axaml.cs b/src/Views/Preferences.axaml.cs index a6b4b722..ca980072 100644 --- a/src/Views/Preferences.axaml.cs +++ b/src/Views/Preferences.axaml.cs @@ -349,7 +349,7 @@ namespace SourceGit.Views var tool = Models.ExternalMerger.Supported[type]; var options = new FilePickerOpenOptions() { - FileTypeFilter = [new FilePickerFileType(tool.Name) { Patterns = tool.GetPatterns() }], + FileTypeFilter = [new FilePickerFileType(tool.Name) { Patterns = tool.GetPatternsToFindExecFile() }], AllowMultiple = false, };