123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- 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"
- };
- #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
- }
- }
- }
|