File size: 4,497 Bytes
18a519f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | 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
}
}
}
|