From 0c6af27b40b5c9290c6b3438f3d730c279e743a5 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 15 Aug 2024 11:32:02 +0800 Subject: [PATCH] refactor: rewrite the way to find external editors (#347) * do not find tools from environment variables since it needs a lot of works on some platforms, such as macOS * add `external_editors.json` to allow user configure paths directly --- README.md | 30 +++++++++++++++-------- src/App.JsonCodeGen.cs | 1 + src/Models/ExternalTool.cs | 50 +++++++++++++++++++++++++++++--------- 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 54765165..7dd685ae 100644 --- a/README.md +++ b/README.md @@ -84,17 +84,27 @@ For **Linux** users: This app supports open repository in external tools listed in the table below. -| Tool | Windows | macOS | Linux | Environment Variable | -|-------------------------------|---------|-------|-------|----------------------| -| Visual Studio Code | YES | YES | YES | VSCODE_PATH | -| Visual Studio Code - Insiders | YES | YES | YES | VSCODE_INSIDERS_PATH | -| VSCodium | YES | YES | YES | VSCODIUM_PATH | -| JetBrains Fleet | YES | YES | YES | FLEET_PATH | -| Sublime Text | YES | YES | YES | SUBLIME_TEXT_PATH | +| Tool | Windows | macOS | Linux | KEY IN `external_editors.json` | +|-------------------------------|---------|-------|-------|--------------------------------| +| Visual Studio Code | YES | YES | YES | VSCODE | +| Visual Studio Code - Insiders | YES | YES | YES | VSCODE_INSIDERS | +| VSCodium | YES | YES | YES | VSCODIUM | +| JetBrains Fleet | YES | YES | YES | FLEET | +| Sublime Text | YES | YES | YES | SUBLIME_TEXT | -* You can set the given environment variable for special tool if it can NOT be found by this app automatically. -* Installing `JetBrains Toolbox` will help this app to find other JetBrains tools installed on your device. -* On macOS, you may need to use `launchctl setenv` to make sure the app can read these environment variables. +> [!NOTE] +> This app will try to find those tools based on some pre-defined or expected locations automatically. If you are using one portable version of these tools, it will not be detected by this app. +> To solve this problem you can add a file named `external_editors.json` and provide the path directly. For example: +```json +{ + "tools": { + "VSCODE": "D:\\VSCode\\Code.exe" + } +} +``` + +> [!NOTE] +> This app also supports a lot of `JetBrains` IDEs, installing `JetBrains Toolbox` will help this app to find them. ## Screenshots diff --git a/src/App.JsonCodeGen.cs b/src/App.JsonCodeGen.cs index f6e3cd88..5d7b114e 100644 --- a/src/App.JsonCodeGen.cs +++ b/src/App.JsonCodeGen.cs @@ -58,6 +58,7 @@ namespace SourceGit typeof(GridLengthConverter), ] )] + [JsonSerializable(typeof(Models.ExternalToolPaths))] [JsonSerializable(typeof(Models.InteractiveRebaseJobCollection))] [JsonSerializable(typeof(Models.JetBrainsState))] [JsonSerializable(typeof(Models.ThemeOverrides))] diff --git a/src/Models/ExternalTool.cs b/src/Models/ExternalTool.cs index 5ea8c744..27035a5c 100644 --- a/src/Models/ExternalTool.cs +++ b/src/Models/ExternalTool.cs @@ -79,6 +79,12 @@ namespace SourceGit.Models public string LaunchCommand { get; set; } } + public class ExternalToolPaths + { + [JsonPropertyName("tools")] + public Dictionary Tools { get; set; } = new Dictionary(); + } + public class ExternalToolsFinder { public List Founded @@ -87,42 +93,60 @@ namespace SourceGit.Models private set; } = new List(); - public void TryAdd(string name, string icon, string args, string env, Func finder) + public ExternalToolsFinder() { - var path = Environment.GetEnvironmentVariable(env); - if (string.IsNullOrEmpty(path) || !File.Exists(path)) + var customPathsConfig = Path.Combine(Native.OS.DataDir, "external_editors.json"); + try { - path = finder(); - if (string.IsNullOrEmpty(path) || !File.Exists(path)) - return; + if (File.Exists(customPathsConfig)) + _customPaths = JsonSerializer.Deserialize(File.ReadAllText(customPathsConfig), JsonCodeGen.Default.ExternalToolPaths); + } + catch + { + // Ignore } - Founded.Add(new ExternalTool(name, icon, path, args)); + if (_customPaths == null) + _customPaths = new ExternalToolPaths(); + } + + public void TryAdd(string name, string icon, string args, string key, Func finder) + { + if (_customPaths.Tools.TryGetValue(key, out var customPath) && File.Exists(customPath)) + { + Founded.Add(new ExternalTool(name, icon, customPath, args)); + } + else + { + var path = finder(); + if (!string.IsNullOrEmpty(path) && File.Exists(path)) + Founded.Add(new ExternalTool(name, icon, path, args)); + } } public void VSCode(Func platformFinder) { - TryAdd("Visual Studio Code", "vscode", "\"{0}\"", "VSCODE_PATH", platformFinder); + TryAdd("Visual Studio Code", "vscode", "\"{0}\"", "VSCODE", platformFinder); } public void VSCodeInsiders(Func platformFinder) { - TryAdd("Visual Studio Code - Insiders", "vscode_insiders", "\"{0}\"", "VSCODE_INSIDERS_PATH", platformFinder); + TryAdd("Visual Studio Code - Insiders", "vscode_insiders", "\"{0}\"", "VSCODE_INSIDERS", platformFinder); } public void VSCodium(Func platformFinder) { - TryAdd("VSCodium", "codium", "\"{0}\"", "VSCODIUM_PATH", platformFinder); + TryAdd("VSCodium", "codium", "\"{0}\"", "VSCODIUM", platformFinder); } public void Fleet(Func platformFinder) { - TryAdd("Fleet", "fleet", "\"{0}\"", "FLEET_PATH", platformFinder); + TryAdd("Fleet", "fleet", "\"{0}\"", "FLEET", platformFinder); } public void SublimeText(Func platformFinder) { - TryAdd("Sublime Text", "sublime_text", "\"{0}\"", "SUBLIME_TEXT_PATH", platformFinder); + TryAdd("Sublime Text", "sublime_text", "\"{0}\"", "SUBLIME_TEXT", platformFinder); } public void FindJetBrainsFromToolbox(Func platformFinder) @@ -146,5 +170,7 @@ namespace SourceGit.Models } } } + + private ExternalToolPaths _customPaths = null; } }