Skip to content

Commit 3dbab1c

Browse files
feat: multi-solution management (#2043)
1 parent 96e2754 commit 3dbab1c

File tree

3 files changed

+62
-33
lines changed

3 files changed

+62
-33
lines changed

src/Models/ExternalTool.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ public class ExternalTool
1616
public string ExecFile { get; }
1717
public Bitmap IconImage { get; }
1818

19-
public ExternalTool(string name, string icon, string execFile, Func<string, string> execArgsGenerator = null)
19+
public ExternalTool(string name, string icon, string execFile, Func<string, string> execArgsGenerator = null, Func<string, List<string>> subOptionsFinder = null)
2020
{
2121
Name = name;
2222
ExecFile = execFile;
2323
_execArgsGenerator = execArgsGenerator ?? (path => path.Quoted());
24+
_subOptionsFinder = subOptionsFinder;
2425

2526
try
2627
{
@@ -48,7 +49,16 @@ public void Open(string path)
4849
});
4950
}
5051

52+
public List<string> FindSubOptions(string path)
53+
{
54+
if (_subOptionsFinder == null)
55+
return null;
56+
57+
return _subOptionsFinder.Invoke(path);
58+
}
59+
5160
private Func<string, string> _execArgsGenerator = null;
61+
private Func<string, List<string>> _subOptionsFinder = null;
5262
}
5363

5464
public class VisualStudioInstance
@@ -130,20 +140,20 @@ public ExternalToolsFinder()
130140
_customization ??= new ExternalToolCustomization();
131141
}
132142

133-
public void TryAdd(string name, string icon, Func<string> finder, Func<string, string> execArgsGenerator = null)
143+
public void TryAdd(string name, string icon, Func<string> finder, Func<string, string> execArgsGenerator = null, Func<string, List<string>> subOptionsFinder = null)
134144
{
135145
if (_customization.Excludes.Contains(name))
136146
return;
137147

138148
if (_customization.Tools.TryGetValue(name, out var customPath) && File.Exists(customPath))
139149
{
140-
Tools.Add(new ExternalTool(name, icon, customPath, execArgsGenerator));
150+
Tools.Add(new ExternalTool(name, icon, customPath, execArgsGenerator, subOptionsFinder));
141151
}
142152
else
143153
{
144154
var path = finder();
145155
if (!string.IsNullOrEmpty(path) && File.Exists(path))
146-
Tools.Add(new ExternalTool(name, icon, path, execArgsGenerator));
156+
Tools.Add(new ExternalTool(name, icon, path, execArgsGenerator, subOptionsFinder));
147157
}
148158
}
149159

src/Native/Windows.cs

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ private void FindVisualStudio(Models.ExternalToolsFinder finder)
401401
{
402402
var exec = instance.ProductPath;
403403
var icon = instance.IsPrerelease ? "vs-preview" : "vs";
404-
finder.TryAdd(instance.DisplayName, icon, () => exec, GenerateCommandlineArgsForVisualStudio);
404+
finder.TryAdd(instance.DisplayName, icon, () => exec, GenerateCommandlineArgsForVisualStudio, FindVisualStudioSolutions);
405405
}
406406
}
407407
}
@@ -446,37 +446,33 @@ private void OpenFolderAndSelectFile(string folderPath)
446446

447447
private string GenerateCommandlineArgsForVisualStudio(string path)
448448
{
449-
if (Directory.Exists(path))
450-
{
451-
var sln = FindVSSolutionFile(new DirectoryInfo(path), 4);
452-
return string.IsNullOrEmpty(sln) ? path.Quoted() : sln.Quoted();
453-
}
454-
455-
return path.Quoted();
449+
var solutions = FindVisualStudioSolutions(path);
450+
return solutions.Count > 0 ? solutions[0].Quoted() : path.Quoted();
456451
}
457452

458-
private string FindVSSolutionFile(DirectoryInfo dir, int leftDepth)
453+
public List<string> FindVisualStudioSolutions(string path)
459454
{
460-
var files = dir.GetFiles();
461-
foreach (var f in files)
455+
var solutions = new List<string>();
456+
if (!Directory.Exists(path))
457+
return solutions;
458+
459+
void Search(DirectoryInfo dir, int depth)
462460
{
463-
if (f.Name.EndsWith(".slnx", StringComparison.OrdinalIgnoreCase) ||
464-
f.Name.EndsWith(".sln", StringComparison.OrdinalIgnoreCase))
465-
return f.FullName;
466-
}
461+
if (depth < 0)
462+
return;
467463

468-
if (leftDepth <= 0)
469-
return null;
464+
foreach (var file in dir.GetFiles("*.sln"))
465+
solutions.Add(file.FullName);
470466

471-
var subDirs = dir.GetDirectories();
472-
foreach (var subDir in subDirs)
473-
{
474-
var first = FindVSSolutionFile(subDir, leftDepth - 1);
475-
if (!string.IsNullOrEmpty(first))
476-
return first;
467+
foreach (var file in dir.GetFiles("*.slnx"))
468+
solutions.Add(file.FullName);
469+
470+
foreach (var subDir in dir.GetDirectories())
471+
Search(subDir, depth - 1);
477472
}
473+
Search(new DirectoryInfo(path), 4);
478474

479-
return null;
475+
return solutions;
480476
}
481477
}
482478
}

src/Views/RepositoryToolbar.axaml.cs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.IO;
23

34
using Avalonia.Controls;
45
using Avalonia.Input;
@@ -61,13 +62,35 @@ private void OpenWithExternalTools(object sender, RoutedEventArgs ev)
6162
var item = new MenuItem();
6263
item.Header = App.Text("Repository.OpenIn", dupTool.Name);
6364
item.Icon = new Image { Width = 16, Height = 16, Source = dupTool.IconImage };
64-
item.Click += (_, e) =>
65+
66+
var subOptions = dupTool.FindSubOptions(fullpath);
67+
if (subOptions != null && subOptions.Count > 1)
6568
{
66-
dupTool.Open(fullpath);
67-
e.Handled = true;
68-
};
69+
foreach (var subOption in subOptions)
70+
{
71+
var subItem = new MenuItem();
72+
subItem.Header = Path.GetFileName(subOption);
73+
subItem.Click += (_, e) =>
74+
{
75+
dupTool.Open(subOption);
76+
e.Handled = true;
77+
};
78+
79+
item.Items.Add(subItem);
80+
}
81+
82+
menu.Items.Add(item);
83+
}
84+
else
85+
{
86+
item.Click += (_, e) =>
87+
{
88+
dupTool.Open(fullpath);
89+
e.Handled = true;
90+
};
6991

70-
menu.Items.Add(item);
92+
menu.Items.Add(item);
93+
}
7194
}
7295
}
7396

0 commit comments

Comments
 (0)