diff --git a/src/Commands/GenerateCommitMessage.cs b/src/Commands/GenerateCommitMessage.cs index b5c978d3..e71fb0b9 100644 --- a/src/Commands/GenerateCommitMessage.cs +++ b/src/Commands/GenerateCommitMessage.cs @@ -108,7 +108,7 @@ namespace SourceGit.Commands if (rsp != null && rsp.Choices.Count > 0) return rsp.Choices[0].Message.Content; - return string.Empty; + return string.Empty; } private string _repo; diff --git a/src/Models/OpenAI.cs b/src/Models/OpenAI.cs index 192459c7..2619f299 100644 --- a/src/Models/OpenAI.cs +++ b/src/Models/OpenAI.cs @@ -123,7 +123,7 @@ namespace SourceGit.Models reader.Wait(); return JsonSerializer.Deserialize(reader.Result, JsonCodeGen.Default.OpenAIChatResponse); - } + } catch { if (cancellation.IsCancellationRequested) diff --git a/src/Models/Shell.cs b/src/Models/Shell.cs deleted file mode 100644 index 9960d136..00000000 --- a/src/Models/Shell.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace SourceGit.Models -{ - public enum Shell - { - Default = 0, - PowerShell, - CommandPrompt, - DefaultShellOfWindowsTerminal, - } -} diff --git a/src/Models/ShellOrTerminal.cs b/src/Models/ShellOrTerminal.cs new file mode 100644 index 00000000..fa3a207b --- /dev/null +++ b/src/Models/ShellOrTerminal.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; + +using Avalonia.Media.Imaging; +using Avalonia.Platform; + +namespace SourceGit.Models +{ + public class ShellOrTerminal + { + public string Type { get; set; } + public string Name { get; set; } + public string Exec { get; set; } + + public Bitmap Icon + { + get + { + var icon = AssetLoader.Open(new Uri($"avares://SourceGit/Resources/Images/ShellIcons/{Type}.png", UriKind.RelativeOrAbsolute)); + return new Bitmap(icon); + } + } + + public static readonly List Supported; + + static ShellOrTerminal() + { + if (OperatingSystem.IsWindows()) + { + Supported = new List() + { + new ShellOrTerminal("git-bash", "Git Bash", "bash.exe"), + new ShellOrTerminal("pwsh", "PowerShell", "pwsh.exe|powershell.exe"), + new ShellOrTerminal("cmd", "Command Prompt", "cmd.exe"), + new ShellOrTerminal("wt", "Windows Terminal", "wt.exe") + }; + } + else if (OperatingSystem.IsMacOS()) + { + Supported = new List() + { + new ShellOrTerminal("mac-terminal", "Terminal", ""), + new ShellOrTerminal("iterm2", "iTerm", ""), + }; + } + else + { + Supported = new List() + { + new ShellOrTerminal("gnome-terminal", "Gnome Terminal", "gnome-terminal"), + new ShellOrTerminal("konsole", "Konsole", "konsole"), + new ShellOrTerminal("xfce4-terminal", "Xfce4 Terminal", "xfce4-terminal"), + new ShellOrTerminal("lxterminal", "LXTerminal", "lxterminal"), + new ShellOrTerminal("deepin-terminal", "Deepin Terminal", "deepin-terminal"), + new ShellOrTerminal("mate-terminal", "MATE Terminal", "mate-terminal"), + new ShellOrTerminal("foot", "Foot", "foot"), + }; + } + } + + public ShellOrTerminal(string type, string name, string exec) + { + Type = type; + Name = name; + Exec = exec; + } + } +} diff --git a/src/Native/Linux.cs b/src/Native/Linux.cs index 1b33cc5d..9537a39a 100644 --- a/src/Native/Linux.cs +++ b/src/Native/Linux.cs @@ -11,29 +11,6 @@ namespace SourceGit.Native [SupportedOSPlatform("linux")] internal class Linux : OS.IBackend { - class Terminal - { - public string FilePath { get; set; } - public string OpenArgFormat { get; set; } - - public Terminal(string exec, string fmt) - { - FilePath = exec; - OpenArgFormat = fmt; - } - - public void Open(string dir) - { - Process.Start(FilePath, string.Format(OpenArgFormat, dir)); - } - } - - public Linux() - { - _xdgOpenPath = FindExecutable("xdg-open"); - _terminal = FindTerminal(); - } - public void SetupApp(AppBuilder builder) { builder.With(new X11PlatformOptions() @@ -47,6 +24,20 @@ namespace SourceGit.Native return FindExecutable("git"); } + public string FindTerminal(Models.ShellOrTerminal shell) + { + var pathVariable = Environment.GetEnvironmentVariable("PATH") ?? string.Empty; + var pathes = pathVariable.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries); + foreach (var path in pathes) + { + var test = Path.Combine(path, shell.Exec); + if (File.Exists(test)) + return test; + } + + return string.Empty; + } + public List FindExternalTools() { var finder = new Models.ExternalToolsFinder(); @@ -61,50 +52,40 @@ namespace SourceGit.Native public void OpenBrowser(string url) { - if (string.IsNullOrEmpty(_xdgOpenPath)) - App.RaiseException("", $"Can NOT find `xdg-open` command!!!"); - else - Process.Start(_xdgOpenPath, $"\"{url}\""); + Process.Start("xdg-open", $"\"{url}\""); } public void OpenInFileManager(string path, bool select) { - if (string.IsNullOrEmpty(_xdgOpenPath)) - { - App.RaiseException("", $"Can NOT find `xdg-open` command!!!"); - return; - } - if (Directory.Exists(path)) { - Process.Start(_xdgOpenPath, $"\"{path}\""); + Process.Start("xdg-open", $"\"{path}\""); } else { var dir = Path.GetDirectoryName(path); if (Directory.Exists(dir)) - Process.Start(_xdgOpenPath, $"\"{dir}\""); + Process.Start("xdg-open", $"\"{dir}\""); } } public void OpenTerminal(string workdir) { - var dir = string.IsNullOrEmpty(workdir) ? "~" : workdir; - if (_terminal == null) - App.RaiseException(dir, $"Only supports gnome-terminal/konsole/xfce4-terminal/lxterminal/deepin-terminal/mate-terminal/foot!"); - else - _terminal.Open(dir); + if (string.IsNullOrEmpty(OS.ShellOrTerminal) || !File.Exists(OS.ShellOrTerminal)) + { + App.RaiseException(workdir, $"Can not found terminal! Please confirm that the correct shell/terminal has been configured."); + return; + } + + var startInfo = new ProcessStartInfo(); + startInfo.WorkingDirectory = string.IsNullOrEmpty(workdir) ? "~" : workdir; + startInfo.FileName = OS.ShellOrTerminal; + Process.Start(startInfo); } public void OpenWithDefaultEditor(string file) { - if (string.IsNullOrEmpty(_xdgOpenPath)) - { - App.RaiseException("", $"Can NOT find `xdg-open` command!!!"); - return; - } - - var proc = Process.Start(_xdgOpenPath, $"\"{file}\""); + var proc = Process.Start("xdg-open", $"\"{file}\""); if (proc != null) { proc.WaitForExit(); @@ -130,51 +111,10 @@ namespace SourceGit.Native return string.Empty; } - private Terminal FindTerminal() - { - var pathVariable = Environment.GetEnvironmentVariable("PATH") ?? string.Empty; - var pathes = pathVariable.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries); - foreach (var path in pathes) - { - var test = Path.Combine(path, "gnome-terminal"); - if (File.Exists(test)) - return new Terminal(test, "--working-directory=\"{0}\""); - - test = Path.Combine(path, "konsole"); - if (File.Exists(test)) - return new Terminal(test, "--workdir \"{0}\""); - - test = Path.Combine(path, "xfce4-terminal"); - if (File.Exists(test)) - return new Terminal(test, "--working-directory=\"{0}\""); - - test = Path.Combine(path, "lxterminal"); - if (File.Exists(test)) - return new Terminal(test, "--working-directory=\"{0}\""); - - test = Path.Combine(path, "deepin-terminal"); - if (File.Exists(test)) - return new Terminal(test, "--work-directory \"{0}\""); - - test = Path.Combine(path, "mate-terminal"); - if (File.Exists(test)) - return new Terminal(test, "--working-directory=\"{0}\""); - - test = Path.Combine(path, "foot"); - if (File.Exists(test)) - return new Terminal(test, "--working-directory=\"{0}\""); - } - - return null; - } - private string FindJetBrainsFleet() { var path = $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}/JetBrains/Toolbox/apps/fleet/bin/Fleet"; return File.Exists(path) ? path : FindExecutable("fleet"); } - - private string _xdgOpenPath = null; - private Terminal _terminal = null; } } diff --git a/src/Native/MacOS.cs b/src/Native/MacOS.cs index f68d7ac5..0ad608b2 100644 --- a/src/Native/MacOS.cs +++ b/src/Native/MacOS.cs @@ -24,6 +24,19 @@ namespace SourceGit.Native return File.Exists("/usr/bin/git") ? "/usr/bin/git" : string.Empty; } + public string FindTerminal(Models.ShellOrTerminal shell) + { + switch (shell.Type) + { + case "mac-terminal": + return "Terminal"; + case "iterm2": + return "iTerm"; + } + + return "InvalidTerminal"; + } + public List FindExternalTools() { var finder = new Models.ExternalToolsFinder(); @@ -53,12 +66,7 @@ namespace SourceGit.Native { var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); var dir = string.IsNullOrEmpty(workdir) ? home : workdir; - - var terminal = "Terminal"; - if (Directory.Exists("/Applications/iTerm.app")) - terminal = "iTerm"; - - Process.Start("open", $"-a {terminal} \"{dir}\""); + Process.Start("open", $"-a {OS.ShellOrTerminal} \"{dir}\""); } public void OpenWithDefaultEditor(string file) diff --git a/src/Native/OS.cs b/src/Native/OS.cs index 0e1b8522..87655798 100644 --- a/src/Native/OS.cs +++ b/src/Native/OS.cs @@ -13,6 +13,7 @@ namespace SourceGit.Native void SetupApp(AppBuilder builder); string FindGitExecutable(); + string FindTerminal(Models.ShellOrTerminal shell); List FindExternalTools(); void OpenTerminal(string workdir); @@ -23,6 +24,7 @@ namespace SourceGit.Native public static string DataDir { get; private set; } = string.Empty; public static string GitExecutable { get; set; } = string.Empty; + public static string ShellOrTerminal { get; set; } = string.Empty; public static List ExternalTools { get; set; } = []; static OS() @@ -45,29 +47,6 @@ namespace SourceGit.Native } } - public static Models.Shell GetShell() - { - if (OperatingSystem.IsWindows()) - return (_backend as Windows)!.Shell; - - return Models.Shell.Default; - } - - public static bool SetShell(Models.Shell shell) - { - if (OperatingSystem.IsWindows()) - { - var windows = (_backend as Windows)!; - if (windows.Shell != shell) - { - windows.Shell = shell; - return true; - } - } - - return false; - } - public static void SetupApp(AppBuilder builder) { _backend.SetupApp(builder); @@ -95,6 +74,14 @@ namespace SourceGit.Native return _backend.FindGitExecutable(); } + public static void SetShellOrTerminal(Models.ShellOrTerminal shellOrTerminal) + { + if (shellOrTerminal == null) + ShellOrTerminal = string.Empty; + else + ShellOrTerminal = _backend.FindTerminal(shellOrTerminal); + } + public static void OpenInFileManager(string path, bool select = false) { _backend.OpenInFileManager(path, select); @@ -107,7 +94,10 @@ namespace SourceGit.Native public static void OpenTerminal(string workdir) { - _backend.OpenTerminal(workdir); + if (string.IsNullOrEmpty(ShellOrTerminal)) + App.RaiseException(workdir, $"Can not found terminal! Please confirm that the correct shell/terminal has been configured."); + else + _backend.OpenTerminal(workdir); } public static void OpenWithDefaultEditor(string file) diff --git a/src/Native/Windows.cs b/src/Native/Windows.cs index 18326fa6..19362d0c 100644 --- a/src/Native/Windows.cs +++ b/src/Native/Windows.cs @@ -53,12 +53,6 @@ namespace SourceGit.Native [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = false)] private static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, int cild, IntPtr apidl, int dwFlags); - public Models.Shell Shell - { - get; - set; - } = Models.Shell.Default; - public void SetupApp(AppBuilder builder) { // Fix drop shadow issue on Windows 10 @@ -98,6 +92,51 @@ namespace SourceGit.Native return null; } + public string FindTerminal(Models.ShellOrTerminal shell) + { + switch (shell.Type) + { + case "git-bash": + if (string.IsNullOrEmpty(OS.GitExecutable)) + break; + + var binDir = Path.GetDirectoryName(OS.GitExecutable)!; + var bash = Path.Combine(binDir, "bash.exe"); + if (!File.Exists(bash)) + break; + + return bash; + case "pwsh": + var localMachine = Microsoft.Win32.RegistryKey.OpenBaseKey( + Microsoft.Win32.RegistryHive.LocalMachine, + Microsoft.Win32.RegistryView.Registry64); + + var pwsh = localMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\pwsh.exe"); + if (pwsh != null) + { + var path = pwsh.GetValue(null) as string; + if (File.Exists(path)) + return path; + } + + var pwshFinder = new StringBuilder("powershell.exe", 512); + if (PathFindOnPath(pwshFinder, null)) + return pwshFinder.ToString(); + + break; + case "cmd": + return "C:\\Windows\\System32\\cmd.exe"; + case "wt": + var wtFinder = new StringBuilder("wt.exe", 512); + if (PathFindOnPath(wtFinder, null)) + return wtFinder.ToString(); + + break; + } + + return string.Empty; + } + public List FindExternalTools() { var finder = new Models.ExternalToolsFinder(); @@ -119,56 +158,15 @@ namespace SourceGit.Native public void OpenTerminal(string workdir) { - if (string.IsNullOrEmpty(workdir) || !Path.Exists(workdir)) + if (string.IsNullOrEmpty(OS.ShellOrTerminal) || !File.Exists(OS.ShellOrTerminal)) { - workdir = "."; + App.RaiseException(workdir, $"Can not found terminal! Please confirm that the correct shell/terminal has been configured."); + return; } var startInfo = new ProcessStartInfo(); startInfo.WorkingDirectory = workdir; - - switch (Shell) - { - case Models.Shell.Default: - if (string.IsNullOrEmpty(OS.GitExecutable)) - { - App.RaiseException(workdir, $"Can NOT found bash.exe"); - return; - } - - var binDir = Path.GetDirectoryName(OS.GitExecutable)!; - var bash = Path.Combine(binDir, "bash.exe"); - if (!File.Exists(bash)) - { - App.RaiseException(workdir, $"Can NOT found bash.exe under '{binDir}'"); - return; - } - - startInfo.FileName = bash; - break; - case Models.Shell.PowerShell: - startInfo.FileName = ChoosePowerShell(); - startInfo.Arguments = startInfo.FileName.EndsWith("pwsh.exe") ? $"-WorkingDirectory \"{workdir}\" -Nologo" : "-Nologo"; - break; - case Models.Shell.CommandPrompt: - startInfo.FileName = "cmd"; - break; - case Models.Shell.DefaultShellOfWindowsTerminal: - var wt = FindWindowsTerminalApp(); - if (!File.Exists(wt)) - { - App.RaiseException(workdir, $"Can NOT found wt.exe on your system!"); - return; - } - - startInfo.FileName = wt; - startInfo.Arguments = $"-d \"{workdir}\""; - break; - default: - App.RaiseException(workdir, $"Bad shell configuration!"); - return; - } - + startInfo.FileName = OS.ShellOrTerminal; Process.Start(startInfo); } @@ -218,52 +216,6 @@ namespace SourceGit.Native DwmExtendFrameIntoClientArea(platformHandle.Handle, ref margins); } - // There are two versions of PowerShell : pwsh.exe (preferred) and powershell.exe (system default) - private string ChoosePowerShell() - { - if (!string.IsNullOrEmpty(_powershellPath)) - return _powershellPath; - - var localMachine = Microsoft.Win32.RegistryKey.OpenBaseKey( - Microsoft.Win32.RegistryHive.LocalMachine, - Microsoft.Win32.RegistryView.Registry64); - - var pwsh = localMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\pwsh.exe"); - if (pwsh != null) - { - var path = pwsh.GetValue(null) as string; - if (File.Exists(path)) - { - _powershellPath = path; - return _powershellPath; - } - } - - var finder = new StringBuilder("powershell.exe", 512); - if (PathFindOnPath(finder, null)) - { - _powershellPath = finder.ToString(); - return _powershellPath; - } - - return string.Empty; - } - - private string FindWindowsTerminalApp() - { - if (!string.IsNullOrEmpty(_wtPath)) - return _wtPath; - - var finder = new StringBuilder("wt.exe", 512); - if (PathFindOnPath(finder, null)) - { - _wtPath = finder.ToString(); - return _wtPath; - } - - return string.Empty; - } - #region EXTERNAL_EDITOR_FINDER private string FindVSCode() { @@ -385,8 +337,5 @@ namespace SourceGit.Native ILFree(pidl); } } - - private string _powershellPath = string.Empty; - private string _wtPath = string.Empty; } } diff --git a/src/Resources/Images/ShellIcons/deepin-terminal.png b/src/Resources/Images/ShellIcons/deepin-terminal.png new file mode 100644 index 00000000..78eef1b4 Binary files /dev/null and b/src/Resources/Images/ShellIcons/deepin-terminal.png differ diff --git a/src/Resources/Images/ShellIcons/foot.png b/src/Resources/Images/ShellIcons/foot.png new file mode 100644 index 00000000..c5dbd0a5 Binary files /dev/null and b/src/Resources/Images/ShellIcons/foot.png differ diff --git a/src/Resources/Images/ShellIcons/gnome-terminal.png b/src/Resources/Images/ShellIcons/gnome-terminal.png new file mode 100644 index 00000000..f9edd2e3 Binary files /dev/null and b/src/Resources/Images/ShellIcons/gnome-terminal.png differ diff --git a/src/Resources/Images/ShellIcons/item2.png b/src/Resources/Images/ShellIcons/item2.png new file mode 100644 index 00000000..16fbd3bd Binary files /dev/null and b/src/Resources/Images/ShellIcons/item2.png differ diff --git a/src/Resources/Images/ShellIcons/konsole.png b/src/Resources/Images/ShellIcons/konsole.png new file mode 100644 index 00000000..e1dbcd49 Binary files /dev/null and b/src/Resources/Images/ShellIcons/konsole.png differ diff --git a/src/Resources/Images/ShellIcons/lxterminal.png b/src/Resources/Images/ShellIcons/lxterminal.png new file mode 100644 index 00000000..99f62683 Binary files /dev/null and b/src/Resources/Images/ShellIcons/lxterminal.png differ diff --git a/src/Resources/Images/ShellIcons/mac-terminal.png b/src/Resources/Images/ShellIcons/mac-terminal.png new file mode 100644 index 00000000..569af756 Binary files /dev/null and b/src/Resources/Images/ShellIcons/mac-terminal.png differ diff --git a/src/Resources/Images/ShellIcons/mate-terminal.png b/src/Resources/Images/ShellIcons/mate-terminal.png new file mode 100644 index 00000000..d48cedfa Binary files /dev/null and b/src/Resources/Images/ShellIcons/mate-terminal.png differ diff --git a/src/Resources/Images/ShellIcons/xfce4-terminal.png b/src/Resources/Images/ShellIcons/xfce4-terminal.png new file mode 100644 index 00000000..9eda3d00 Binary files /dev/null and b/src/Resources/Images/ShellIcons/xfce4-terminal.png differ diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 7095c6db..7d46b44b 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -394,6 +394,10 @@ Design-Anpassungen Fixe Tab-Breite in Titelleiste Verwende nativen Fensterrahmen + DIFF/MERGE TOOL + Installationspfad + Installationspfad zum Diff/Merge Tool + Tool ALLGEMEIN Beim Starten nach Updates suchen Sprache @@ -408,7 +412,6 @@ Benutzer Email Globale Git Benutzer Email Installationspfad - Shell Benutzername Globaler Git Benutzername Git Version @@ -421,10 +424,6 @@ Installationspfad zum GPG Programm Benutzer Signierungsschlüssel GPG Benutzer Signierungsschlüssel - DIFF/MERGE TOOL - Installationspfad - Installationspfad zum Diff/Merge Tool - Tool Remote löschen Ziel: Worktrees löschen diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index c56bb3b5..72a6a8ba 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -399,6 +399,10 @@ Theme Overrides Use fixed tab width in titlebar Use native window frame + DIFF/MERGE TOOL + Install Path + Input path for diff/merge tool + Tool GENERAL Check for updates on startup Language @@ -413,7 +417,6 @@ User Email Global git user email Install Path - Shell User Name Global git user name Git version @@ -426,10 +429,10 @@ Input path for installed gpg program User Signing Key User's gpg signing key - DIFF/MERGE TOOL - Install Path - Input path for diff/merge tool - Tool + INTEGRATION + SHELL/TERMINAL + Shell/Terminal + Path Prune Remote Target: Prune Worktrees diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index 702b5c5a..40df6d99 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -387,6 +387,10 @@ Dérogations de thème Utiliser des onglets de taille fixe dans la barre de titre Utiliser un cadre de fenêtre natif + OUTIL DIFF/MERGE + Chemin d'installation + Saisir le chemin d'installation de l'outil diff/merge + Outil GÉNÉRAL Vérifier les mises à jour au démarrage Language @@ -401,7 +405,6 @@ E-mail utilsateur E-mail utilsateur global Chemin d'installation - Shell Nom d'utilisateur Nom d'utilisateur global Version de Git @@ -414,10 +417,6 @@ Saisir le chemin d'installation vers le programme GPG Clé de signature de l'utilisateur Clé de signature GPG de l'utilisateur - OUTIL DIFF/MERGE - Chemin d'installation - Saisir le chemin d'installation de l'outil diff/merge - Outil Élaguer une branche distant Cible : Élaguer les Worktrees diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index ad3c6ed2..96cdda3e 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -381,6 +381,10 @@ Tema Sobrescrever Tema Usar largura fixa da aba na barra de título + FERRAMENTA DE DIF/MERGE + Caminho de Instalação + Insira o caminho para a ferramenta de dif/merge + Ferramenta GERAL Verificar atualizações na inicialização Idioma @@ -395,7 +399,6 @@ E-mail do Usuário E-mail global do usuário git Caminho de Instalação - Shell Nome do Usuário Nome global do usuário git Versão do Git @@ -408,10 +411,6 @@ Insira o caminho do programa gpg instalado Chave de Assinatura do Usuário Chave de assinatura gpg do usuário - FERRAMENTA DE DIF/MERGE - Caminho de Instalação - Insira o caminho para a ferramenta de dif/merge - Ferramenta Prunar Remoto Alvo: Podar Worktrees diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index aed1c259..6c8739fe 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -398,6 +398,10 @@ 主题自定义 主标签使用固定宽度 使用系统默认窗体样式 + 对比/合并工具 + 安装路径 + 填写工具可执行文件所在位置 + 工具 通用配置 启动时检测软件更新 显示语言 @@ -412,7 +416,6 @@ 邮箱 默认GIT用户邮箱 安装路径 - 终端Shell 用户名 默认GIT用户名 Git 版本 @@ -425,10 +428,10 @@ 签名程序所在路径 用户签名KEY 输入签名提交所使用的KEY - 对比/合并工具 - 安装路径 - 填写工具可执行文件所在位置 - 工具 + 第三方工具集成 + 终端/SHELL + 终端/SHELL + 安装路径 清理远程已删除分支 目标 : 清理工作树 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 7816b604..5549fe8c 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -398,6 +398,10 @@ 自訂主題 使用固定寬度的分頁標籤 使用系統原生預設視窗樣式 + 對比/合併工具 + 安裝路徑 + 填寫可執行檔案所在路徑 + 工具 一般設定 啟動時檢查軟體更新 顯示語言 @@ -412,7 +416,6 @@ 電子郵件 預設 Git 使用者電子郵件 安裝路徑 - 終端 Shell 使用者名稱 預設 Git 使用者名稱 Git 版本 @@ -425,10 +428,10 @@ 填寫 gpg.exe 所在路徑 使用者簽章金鑰 填寫簽章提交所使用的金鑰 - 對比/合併工具 - 安裝路徑 - 填寫可執行檔案所在路徑 - 工具 + 第三方工具集成 + 終端/SHELL + 終端/SHELL + 安裝路徑 清理遠端已刪除分支 目標: 清理工作區 diff --git a/src/ViewModels/Preference.cs b/src/ViewModels/Preference.cs index a81039af..6887e6c9 100644 --- a/src/ViewModels/Preference.cs +++ b/src/ViewModels/Preference.cs @@ -229,16 +229,6 @@ namespace SourceGit.ViewModels } } - public Models.Shell GitShell - { - get => Native.OS.GetShell(); - set - { - if (Native.OS.SetShell(value)) - OnPropertyChanged(); - } - } - public string GitDefaultCloneDir { get => _gitDefaultCloneDir; @@ -274,6 +264,59 @@ namespace SourceGit.ViewModels } } + public int ShellOrTerminal + { + get => _shellOrTerminal; + set + { + if (SetProperty(ref _shellOrTerminal, value)) + { + if (value >= 0 && value < Models.ShellOrTerminal.Supported.Count) + Native.OS.SetShellOrTerminal(Models.ShellOrTerminal.Supported[value]); + else + Native.OS.SetShellOrTerminal(null); + + OnPropertyChanged(nameof(ShellOrTerminalPath)); + } + } + } + + public string ShellOrTerminalPath + { + get => Native.OS.ShellOrTerminal; + set + { + if (value != Native.OS.ShellOrTerminal) + { + Native.OS.ShellOrTerminal = value; + OnPropertyChanged(); + } + } + } + + public int ExternalMergeToolType + { + get => _externalMergeToolType; + set + { + var changed = SetProperty(ref _externalMergeToolType, value); + if (changed && !OperatingSystem.IsWindows() && value > 0 && value < Models.ExternalMerger.Supported.Count) + { + var tool = Models.ExternalMerger.Supported[value]; + if (File.Exists(tool.Exec)) + ExternalMergeToolPath = tool.Exec; + else + ExternalMergeToolPath = string.Empty; + } + } + } + + public string ExternalMergeToolPath + { + get => _externalMergeToolPath; + set => SetProperty(ref _externalMergeToolPath, value); + } + public string OpenAIServer { get => Models.OpenAI.Server; @@ -313,29 +356,6 @@ namespace SourceGit.ViewModels } } - public int ExternalMergeToolType - { - get => _externalMergeToolType; - set - { - var changed = SetProperty(ref _externalMergeToolType, value); - if (changed && !OperatingSystem.IsWindows() && value > 0 && value < Models.ExternalMerger.Supported.Count) - { - var tool = Models.ExternalMerger.Supported[value]; - if (File.Exists(tool.Exec)) - ExternalMergeToolPath = tool.Exec; - else - ExternalMergeToolPath = string.Empty; - } - } - } - - public string ExternalMergeToolPath - { - get => _externalMergeToolPath; - set => SetProperty(ref _externalMergeToolPath, value); - } - public List RepositoryNodes { get; @@ -560,6 +580,7 @@ namespace SourceGit.ViewModels private string _gitDefaultCloneDir = string.Empty; + private int _shellOrTerminal = -1; private int _externalMergeToolType = 0; private string _externalMergeToolPath = string.Empty; } diff --git a/src/Views/Preference.axaml b/src/Views/Preference.axaml index 2ee1517d..3701e3eb 100644 --- a/src/Views/Preference.axaml +++ b/src/Views/Preference.axaml @@ -194,7 +194,7 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -280,31 +241,31 @@ - - - - - - - - - + - - - - - - - - - - - - - - - - - @@ -449,51 +375,142 @@ - + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Views/Preference.axaml.cs b/src/Views/Preference.axaml.cs index e76fce2f..af70ee8e 100644 --- a/src/Views/Preference.axaml.cs +++ b/src/Views/Preference.axaml.cs @@ -183,7 +183,7 @@ namespace SourceGit.Views e.Handled = true; } - private async void SelectDefaultCloneDir(object _1, RoutedEventArgs _2) + private async void SelectDefaultCloneDir(object _, RoutedEventArgs e) { var options = new FolderPickerOpenOptions() { AllowMultiple = false }; try @@ -194,13 +194,15 @@ namespace SourceGit.Views ViewModels.Preference.Instance.GitDefaultCloneDir = selected[0].Path.LocalPath; } } - catch (Exception e) + catch (Exception ex) { - App.RaiseException(string.Empty, $"Failed to select default clone directory: {e.Message}"); + App.RaiseException(string.Empty, $"Failed to select default clone directory: {ex.Message}"); } + + e.Handled = true; } - private async void SelectGPGExecutable(object _1, RoutedEventArgs _2) + private async void SelectGPGExecutable(object _, RoutedEventArgs e) { var patterns = new List(); if (OperatingSystem.IsWindows()) @@ -219,14 +221,39 @@ namespace SourceGit.Views { GPGExecutableFile = selected[0].Path.LocalPath; } + + e.Handled = true; } - private async void SelectExternalMergeTool(object _1, RoutedEventArgs _2) + private async void SelectShellOrTerminal(object _, RoutedEventArgs e) + { + var type = ViewModels.Preference.Instance.ShellOrTerminal; + if (type == -1) + return; + + var shell = Models.ShellOrTerminal.Supported[type]; + var options = new FilePickerOpenOptions() + { + FileTypeFilter = [new FilePickerFileType(shell.Name) { Patterns = [shell.Exec] }], + AllowMultiple = false, + }; + + var selected = await StorageProvider.OpenFilePickerAsync(options); + if (selected.Count == 1) + { + ViewModels.Preference.Instance.ShellOrTerminalPath = selected[0].Path.LocalPath; + } + + e.Handled = true; + } + + private async void SelectExternalMergeTool(object _, RoutedEventArgs e) { var type = ViewModels.Preference.Instance.ExternalMergeToolType; if (type < 0 || type >= Models.ExternalMerger.Supported.Count) { ViewModels.Preference.Instance.ExternalMergeToolType = 0; + e.Handled = true; return; } @@ -242,6 +269,8 @@ namespace SourceGit.Views { ViewModels.Preference.Instance.ExternalMergeToolPath = selected[0].Path.LocalPath; } + + e.Handled = true; } private void SetIfChanged(Dictionary cached, string key, string value, string defValue) diff --git a/src/Views/WorkingCopy.axaml.cs b/src/Views/WorkingCopy.axaml.cs index 3ce63941..f8e4fa23 100644 --- a/src/Views/WorkingCopy.axaml.cs +++ b/src/Views/WorkingCopy.axaml.cs @@ -142,7 +142,7 @@ namespace SourceGit.Views App.RaiseException(null, "No files added to commit!"); } } - + e.Handled = true; } }