Skip to content

Commit 29337e2

Browse files
committed
Support Workspace file
1 parent e4ef340 commit 29337e2

File tree

6 files changed

+121
-66
lines changed

6 files changed

+121
-66
lines changed

Flow.Plugin.VSCodeWorkspaces.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<AssemblyName>Flow.Plugin.VSCodeWorkspaces</AssemblyName>
88
<OutputType>Library</OutputType>
99
<Version>1.0</Version>
10-
<useWPF>true</useWPF>
10+
<UseWpf>true</UseWpf>
1111
<Platforms>x64</Platforms>
1212
<AppendRuntimeIdentifierToOutputPath>False</AppendRuntimeIdentifierToOutputPath>
1313
<LangVersion>latest</LangVersion>

Main.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class Main : IPlugin, IPluginI18n, ISettingProvider, IContextMenu
3636
public List<Result> Query(Query query)
3737
{
3838
var results = new List<Result>();
39-
var workspaces = new List<VSCodeWorkspace>();
39+
var workspaces = new List<VsCodeWorkspace>();
4040

4141
// User defined extra workspaces
4242
if (defaultInstalce != null)
@@ -122,20 +122,20 @@ public List<Result> Query(Query query)
122122
return results;
123123
}
124124

125-
private Result CreateWorkspaceResult(VSCodeWorkspace ws)
125+
private static Result CreateWorkspaceResult(VsCodeWorkspace ws)
126126
{
127127
var title = $"{ws.FolderName}";
128128
var typeWorkspace = ws.WorkspaceTypeToString();
129129

130-
if (ws.TypeWorkspace != TypeWorkspace.Local)
130+
if (ws.WorkspaceLocation != WorkspaceLocation.Local)
131131
{
132132
title = ws.Lable != null
133133
? $"{ws.Lable}"
134134
: $"{title}{(ws.ExtraInfo != null ? $" - {ws.ExtraInfo}" : string.Empty)} ({typeWorkspace})";
135135
}
136136

137137
var tooltip =
138-
$"{Resources.Workspace}{(ws.TypeWorkspace != TypeWorkspace.Local ? $" {Resources.In} {typeWorkspace}" : string.Empty)}: {SystemPath.RealPath(ws.RelativePath)}";
138+
$"{Resources.Workspace}{(ws.WorkspaceLocation != WorkspaceLocation.Local ? $" {Resources.In} {typeWorkspace}" : string.Empty)}: {SystemPath.RealPath(ws.RelativePath)}";
139139

140140
return new Result
141141
{
@@ -160,7 +160,11 @@ private Result CreateWorkspaceResult(VSCodeWorkspace ws)
160160
UseShellExecute = true,
161161
WindowStyle = ProcessWindowStyle.Hidden,
162162
};
163-
process.ArgumentList.Add("--folder-uri");
163+
164+
process.ArgumentList.Add(ws.WorkspaceType == WorkspaceType.Workspace
165+
? "--file-uri"
166+
: "--folder-uri");
167+
164168
process.ArgumentList.Add(ws.Path);
165169

166170
Process.Start(process);
@@ -211,7 +215,7 @@ public string GetTranslatedPluginDescription()
211215
public List<Result> LoadContextMenus(Result selectedResult)
212216
{
213217
List<Result> results = new();
214-
if (selectedResult.ContextData is VSCodeWorkspace ws && ws.TypeWorkspace == TypeWorkspace.Local)
218+
if (selectedResult.ContextData is VsCodeWorkspace ws && ws.WorkspaceLocation == WorkspaceLocation.Local)
215219
{
216220
results.Add(new Result
217221
{

SettingsView.xaml.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ private void ButtonAdd_Click(object sender, RoutedEventArgs e)
4141
var uri = addUri.Text;
4242

4343
// System.Uri fails to parse vscode-remote://XXX+YYY URIs, skip them
44-
var type = ParseVSCodeUri.GetTypeWorkspace(uri).TypeWorkspace;
45-
if (!type.HasValue || type.Value == TypeWorkspace.Local)
44+
var type = ParseVSCodeUri.GetTypeWorkspace(uri).workspaceLocation;
45+
if (!type.HasValue || type.Value == WorkspaceLocation.Local)
4646
{
4747
// Converts file paths to proper URI
4848
uri = new Uri(uri).AbsoluteUri;

WorkspacesHelper/ParseVSCodeUri.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ public class ParseVSCodeUri
1818

1919
private static readonly Regex DevContainerWorkspace = new Regex(@"^vscode-remote://dev-container\+(.+?(?=\/))(.+)$", RegexOptions.Compiled);
2020

21-
public static (TypeWorkspace? TypeWorkspace, string MachineName, string Path) GetTypeWorkspace(string uri)
21+
public static (WorkspaceLocation? workspaceLocation, string MachineName, string Path) GetTypeWorkspace(string uri)
2222
{
2323
if (LocalWorkspace.IsMatch(uri))
2424
{
2525
var match = LocalWorkspace.Match(uri);
2626

2727
if (match.Groups.Count > 1)
2828
{
29-
return (TypeWorkspace.Local, null, match.Groups[1].Value);
29+
return (WorkspaceLocation.Local, null, match.Groups[1].Value);
3030
}
3131
}
3232
else if (RemoteSSHWorkspace.IsMatch(uri))
@@ -35,7 +35,7 @@ public static (TypeWorkspace? TypeWorkspace, string MachineName, string Path) Ge
3535

3636
if (match.Groups.Count > 1)
3737
{
38-
return (TypeWorkspace.RemoteSSH, match.Groups[1].Value, match.Groups[2].Value);
38+
return (WorkspaceLocation.RemoteSSH, match.Groups[1].Value, match.Groups[2].Value);
3939
}
4040
}
4141
else if (RemoteWSLWorkspace.IsMatch(uri))
@@ -44,7 +44,7 @@ public static (TypeWorkspace? TypeWorkspace, string MachineName, string Path) Ge
4444

4545
if (match.Groups.Count > 1)
4646
{
47-
return (TypeWorkspace.RemoteWSL, match.Groups[1].Value, match.Groups[2].Value);
47+
return (WorkspaceLocation.RemoteWSL, match.Groups[1].Value, match.Groups[2].Value);
4848
}
4949
}
5050
else if (CodespacesWorkspace.IsMatch(uri))
@@ -53,7 +53,7 @@ public static (TypeWorkspace? TypeWorkspace, string MachineName, string Path) Ge
5353

5454
if (match.Groups.Count > 1)
5555
{
56-
return (TypeWorkspace.Codespaces, null, match.Groups[2].Value);
56+
return (WorkspaceLocation.Codespaces, null, match.Groups[2].Value);
5757
}
5858
}
5959
else if (DevContainerWorkspace.IsMatch(uri))
@@ -62,7 +62,7 @@ public static (TypeWorkspace? TypeWorkspace, string MachineName, string Path) Ge
6262

6363
if (match.Groups.Count > 1)
6464
{
65-
return (TypeWorkspace.DevContainer, null, match.Groups[2].Value);
65+
return (WorkspaceLocation.DevContainer, null, match.Groups[2].Value);
6666
}
6767
}
6868

WorkspacesHelper/VSCodeWorkspace.cs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace Flow.Plugin.VSCodeWorkspaces.WorkspacesHelper
1010
{
11-
public record VSCodeWorkspace
11+
public record VsCodeWorkspace
1212
{
1313
public PathString Path { get; init; }
1414

@@ -20,26 +20,28 @@ public record VSCodeWorkspace
2020

2121
public string ExtraInfo { get; init; }
2222

23-
public TypeWorkspace TypeWorkspace { get; init; }
23+
public WorkspaceLocation WorkspaceLocation { get; init; }
24+
25+
public WorkspaceType WorkspaceType { get; init; }
2426

2527
public VSCodeInstance VSCodeInstance { get; init; }
2628

2729
public string WorkspaceTypeToString()
2830
{
29-
return TypeWorkspace switch
31+
return WorkspaceLocation switch
3032
{
31-
TypeWorkspace.Local => Resources.TypeWorkspaceLocal,
32-
TypeWorkspace.Codespaces => "Codespaces",
33-
TypeWorkspace.RemoteContainers => Resources.TypeWorkspaceContainer,
34-
TypeWorkspace.RemoteSSH => "SSH",
35-
TypeWorkspace.RemoteWSL => "WSL",
36-
TypeWorkspace.DevContainer => Resources.TypeWorkspaceDevContainer,
33+
WorkspaceLocation.Local => Resources.TypeWorkspaceLocal,
34+
WorkspaceLocation.Codespaces => "Codespaces",
35+
WorkspaceLocation.RemoteContainers => Resources.TypeWorkspaceContainer,
36+
WorkspaceLocation.RemoteSSH => "SSH",
37+
WorkspaceLocation.RemoteWSL => "WSL",
38+
WorkspaceLocation.DevContainer => Resources.TypeWorkspaceDevContainer,
3739
_ => string.Empty
3840
};
3941
}
4042
}
4143

42-
public enum TypeWorkspace
44+
public enum WorkspaceLocation
4345
{
4446
Local = 1,
4547
Codespaces = 2,
@@ -48,4 +50,10 @@ public enum TypeWorkspace
4850
RemoteContainers = 5,
4951
DevContainer = 6,
5052
}
53+
54+
public enum WorkspaceType
55+
{
56+
Folder = 1,
57+
Workspace = 2,
58+
}
5159
}

WorkspacesHelper/VSCodeWorkspacesApi.cs

Lines changed: 84 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Text.Json;
1010
using System.Text.RegularExpressions;
1111
using Flow.Plugin.VSCodeWorkspaces.VSCodeHelper;
12+
using JetBrains.Annotations;
1213
using Microsoft.Data.Sqlite;
1314

1415
namespace Flow.Plugin.VSCodeWorkspaces.WorkspacesHelper
@@ -19,45 +20,43 @@ public VSCodeWorkspacesApi()
1920
{
2021
}
2122

22-
public static VSCodeWorkspace ParseVSCodeUri(string uri, VSCodeInstance vscodeInstance)
23+
public static VsCodeWorkspace ParseVSCodeUri(string uri, VSCodeInstance vscodeInstance)
2324
{
24-
if (uri != null && uri is string)
25+
if (uri is not null)
2526
{
26-
string unescapeUri = Uri.UnescapeDataString(uri);
27+
var unescapeUri = Uri.UnescapeDataString(uri);
2728
var typeWorkspace = WorkspacesHelper.ParseVSCodeUri.GetTypeWorkspace(unescapeUri);
28-
if (typeWorkspace.TypeWorkspace.HasValue)
29-
{
30-
var folderName = Path.GetFileName(unescapeUri);
29+
if (!typeWorkspace.workspaceLocation.HasValue) return null;
30+
var folderName = Path.GetFileName(unescapeUri);
3131

32-
// Check we haven't returned '' if we have a path like C:\
33-
if (string.IsNullOrEmpty(folderName))
34-
{
35-
DirectoryInfo dirInfo = new DirectoryInfo(unescapeUri);
36-
folderName = dirInfo.Name.TrimEnd(':');
37-
}
38-
39-
return new VSCodeWorkspace()
40-
{
41-
Path = unescapeUri,
42-
RelativePath = typeWorkspace.Path,
43-
FolderName = folderName,
44-
ExtraInfo = typeWorkspace.MachineName,
45-
TypeWorkspace = typeWorkspace.TypeWorkspace.Value,
46-
VSCodeInstance = vscodeInstance,
47-
};
32+
// Check we haven't returned '' if we have a path like C:\
33+
if (string.IsNullOrEmpty(folderName))
34+
{
35+
DirectoryInfo dirInfo = new DirectoryInfo(unescapeUri);
36+
folderName = dirInfo.Name.TrimEnd(':');
4837
}
38+
39+
return new VsCodeWorkspace()
40+
{
41+
Path = unescapeUri,
42+
RelativePath = typeWorkspace.Path,
43+
FolderName = folderName,
44+
ExtraInfo = typeWorkspace.MachineName,
45+
WorkspaceLocation = typeWorkspace.workspaceLocation.Value,
46+
VSCodeInstance = vscodeInstance,
47+
};
4948
}
5049

5150
return null;
5251
}
5352

54-
public Regex workspaceLabelParser = new Regex("(.+?)(\\[.+\\])");
53+
public readonly Regex WorkspaceLabelParser = new Regex("(.+?)(\\[.+\\])");
5554

56-
public List<VSCodeWorkspace> Workspaces
55+
public List<VsCodeWorkspace> Workspaces
5756
{
5857
get
5958
{
60-
var results = new List<VSCodeWorkspace>();
59+
var results = new List<VsCodeWorkspace>();
6160

6261
foreach (var vscodeInstance in VSCodeInstances.Instances)
6362
{
@@ -81,7 +80,7 @@ public List<VSCodeWorkspace> Workspaces
8180
vscodeStorageFile.OpenedPathsList.Workspaces3
8281
.Select(workspaceUri => ParseVSCodeUri(workspaceUri, vscodeInstance))
8382
.Where(uri => uri != null)
84-
.Select(uri => (VSCodeWorkspace)uri));
83+
.Select(uri => (VsCodeWorkspace)uri));
8584
}
8685

8786
// vscode v1.55.0 or later
@@ -116,29 +115,73 @@ public List<VSCodeWorkspace> Workspaces
116115
continue;
117116
foreach (var entry in entries.EnumerateArray())
118117
{
119-
if (!entry.TryGetProperty("folderUri", out var folderUri))
120-
continue;
121-
var workspaceUri = folderUri.GetString();
122-
var workspace = ParseVSCodeUri(workspaceUri, vscodeInstance);
123-
if (workspace == null)
124-
continue;
125-
126-
if (entry.TryGetProperty("label", out var label))
118+
if (entry.TryGetProperty("folderUri", out var folderUri) &&
119+
ParseFolderEntry(folderUri, vscodeInstance, entry) is { } folderWorkspace)
127120
{
128-
var labelString = label.GetString()!;
129-
var matchGroup = workspaceLabelParser.Match(labelString);
130-
workspace = workspace with {
131-
Lable = $"{matchGroup.Groups[2]} {matchGroup.Groups[1]}"
132-
};
121+
results.Add(folderWorkspace);
122+
}
123+
else if (entry.TryGetProperty("workspace", out var workspaceInfo) &&
124+
ParseWorkspaceEntry(workspaceInfo, vscodeInstance, entry) is { } workspace)
125+
{
126+
results.Add(workspace);
133127
}
134-
135-
results.Add(workspace);
136128
}
137129
}
138130
}
139131

140132
return results;
141133
}
142134
}
135+
136+
[CanBeNull]
137+
private VsCodeWorkspace ParseWorkspaceEntry(JsonElement workspaceInfo, VSCodeInstance vscodeInstance,
138+
JsonElement entry)
139+
{
140+
if (workspaceInfo.TryGetProperty("configPath", out var configPath))
141+
{
142+
var workspace = ParseVSCodeUri(configPath.GetString(), vscodeInstance);
143+
if (workspace == null)
144+
return null;
145+
146+
if (entry.TryGetProperty("label", out var label))
147+
{
148+
var labelString = label.GetString()!;
149+
var matchGroup = WorkspaceLabelParser.Match(labelString);
150+
workspace = workspace with
151+
{
152+
Lable = $"{matchGroup.Groups[2]} {matchGroup.Groups[1]}",
153+
WorkspaceType = WorkspaceType.Workspace
154+
};
155+
}
156+
157+
return workspace;
158+
}
159+
160+
return null;
161+
}
162+
163+
164+
[CanBeNull]
165+
private VsCodeWorkspace ParseFolderEntry(JsonElement folderUri, VSCodeInstance vscodeInstance,
166+
JsonElement entry)
167+
{
168+
var workspaceUri = folderUri.GetString();
169+
var workspace = ParseVSCodeUri(workspaceUri, vscodeInstance);
170+
if (workspace == null)
171+
return null;
172+
173+
if (entry.TryGetProperty("label", out var label))
174+
{
175+
var labelString = label.GetString()!;
176+
var matchGroup = WorkspaceLabelParser.Match(labelString);
177+
workspace = workspace with
178+
{
179+
Lable = $"{matchGroup.Groups[2]} {matchGroup.Groups[1]}",
180+
WorkspaceType = WorkspaceType.Workspace
181+
};
182+
}
183+
184+
return workspace;
185+
}
143186
}
144187
}

0 commit comments

Comments
 (0)