You've already forked com.unity.ide.cursor
mirror of
https://github.com/boxqkrtm/com.unity.ide.cursor.git
synced 2026-05-15 06:40:08 +00:00
com.unity.ide.visualstudio@2.0.20
## [2.0.20] - 2023-06-27 Integration: - Internal API refactoring. ## [2.0.19] - 2023-06-14 Integration: - Add support for Visual Studio Code. Project generation: - Add support for Sdk Style poject generation. - Fix an issue related to missing properties with 2021.3.
This commit is contained in:
345
Editor/VisualStudioCodeInstallation.cs
Normal file
345
Editor/VisualStudioCodeInstallation.cs
Normal file
@@ -0,0 +1,345 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
using IOPath = System.IO.Path;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.Unity.VisualStudio.Editor
|
||||
{
|
||||
internal class VisualStudioCodeInstallation : VisualStudioInstallation
|
||||
{
|
||||
private static readonly IGenerator _generator = new SdkStyleProjectGeneration();
|
||||
|
||||
public override bool SupportsAnalyzers
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override Version LatestLanguageVersionSupported
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Version(11, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetExtensionPath()
|
||||
{
|
||||
var vscode = IsPrerelease ? ".vscode-insiders" : ".vscode";
|
||||
var extensionsPath = IOPath.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), vscode, "extensions");
|
||||
if (!Directory.Exists(extensionsPath))
|
||||
return null;
|
||||
|
||||
return Directory
|
||||
.EnumerateDirectories(extensionsPath, "visualstudiotoolsforunity.vstuc*") // publisherid.extensionid
|
||||
.OrderByDescending(n => n)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public override string[] GetAnalyzers()
|
||||
{
|
||||
var vstuPath = GetExtensionPath();
|
||||
if (string.IsNullOrEmpty(vstuPath))
|
||||
return Array.Empty<string>();
|
||||
|
||||
return GetAnalyzers(vstuPath); }
|
||||
|
||||
public override IGenerator ProjectGenerator
|
||||
{
|
||||
get
|
||||
{
|
||||
return _generator;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsCandidateForDiscovery(string path)
|
||||
{
|
||||
if (VisualStudioEditor.IsOSX)
|
||||
return Directory.Exists(path) && Regex.IsMatch(path, ".*Code.*.app$", RegexOptions.IgnoreCase);
|
||||
|
||||
if (VisualStudioEditor.IsWindows)
|
||||
return File.Exists(path) && Regex.IsMatch(path, ".*Code.*.exe$", RegexOptions.IgnoreCase);
|
||||
|
||||
return File.Exists(path) && path.EndsWith("code", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
internal class VisualStudioCodeManifest
|
||||
{
|
||||
public string name;
|
||||
public string version;
|
||||
}
|
||||
|
||||
public static bool TryDiscoverInstallation(string editorPath, out IVisualStudioInstallation installation)
|
||||
{
|
||||
installation = null;
|
||||
|
||||
if (string.IsNullOrEmpty(editorPath))
|
||||
return false;
|
||||
|
||||
if (!IsCandidateForDiscovery(editorPath))
|
||||
return false;
|
||||
|
||||
Version version = null;
|
||||
var isPrerelease = false;
|
||||
|
||||
try
|
||||
{
|
||||
var manifestBase = GetRealPath(editorPath);
|
||||
|
||||
if (VisualStudioEditor.IsWindows) // on Windows, editorPath is a file, resources as subdirectory
|
||||
manifestBase = IOPath.GetDirectoryName(manifestBase);
|
||||
else if (VisualStudioEditor.IsOSX) // on Mac, editorPath is a directory
|
||||
manifestBase = IOPath.Combine(manifestBase, "Contents");
|
||||
else // on Linux, editorPath is a file, in a bin sub-directory
|
||||
manifestBase = Directory.GetParent(manifestBase)?.Parent?.FullName;
|
||||
|
||||
if (manifestBase == null)
|
||||
return false;
|
||||
|
||||
var manifestFullPath = IOPath.Combine(manifestBase, @"resources", "app", "package.json");
|
||||
if (File.Exists(manifestFullPath))
|
||||
{
|
||||
var manifest = JsonUtility.FromJson<VisualStudioCodeManifest>(File.ReadAllText(manifestFullPath));
|
||||
Version.TryParse(manifest.version.Split('-').First(), out version);
|
||||
isPrerelease = manifest.version.ToLower().Contains("insider");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// do not fail if we are not able to retrieve the exact version number
|
||||
}
|
||||
|
||||
isPrerelease = isPrerelease || editorPath.ToLower().Contains("insider");
|
||||
installation = new VisualStudioCodeInstallation()
|
||||
{
|
||||
IsPrerelease = isPrerelease,
|
||||
Name = "Visual Studio Code" + (isPrerelease ? " - Insider" : string.Empty) + (version != null ? $" [{version.ToString(3)}]" : string.Empty),
|
||||
Path = editorPath,
|
||||
Version = version ?? new Version()
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static IEnumerable<IVisualStudioInstallation> GetVisualStudioInstallations()
|
||||
{
|
||||
var candidates = new List<string>();
|
||||
|
||||
if (VisualStudioEditor.IsWindows)
|
||||
{
|
||||
var localAppPath = IOPath.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Programs");
|
||||
var programFiles = IOPath.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles));
|
||||
|
||||
foreach (var basePath in new[] {localAppPath, programFiles})
|
||||
{
|
||||
candidates.Add(IOPath.Combine(basePath, "Microsoft VS Code", "Code.exe"));
|
||||
candidates.Add(IOPath.Combine(basePath, "Microsoft VS Code Insiders", "Code - Insiders.exe"));
|
||||
}
|
||||
}
|
||||
else if (VisualStudioEditor.IsOSX)
|
||||
{
|
||||
var appPath = IOPath.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles));
|
||||
candidates.AddRange(Directory.EnumerateDirectories(appPath, "Visual Studio Code*.app"));
|
||||
}
|
||||
else
|
||||
{
|
||||
candidates.Add("/usr/bin/code");
|
||||
candidates.Add("/bin/code");
|
||||
candidates.Add("/usr/local/bin/code");
|
||||
}
|
||||
|
||||
foreach (var candidate in candidates)
|
||||
{
|
||||
if (TryDiscoverInstallation(candidate, out var installation))
|
||||
yield return installation;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR_LINUX
|
||||
[DllImport ("libc")]
|
||||
private static extern int readlink(string path, byte[] buffer, int buflen);
|
||||
|
||||
internal static string GetRealPath(string path)
|
||||
{
|
||||
byte[] buf = new byte[512];
|
||||
int ret = readlink(path, buf, buf.Length);
|
||||
if (ret == -1) return path;
|
||||
char[] cbuf = new char[512];
|
||||
int chars = System.Text.Encoding.Default.GetChars(buf, 0, ret, cbuf, 0);
|
||||
return new String(cbuf, 0, chars);
|
||||
}
|
||||
#else
|
||||
internal static string GetRealPath(string path)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
#endif
|
||||
|
||||
public override void CreateExtraFiles(string projectDirectory)
|
||||
{
|
||||
try
|
||||
{
|
||||
// see https://tattoocoder.com/recommending-vscode-extensions-within-your-open-source-projects/
|
||||
var vscodeDirectory = IOPath.Combine(projectDirectory.NormalizePathSeparators(), ".vscode");
|
||||
Directory.CreateDirectory(vscodeDirectory);
|
||||
|
||||
CreateRecommendedExtensionsFile(vscodeDirectory);
|
||||
CreateSettingsFile(vscodeDirectory);
|
||||
CreateLaunchFile(vscodeDirectory);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateLaunchFile(string vscodeDirectory)
|
||||
{
|
||||
var launchFile = IOPath.Combine(vscodeDirectory, "launch.json");
|
||||
if (File.Exists(launchFile))
|
||||
return;
|
||||
|
||||
const string content = @"{
|
||||
""version"": ""0.2.0"",
|
||||
""configurations"": [
|
||||
{
|
||||
""name"": ""Attach to Unity"",
|
||||
""type"": ""vstuc"",
|
||||
""request"": ""attach"",
|
||||
}
|
||||
]
|
||||
}";
|
||||
|
||||
File.WriteAllText(launchFile, content);
|
||||
}
|
||||
|
||||
private static void CreateSettingsFile(string vscodeDirectory)
|
||||
{
|
||||
var settingsFile = IOPath.Combine(vscodeDirectory, "settings.json");
|
||||
if (File.Exists(settingsFile))
|
||||
return;
|
||||
|
||||
const string content = @"{
|
||||
""files.exclude"":
|
||||
{
|
||||
""**/.DS_Store"":true,
|
||||
""**/.git"":true,
|
||||
""**/.vs"":true,
|
||||
""**/.gitmodules"":true,
|
||||
""**/.vsconfig"":true,
|
||||
""**/*.booproj"":true,
|
||||
""**/*.pidb"":true,
|
||||
""**/*.suo"":true,
|
||||
""**/*.user"":true,
|
||||
""**/*.userprefs"":true,
|
||||
""**/*.unityproj"":true,
|
||||
""**/*.dll"":true,
|
||||
""**/*.exe"":true,
|
||||
""**/*.pdf"":true,
|
||||
""**/*.mid"":true,
|
||||
""**/*.midi"":true,
|
||||
""**/*.wav"":true,
|
||||
""**/*.gif"":true,
|
||||
""**/*.ico"":true,
|
||||
""**/*.jpg"":true,
|
||||
""**/*.jpeg"":true,
|
||||
""**/*.png"":true,
|
||||
""**/*.psd"":true,
|
||||
""**/*.tga"":true,
|
||||
""**/*.tif"":true,
|
||||
""**/*.tiff"":true,
|
||||
""**/*.3ds"":true,
|
||||
""**/*.3DS"":true,
|
||||
""**/*.fbx"":true,
|
||||
""**/*.FBX"":true,
|
||||
""**/*.lxo"":true,
|
||||
""**/*.LXO"":true,
|
||||
""**/*.ma"":true,
|
||||
""**/*.MA"":true,
|
||||
""**/*.obj"":true,
|
||||
""**/*.OBJ"":true,
|
||||
""**/*.asset"":true,
|
||||
""**/*.cubemap"":true,
|
||||
""**/*.flare"":true,
|
||||
""**/*.mat"":true,
|
||||
""**/*.meta"":true,
|
||||
""**/*.prefab"":true,
|
||||
""**/*.unity"":true,
|
||||
""build/"":true,
|
||||
""Build/"":true,
|
||||
""Library/"":true,
|
||||
""library/"":true,
|
||||
""obj/"":true,
|
||||
""Obj/"":true,
|
||||
""Logs/"":true,
|
||||
""logs/"":true,
|
||||
""ProjectSettings/"":true,
|
||||
""UserSettings/"":true,
|
||||
""temp/"":true,
|
||||
""Temp/"":true
|
||||
},
|
||||
""omnisharp.enableRoslynAnalyzers"": true
|
||||
}";
|
||||
|
||||
File.WriteAllText(settingsFile, content);
|
||||
}
|
||||
|
||||
private static void CreateRecommendedExtensionsFile(string vscodeDirectory)
|
||||
{
|
||||
var extensionFile = IOPath.Combine(vscodeDirectory, "extensions.json");
|
||||
if (File.Exists(extensionFile))
|
||||
return;
|
||||
|
||||
const string content = @"{
|
||||
""recommendations"": [
|
||||
""visualstudiotoolsforunity.vstuc""
|
||||
]
|
||||
}
|
||||
";
|
||||
File.WriteAllText(extensionFile, content);
|
||||
}
|
||||
|
||||
public override bool Open(string path, int line, int column, string solution)
|
||||
{
|
||||
line = Math.Max(1, line);
|
||||
column = Math.Max(0, column);
|
||||
|
||||
var directory = IOPath.GetDirectoryName(solution);
|
||||
var application = Path;
|
||||
|
||||
ProcessRunner.Start(string.IsNullOrEmpty(path) ?
|
||||
ProcessStartInfoFor(application, $"\"{directory}\"") :
|
||||
ProcessStartInfoFor(application, $"\"{directory}\" -g \"{path}\":{line}:{column}"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static ProcessStartInfo ProcessStartInfoFor(string application, string arguments)
|
||||
{
|
||||
if (!VisualStudioEditor.IsOSX)
|
||||
return ProcessRunner.ProcessStartInfoFor(application, arguments, redirect: false);
|
||||
|
||||
// wrap with built-in OSX open feature
|
||||
arguments = $"-n \"{application}\" --args {arguments}";
|
||||
application = "open";
|
||||
return ProcessRunner.ProcessStartInfoFor(application, arguments, redirect:false, shell: true);
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user