mirror of
https://fastgit.cc/github.com/sourcegit-scm/sourcegit
synced 2026-04-21 21:30:37 +08:00
feat: multi-solution management (#2043)
This commit is contained in:
@@ -16,11 +16,12 @@ namespace SourceGit.Models
|
||||
public string ExecFile { get; }
|
||||
public Bitmap IconImage { get; }
|
||||
|
||||
public ExternalTool(string name, string icon, string execFile, Func<string, string> execArgsGenerator = null)
|
||||
public ExternalTool(string name, string icon, string execFile, Func<string, string> execArgsGenerator = null, Func<string, List<string>> subOptionsFinder = null)
|
||||
{
|
||||
Name = name;
|
||||
ExecFile = execFile;
|
||||
_execArgsGenerator = execArgsGenerator ?? (path => path.Quoted());
|
||||
_subOptionsFinder = subOptionsFinder;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -48,7 +49,16 @@ namespace SourceGit.Models
|
||||
});
|
||||
}
|
||||
|
||||
public List<string> FindSubOptions(string path)
|
||||
{
|
||||
if (_subOptionsFinder == null)
|
||||
return null;
|
||||
|
||||
return _subOptionsFinder.Invoke(path);
|
||||
}
|
||||
|
||||
private Func<string, string> _execArgsGenerator = null;
|
||||
private Func<string, List<string>> _subOptionsFinder = null;
|
||||
}
|
||||
|
||||
public class VisualStudioInstance
|
||||
@@ -130,20 +140,20 @@ namespace SourceGit.Models
|
||||
_customization ??= new ExternalToolCustomization();
|
||||
}
|
||||
|
||||
public void TryAdd(string name, string icon, Func<string> finder, Func<string, string> execArgsGenerator = null)
|
||||
public void TryAdd(string name, string icon, Func<string> finder, Func<string, string> execArgsGenerator = null, Func<string, List<string>> subOptionsFinder = null)
|
||||
{
|
||||
if (_customization.Excludes.Contains(name))
|
||||
return;
|
||||
|
||||
if (_customization.Tools.TryGetValue(name, out var customPath) && File.Exists(customPath))
|
||||
{
|
||||
Tools.Add(new ExternalTool(name, icon, customPath, execArgsGenerator));
|
||||
Tools.Add(new ExternalTool(name, icon, customPath, execArgsGenerator, subOptionsFinder));
|
||||
}
|
||||
else
|
||||
{
|
||||
var path = finder();
|
||||
if (!string.IsNullOrEmpty(path) && File.Exists(path))
|
||||
Tools.Add(new ExternalTool(name, icon, path, execArgsGenerator));
|
||||
Tools.Add(new ExternalTool(name, icon, path, execArgsGenerator, subOptionsFinder));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -401,7 +401,7 @@ namespace SourceGit.Native
|
||||
{
|
||||
var exec = instance.ProductPath;
|
||||
var icon = instance.IsPrerelease ? "vs-preview" : "vs";
|
||||
finder.TryAdd(instance.DisplayName, icon, () => exec, GenerateCommandlineArgsForVisualStudio);
|
||||
finder.TryAdd(instance.DisplayName, icon, () => exec, GenerateCommandlineArgsForVisualStudio, FindVisualStudioSolutions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,37 +446,33 @@ namespace SourceGit.Native
|
||||
|
||||
private string GenerateCommandlineArgsForVisualStudio(string path)
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
var sln = FindVSSolutionFile(new DirectoryInfo(path), 4);
|
||||
return string.IsNullOrEmpty(sln) ? path.Quoted() : sln.Quoted();
|
||||
}
|
||||
|
||||
return path.Quoted();
|
||||
var solutions = FindVisualStudioSolutions(path);
|
||||
return solutions.Count > 0 ? solutions[0].Quoted() : path.Quoted();
|
||||
}
|
||||
|
||||
private string FindVSSolutionFile(DirectoryInfo dir, int leftDepth)
|
||||
public List<string> FindVisualStudioSolutions(string path)
|
||||
{
|
||||
var files = dir.GetFiles();
|
||||
foreach (var f in files)
|
||||
var solutions = new List<string>();
|
||||
if (!Directory.Exists(path))
|
||||
return solutions;
|
||||
|
||||
void Search(DirectoryInfo dir, int depth)
|
||||
{
|
||||
if (f.Name.EndsWith(".slnx", StringComparison.OrdinalIgnoreCase) ||
|
||||
f.Name.EndsWith(".sln", StringComparison.OrdinalIgnoreCase))
|
||||
return f.FullName;
|
||||
if (depth < 0)
|
||||
return;
|
||||
|
||||
foreach (var file in dir.GetFiles("*.sln"))
|
||||
solutions.Add(file.FullName);
|
||||
|
||||
foreach (var file in dir.GetFiles("*.slnx"))
|
||||
solutions.Add(file.FullName);
|
||||
|
||||
foreach (var subDir in dir.GetDirectories())
|
||||
Search(subDir, depth - 1);
|
||||
}
|
||||
Search(new DirectoryInfo(path), 4);
|
||||
|
||||
if (leftDepth <= 0)
|
||||
return null;
|
||||
|
||||
var subDirs = dir.GetDirectories();
|
||||
foreach (var subDir in subDirs)
|
||||
{
|
||||
var first = FindVSSolutionFile(subDir, leftDepth - 1);
|
||||
if (!string.IsNullOrEmpty(first))
|
||||
return first;
|
||||
}
|
||||
|
||||
return null;
|
||||
return solutions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
@@ -61,13 +62,35 @@ namespace SourceGit.Views
|
||||
var item = new MenuItem();
|
||||
item.Header = App.Text("Repository.OpenIn", dupTool.Name);
|
||||
item.Icon = new Image { Width = 16, Height = 16, Source = dupTool.IconImage };
|
||||
item.Click += (_, e) =>
|
||||
{
|
||||
dupTool.Open(fullpath);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
menu.Items.Add(item);
|
||||
var subOptions = dupTool.FindSubOptions(fullpath);
|
||||
if (subOptions != null && subOptions.Count > 1)
|
||||
{
|
||||
foreach (var subOption in subOptions)
|
||||
{
|
||||
var subItem = new MenuItem();
|
||||
subItem.Header = Path.GetFileName(subOption);
|
||||
subItem.Click += (_, e) =>
|
||||
{
|
||||
dupTool.Open(subOption);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
item.Items.Add(subItem);
|
||||
}
|
||||
|
||||
menu.Items.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Click += (_, e) =>
|
||||
{
|
||||
dupTool.Open(fullpath);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
menu.Items.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user