Singularity/Library/PackageCache/com.unity.ide.vscode@1.2.5/Editor/VSCodeDiscovery.cs
2024-05-06 11:45:45 -07:00

139 lines
4.4 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Unity.CodeEditor;
namespace VSCodeEditor
{
public interface IDiscovery
{
CodeEditor.Installation[] PathCallback();
}
public class VSCodeDiscovery : IDiscovery
{
List<CodeEditor.Installation> m_Installations;
public CodeEditor.Installation[] PathCallback()
{
if (m_Installations == null)
{
m_Installations = new List<CodeEditor.Installation>();
FindInstallationPaths();
}
return m_Installations.ToArray();
}
void FindInstallationPaths()
{
string[] possiblePaths =
#if UNITY_EDITOR_OSX
{
"/Applications/Visual Studio Code.app",
"/Applications/Visual Studio Code - Insiders.app"
};
#elif UNITY_EDITOR_WIN
{
GetProgramFiles() + @"/Microsoft VS Code/bin/code.cmd",
GetProgramFiles() + @"/Microsoft VS Code/Code.exe",
GetProgramFiles() + @"/Microsoft VS Code Insiders/bin/code-insiders.cmd",
GetProgramFiles() + @"/Microsoft VS Code Insiders/Code.exe",
GetLocalAppData() + @"/Programs/Microsoft VS Code/bin/code.cmd",
GetLocalAppData() + @"/Programs/Microsoft VS Code/Code.exe",
GetLocalAppData() + @"/Programs/Microsoft VS Code Insiders/bin/code-insiders.cmd",
GetLocalAppData() + @"/Programs/Microsoft VS Code Insiders/Code.exe",
};
#else
{
"/usr/bin/code",
"/bin/code",
"/usr/local/bin/code",
"/var/lib/flatpak/exports/bin/com.visualstudio.code",
"/snap/current/bin/code",
"/snap/bin/code"
};
#endif
var existingPaths = possiblePaths.Where(VSCodeExists).ToList();
if (!existingPaths.Any())
{
return;
}
var lcp = GetLongestCommonPrefix(existingPaths);
switch (existingPaths.Count)
{
case 1:
{
var path = existingPaths.First();
m_Installations = new List<CodeEditor.Installation>
{
new CodeEditor.Installation
{
Path = path,
Name = path.Contains("Insiders")
? "Visual Studio Code Insiders"
: "Visual Studio Code"
}
};
break;
}
case 2 when existingPaths.Any(path => !(path.Substring(lcp.Length).Contains("/") || path.Substring(lcp.Length).Contains("\\"))):
{
goto case 1;
}
default:
{
m_Installations = existingPaths.Select(path => new CodeEditor.Installation
{
Name = $"Visual Studio Code Insiders ({path.Substring(lcp.Length)})",
Path = path
}).ToList();
break;
}
}
}
#if UNITY_EDITOR_WIN
static string GetProgramFiles()
{
return Environment.GetEnvironmentVariable("ProgramFiles")?.Replace("\\", "/");
}
static string GetLocalAppData()
{
return Environment.GetEnvironmentVariable("LOCALAPPDATA")?.Replace("\\", "/");
}
#endif
static string GetLongestCommonPrefix(List<string> paths)
{
var baseLength = paths.First().Length;
for (var pathIndex = 1; pathIndex < paths.Count; pathIndex++)
{
baseLength = Math.Min(baseLength, paths[pathIndex].Length);
for (var i = 0; i < baseLength; i++)
{
if (paths[pathIndex][i] == paths[0][i]) continue;
baseLength = i;
break;
}
}
return paths[0].Substring(0, baseLength);
}
static bool VSCodeExists(string path)
{
#if UNITY_EDITOR_OSX
return System.IO.Directory.Exists(path);
#else
return new FileInfo(path).Exists;
#endif
}
}
}