From c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78 Mon Sep 17 00:00:00 2001 From: Andrew Lee Date: Sun, 19 Apr 2020 17:19:32 -0400 Subject: Inital commit --- .../Editor/ProjectGeneration.meta | 8 + .../ProjectGeneration/AssemblyNameProvider.cs | 50 ++ .../ProjectGeneration/AssemblyNameProvider.cs.meta | 11 + .../Editor/ProjectGeneration/FileIO.cs | 38 ++ .../Editor/ProjectGeneration/FileIO.cs.meta | 11 + .../Editor/ProjectGeneration/GUIDGenerator.cs | 21 + .../Editor/ProjectGeneration/GUIDGenerator.cs.meta | 11 + .../Editor/ProjectGeneration/ProjectGeneration.cs | 718 +++++++++++++++++++++ .../ProjectGeneration/ProjectGeneration.cs.meta | 11 + .../Editor/Unity.com.unity.vscode.Editor.asmdef | 9 + .../Unity.com.unity.vscode.Editor.asmdef.meta | 7 + .../Editor/VSCodeDiscovery.cs | 137 ++++ .../Editor/VSCodeDiscovery.cs.meta | 11 + .../Editor/VSCodeScriptEditor.cs | 257 ++++++++ .../Editor/VSCodeScriptEditor.cs.meta | 11 + 15 files changed, 1311 insertions(+) create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration.meta create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/AssemblyNameProvider.cs create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/AssemblyNameProvider.cs.meta create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/FileIO.cs create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/FileIO.cs.meta create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/GUIDGenerator.cs create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/GUIDGenerator.cs.meta create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/ProjectGeneration.cs create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/ProjectGeneration.cs.meta create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/Unity.com.unity.vscode.Editor.asmdef create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/Unity.com.unity.vscode.Editor.asmdef.meta create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeDiscovery.cs create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeDiscovery.cs.meta create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeScriptEditor.cs create mode 100644 Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeScriptEditor.cs.meta (limited to 'Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor') diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration.meta b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration.meta new file mode 100644 index 0000000..48ed36c --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c779d3735d950f341ba35154e8b3234b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/AssemblyNameProvider.cs b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/AssemblyNameProvider.cs new file mode 100644 index 0000000..43e0972 --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/AssemblyNameProvider.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEditor.Compilation; + +namespace VSCodeEditor +{ + public interface IAssemblyNameProvider + { + string GetAssemblyNameFromScriptPath(string path); + IEnumerable GetAssemblies(Func shouldFileBePartOfSolution); + IEnumerable GetAllAssetPaths(); + UnityEditor.PackageManager.PackageInfo FindForAssetPath(string assetPath); + ResponseFileData ParseResponseFile(string responseFilePath, string projectDirectory, string[] systemReferenceDirectories); + } + + internal class AssemblyNameProvider : IAssemblyNameProvider + { + public string GetAssemblyNameFromScriptPath(string path) + { + return CompilationPipeline.GetAssemblyNameFromScriptPath(path); + } + + public IEnumerable GetAssemblies(Func shouldFileBePartOfSolution) + { + return CompilationPipeline.GetAssemblies() + .Where(i => 0 < i.sourceFiles.Length && i.sourceFiles.Any(shouldFileBePartOfSolution)); + } + + public IEnumerable GetAllAssetPaths() + { + return AssetDatabase.GetAllAssetPaths(); + } + + public UnityEditor.PackageManager.PackageInfo FindForAssetPath(string assetPath) + { + return UnityEditor.PackageManager.PackageInfo.FindForAssetPath(assetPath); + } + + public ResponseFileData ParseResponseFile(string responseFilePath, string projectDirectory, string[] systemReferenceDirectories) + { + return CompilationPipeline.ParseResponseFile( + responseFilePath, + projectDirectory, + systemReferenceDirectories + ); + } + } +} diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/AssemblyNameProvider.cs.meta b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/AssemblyNameProvider.cs.meta new file mode 100644 index 0000000..a8ae38b --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/AssemblyNameProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d93ffb668978f7488211a331977b73b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/FileIO.cs b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/FileIO.cs new file mode 100644 index 0000000..aeff22e --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/FileIO.cs @@ -0,0 +1,38 @@ +using System.IO; +using System.Text; + +namespace VSCodeEditor +{ + public interface IFileIO + { + bool Exists(string fileName); + + string ReadAllText(string fileName); + void WriteAllText(string fileName, string content); + + void CreateDirectory(string pathName); + } + + class FileIOProvider : IFileIO + { + public bool Exists(string fileName) + { + return File.Exists(fileName); + } + + public string ReadAllText(string fileName) + { + return File.ReadAllText(fileName); + } + + public void WriteAllText(string fileName, string content) + { + File.WriteAllText(fileName, content, Encoding.UTF8); + } + + public void CreateDirectory(string pathName) + { + Directory.CreateDirectory(pathName); + } + } +} diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/FileIO.cs.meta b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/FileIO.cs.meta new file mode 100644 index 0000000..91d8212 --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/FileIO.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb221cf55b3544646b0c3b6bc790080f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/GUIDGenerator.cs b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/GUIDGenerator.cs new file mode 100644 index 0000000..0654966 --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/GUIDGenerator.cs @@ -0,0 +1,21 @@ +namespace VSCodeEditor +{ + public interface IGUIDGenerator + { + string ProjectGuid(string projectName, string assemblyName); + string SolutionGuid(string projectName, string extension); + } + + class GUIDProvider : IGUIDGenerator + { + public string ProjectGuid(string projectName, string assemblyName) + { + return SolutionGuidGenerator.GuidForProject(projectName + assemblyName); + } + + public string SolutionGuid(string projectName, string extension) + { + return SolutionGuidGenerator.GuidForSolution(projectName, extension); // GetExtensionOfSourceFiles(assembly.sourceFiles) + } + } +} diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/GUIDGenerator.cs.meta b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/GUIDGenerator.cs.meta new file mode 100644 index 0000000..9ce342e --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/GUIDGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e58bd3cca6475e54b93632bb6837aeea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/ProjectGeneration.cs b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/ProjectGeneration.cs new file mode 100644 index 0000000..61e86e1 --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/ProjectGeneration.cs @@ -0,0 +1,718 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security; +using System.Security.Cryptography; +using System.Text; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEditor.Compilation; +using UnityEditor.PackageManager; +using UnityEngine; +using UnityEngine.Profiling; + +namespace VSCodeEditor +{ + public interface IGenerator + { + bool SyncIfNeeded(List affectedFiles, string[] reimportedFiles); + void Sync(); + string SolutionFile(); + string ProjectDirectory { get; } + void GenerateAll(bool generateAll); + bool SolutionExists(); + } + + public class ProjectGeneration : IGenerator + { + enum ScriptingLanguage + { + None, + CSharp + } + + public static readonly string MSBuildNamespaceUri = "http://schemas.microsoft.com/developer/msbuild/2003"; + + const string k_WindowsNewline = "\r\n"; + + const string k_SettingsJson = @"{ + ""files.exclude"": + { + ""**/.DS_Store"":true, + ""**/.git"":true, + ""**/.gitignore"":true, + ""**/.gitmodules"":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, + ""ProjectSettings/"":true, + ""temp/"":true, + ""Temp/"":true + } +}"; + + /// + /// Map source extensions to ScriptingLanguages + /// + static readonly Dictionary k_BuiltinSupportedExtensions = new Dictionary + { + { "cs", ScriptingLanguage.CSharp }, + { "uxml", ScriptingLanguage.None }, + { "uss", ScriptingLanguage.None }, + { "shader", ScriptingLanguage.None }, + { "compute", ScriptingLanguage.None }, + { "cginc", ScriptingLanguage.None }, + { "hlsl", ScriptingLanguage.None }, + { "glslinc", ScriptingLanguage.None }, + { "template", ScriptingLanguage.None }, + { "raytrace", ScriptingLanguage.None } + }; + + string m_SolutionProjectEntryTemplate = string.Join("\r\n", @"Project(""{{{0}}}"") = ""{1}"", ""{2}"", ""{{{3}}}""", @"EndProject").Replace(" ", "\t"); + + string m_SolutionProjectConfigurationTemplate = string.Join("\r\n", @" {{{0}}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU", @" {{{0}}}.Debug|Any CPU.Build.0 = Debug|Any CPU", @" {{{0}}}.Release|Any CPU.ActiveCfg = Release|Any CPU", @" {{{0}}}.Release|Any CPU.Build.0 = Release|Any CPU").Replace(" ", "\t"); + + static readonly string[] k_ReimportSyncExtensions = { ".dll", ".asmdef" }; + + string[] m_ProjectSupportedExtensions = new string[0]; + public string ProjectDirectory { get; } + bool m_ShouldGenerateAll; + + public void GenerateAll(bool generateAll) + { + m_ShouldGenerateAll = generateAll; + } + + readonly string m_ProjectName; + readonly IAssemblyNameProvider m_AssemblyNameProvider; + readonly IFileIO m_FileIOProvider; + readonly IGUIDGenerator m_GUIDProvider; + + const string k_ToolsVersion = "4.0"; + const string k_ProductVersion = "10.0.20506"; + const string k_BaseDirectory = "."; + const string k_TargetFrameworkVersion = "v4.7.1"; + const string k_TargetLanguageVersion = "latest"; + + public ProjectGeneration(string tempDirectory) + : this(tempDirectory, new AssemblyNameProvider(), new FileIOProvider(), new GUIDProvider()) { } + + public ProjectGeneration(string tempDirectory, IAssemblyNameProvider assemblyNameProvider, IFileIO fileIO, IGUIDGenerator guidGenerator) + { + ProjectDirectory = tempDirectory.Replace('\\', '/'); + m_ProjectName = Path.GetFileName(ProjectDirectory); + m_AssemblyNameProvider = assemblyNameProvider; + m_FileIOProvider = fileIO; + m_GUIDProvider = guidGenerator; + } + + /// + /// Syncs the scripting solution if any affected files are relevant. + /// + /// + /// Whether the solution was synced. + /// + /// + /// A set of files whose status has changed + /// + /// + /// A set of files that got reimported + /// + public bool SyncIfNeeded(List affectedFiles, string[] reimportedFiles) + { + Profiler.BeginSample("SolutionSynchronizerSync"); + SetupProjectSupportedExtensions(); + + // Don't sync if we haven't synced before + if (SolutionExists() && HasFilesBeenModified(affectedFiles, reimportedFiles)) + { + var assemblies = m_AssemblyNameProvider.GetAssemblies(ShouldFileBePartOfSolution); + var allProjectAssemblies = RelevantAssembliesForMode(assemblies).ToList(); + var allAssetProjectParts = GenerateAllAssetProjectParts(); + + var affectedNames = affectedFiles.Select(asset => m_AssemblyNameProvider.GetAssemblyNameFromScriptPath(asset)?.Split(new [] {".dll"}, StringSplitOptions.RemoveEmptyEntries)[0]); + var reimportedNames = reimportedFiles.Select(asset => m_AssemblyNameProvider.GetAssemblyNameFromScriptPath(asset)?.Split(new [] {".dll"}, StringSplitOptions.RemoveEmptyEntries)[0]); + var affectedAndReimported = new HashSet(affectedNames.Concat(reimportedNames)); + var assemblyNames = new HashSet(allProjectAssemblies.Select(assembly => Path.GetFileName(assembly.outputPath))); + + foreach (var assembly in allProjectAssemblies) + { + if (!affectedAndReimported.Contains(assembly.name)) + continue; + + SyncProject(assembly, allAssetProjectParts, ParseResponseFileData(assembly), assemblyNames); + } + + Profiler.EndSample(); + return true; + } + + Profiler.EndSample(); + return false; + } + + bool HasFilesBeenModified(List affectedFiles, string[] reimportedFiles) + { + return affectedFiles.Any(ShouldFileBePartOfSolution) || reimportedFiles.Any(ShouldSyncOnReimportedAsset); + } + + static bool ShouldSyncOnReimportedAsset(string asset) + { + return k_ReimportSyncExtensions.Contains(new FileInfo(asset).Extension); + } + + public void Sync() + { + SetupProjectSupportedExtensions(); + GenerateAndWriteSolutionAndProjects(); + } + + public bool SolutionExists() + { + return m_FileIOProvider.Exists(SolutionFile()); + } + + void SetupProjectSupportedExtensions() + { + m_ProjectSupportedExtensions = EditorSettings.projectGenerationUserExtensions; + } + + bool ShouldFileBePartOfSolution(string file) + { + string extension = Path.GetExtension(file); + + // Exclude files coming from packages except if they are internalized. + if (!m_ShouldGenerateAll && IsInternalizedPackagePath(file)) + { + return false; + } + + // Dll's are not scripts but still need to be included.. + if (extension == ".dll") + return true; + + if (file.ToLower().EndsWith(".asmdef")) + return true; + + return IsSupportedExtension(extension); + } + + bool IsSupportedExtension(string extension) + { + extension = extension.TrimStart('.'); + if (k_BuiltinSupportedExtensions.ContainsKey(extension)) + return true; + if (m_ProjectSupportedExtensions.Contains(extension)) + return true; + return false; + } + + static ScriptingLanguage ScriptingLanguageFor(Assembly assembly) + { + return ScriptingLanguageFor(GetExtensionOfSourceFiles(assembly.sourceFiles)); + } + + static string GetExtensionOfSourceFiles(string[] files) + { + return files.Length > 0 ? GetExtensionOfSourceFile(files[0]) : "NA"; + } + + static string GetExtensionOfSourceFile(string file) + { + var ext = Path.GetExtension(file).ToLower(); + ext = ext.Substring(1); //strip dot + return ext; + } + + static ScriptingLanguage ScriptingLanguageFor(string extension) + { + return k_BuiltinSupportedExtensions.TryGetValue(extension.TrimStart('.'), out var result) + ? result + : ScriptingLanguage.None; + } + + public void GenerateAndWriteSolutionAndProjects() + { + // Only synchronize assemblies that have associated source files and ones that we actually want in the project. + // This also filters out DLLs coming from .asmdef files in packages. + var assemblies = m_AssemblyNameProvider.GetAssemblies(ShouldFileBePartOfSolution); + + var allAssetProjectParts = GenerateAllAssetProjectParts(); + + SyncSolution(assemblies); + var allProjectAssemblies = RelevantAssembliesForMode(assemblies).ToList(); + var assemblyNames = new HashSet(allProjectAssemblies.Select(assembly => Path.GetFileName(assembly.outputPath))); + foreach (Assembly assembly in allProjectAssemblies) + { + var responseFileData = ParseResponseFileData(assembly); + SyncProject(assembly, allAssetProjectParts, responseFileData, assemblyNames); + } + + WriteVSCodeSettingsFiles(); + } + + IEnumerable ParseResponseFileData(Assembly assembly) + { + var systemReferenceDirectories = CompilationPipeline.GetSystemAssemblyDirectories(assembly.compilerOptions.ApiCompatibilityLevel); + + Dictionary responseFilesData = assembly.compilerOptions.ResponseFiles.ToDictionary(x => x, x => m_AssemblyNameProvider.ParseResponseFile( + x, + ProjectDirectory, + systemReferenceDirectories + )); + + Dictionary responseFilesWithErrors = responseFilesData.Where(x => x.Value.Errors.Any()) + .ToDictionary(x => x.Key, x => x.Value); + + if (responseFilesWithErrors.Any()) + { + foreach (var error in responseFilesWithErrors) + foreach (var valueError in error.Value.Errors) + { + Debug.LogError($"{error.Key} Parse Error : {valueError}"); + } + } + + return responseFilesData.Select(x => x.Value); + } + + Dictionary GenerateAllAssetProjectParts() + { + Dictionary stringBuilders = new Dictionary(); + + foreach (string asset in m_AssemblyNameProvider.GetAllAssetPaths()) + { + // Exclude files coming from packages except if they are internalized. + // TODO: We need assets from the assembly API + if (!m_ShouldGenerateAll && IsInternalizedPackagePath(asset)) + { + continue; + } + + string extension = Path.GetExtension(asset); + if (IsSupportedExtension(extension) && ScriptingLanguage.None == ScriptingLanguageFor(extension)) + { + // Find assembly the asset belongs to by adding script extension and using compilation pipeline. + var assemblyName = m_AssemblyNameProvider.GetAssemblyNameFromScriptPath(asset); + + if (string.IsNullOrEmpty(assemblyName)) + { + continue; + } + + assemblyName = Path.GetFileNameWithoutExtension(assemblyName); + + if (!stringBuilders.TryGetValue(assemblyName, out var projectBuilder)) + { + projectBuilder = new StringBuilder(); + stringBuilders[assemblyName] = projectBuilder; + } + + projectBuilder.Append(" ").Append(k_WindowsNewline); + } + } + + var result = new Dictionary(); + + foreach (var entry in stringBuilders) + result[entry.Key] = entry.Value.ToString(); + + return result; + } + + bool IsInternalizedPackagePath(string file) + { + if (string.IsNullOrWhiteSpace(file)) + { + return false; + } + + var packageInfo = m_AssemblyNameProvider.FindForAssetPath(file); + if (packageInfo == null) + { + return false; + } + + var packageSource = packageInfo.source; + return packageSource != PackageSource.Embedded && packageSource != PackageSource.Local; + } + + void SyncProject( + Assembly assembly, + Dictionary allAssetsProjectParts, + IEnumerable responseFilesData, + HashSet assemblyNames) + { + SyncProjectFileIfNotChanged(ProjectFile(assembly), ProjectText(assembly, allAssetsProjectParts, responseFilesData, assemblyNames)); + } + + void SyncProjectFileIfNotChanged(string path, string newContents) + { + SyncFileIfNotChanged(path, newContents); + } + + void SyncSolutionFileIfNotChanged(string path, string newContents) + { + SyncFileIfNotChanged(path, newContents); + } + + void SyncFileIfNotChanged(string filename, string newContents) + { + if (m_FileIOProvider.Exists(filename)) + { + var currentContents = m_FileIOProvider.ReadAllText(filename); + + if (currentContents == newContents) + { + return; + } + } + + m_FileIOProvider.WriteAllText(filename, newContents); + } + + string ProjectText( + Assembly assembly, + Dictionary allAssetsProjectParts, + IEnumerable responseFilesData, + HashSet assemblyNames) + { + var projectBuilder = new StringBuilder(); + ProjectHeader(assembly, responseFilesData, projectBuilder); + var references = new List(); + var projectReferences = new List(); + + foreach (string file in assembly.sourceFiles) + { + if (!ShouldFileBePartOfSolution(file)) + continue; + + var extension = Path.GetExtension(file).ToLower(); + var fullFile = EscapedRelativePathFor(file); + if (".dll" != extension) + { + projectBuilder.Append(" ").Append(k_WindowsNewline); + } + else + { + references.Add(fullFile); + } + } + + // Append additional non-script files that should be included in project generation. + if (allAssetsProjectParts.TryGetValue(assembly.name, out var additionalAssetsForProject)) + projectBuilder.Append(additionalAssetsForProject); + + var responseRefs = responseFilesData.SelectMany(x => x.FullPathReferences.Select(r => r)); + foreach (var reference in assembly.compiledAssemblyReferences.Union(responseRefs).Union(references)) + { + string fullReference = Path.IsPathRooted(reference) ? reference : Path.Combine(ProjectDirectory, reference); + AppendReference(fullReference, projectBuilder); + } + + if (0 < assembly.assemblyReferences.Length) + { + projectBuilder.Append(" ").Append(k_WindowsNewline); + projectBuilder.Append(" ").Append(k_WindowsNewline); + foreach (Assembly reference in assembly.assemblyReferences) + { + var referencedProject = reference.outputPath; + + projectBuilder.Append(" ").Append(k_WindowsNewline); + projectBuilder.Append(" {").Append(ProjectGuid(reference.name)).Append("}").Append(k_WindowsNewline); + projectBuilder.Append(" ").Append(reference.name).Append("").Append(k_WindowsNewline); + projectBuilder.Append(" ").Append(k_WindowsNewline); + } + } + + projectBuilder.Append(ProjectFooter()); + return projectBuilder.ToString(); + } + + static void AppendReference(string fullReference, StringBuilder projectBuilder) + { + //replace \ with / and \\ with / + var escapedFullPath = SecurityElement.Escape(fullReference); + escapedFullPath = escapedFullPath.Replace("\\\\", "/"); + escapedFullPath = escapedFullPath.Replace("\\", "/"); + projectBuilder.Append(" ").Append(k_WindowsNewline); + projectBuilder.Append(" ").Append(escapedFullPath).Append("").Append(k_WindowsNewline); + projectBuilder.Append(" ").Append(k_WindowsNewline); + } + + public string ProjectFile(Assembly assembly) + { + var fileBuilder = new StringBuilder(assembly.name); + fileBuilder.Append(".csproj"); + return Path.Combine(ProjectDirectory, fileBuilder.ToString()); + } + + public string SolutionFile() + { + return Path.Combine(ProjectDirectory, $"{m_ProjectName}.sln"); + } + + void ProjectHeader( + Assembly assembly, + IEnumerable responseFilesData, + StringBuilder builder + ) + { + // TODO: .Concat(EditorUserBuildSettings.activeScriptCompilationDefines) + GetProjectHeaderTemplate( + builder, + ProjectGuid(assembly.name), + assembly.name, + string.Join(";", new[] { "DEBUG", "TRACE" }.Concat(assembly.defines).Concat(responseFilesData.SelectMany(x => x.Defines)).Distinct().ToArray()), + assembly.compilerOptions.AllowUnsafeCode | responseFilesData.Any(x => x.Unsafe)); + } + + static string GetSolutionText() + { + return string.Join("\r\n", @"", @"Microsoft Visual Studio Solution File, Format Version {0}", @"# Visual Studio {1}", @"{2}", @"Global", @" GlobalSection(SolutionConfigurationPlatforms) = preSolution", @" Debug|Any CPU = Debug|Any CPU", @" Release|Any CPU = Release|Any CPU", @" EndGlobalSection", @" GlobalSection(ProjectConfigurationPlatforms) = postSolution", @"{3}", @" EndGlobalSection", @" GlobalSection(SolutionProperties) = preSolution", @" HideSolutionNode = FALSE", @" EndGlobalSection", @"EndGlobal", @"").Replace(" ", "\t"); + } + + static string GetProjectFooterTemplate() + { + return string.Join("\r\n", @" ", @" ", @" ", @"", @""); + } + + static void GetProjectHeaderTemplate( + StringBuilder builder, + string assemblyGUID, + string assemblyName, + string defines, + bool allowUnsafe + ) + { + builder.Append(@"").Append(k_WindowsNewline); + builder.Append(@"").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_TargetLanguageVersion).Append("").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_WindowsNewline); + builder.Append(@" Debug").Append(k_WindowsNewline); + builder.Append(@" AnyCPU").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_ProductVersion).Append("").Append(k_WindowsNewline); + builder.Append(@" 2.0").Append(k_WindowsNewline); + builder.Append(@" ").Append(EditorSettings.projectGenerationRootNamespace).Append("").Append(k_WindowsNewline); + builder.Append(@" {").Append(assemblyGUID).Append("}").Append(k_WindowsNewline); + builder.Append(@" Library").Append(k_WindowsNewline); + builder.Append(@" Properties").Append(k_WindowsNewline); + builder.Append(@" ").Append(assemblyName).Append("").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_TargetFrameworkVersion).Append("").Append(k_WindowsNewline); + builder.Append(@" 512").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_BaseDirectory).Append("").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_WindowsNewline); + builder.Append(@" true").Append(k_WindowsNewline); + builder.Append(@" full").Append(k_WindowsNewline); + builder.Append(@" false").Append(k_WindowsNewline); + builder.Append(@" Temp\bin\Debug\").Append(k_WindowsNewline); + builder.Append(@" ").Append(defines).Append("").Append(k_WindowsNewline); + builder.Append(@" prompt").Append(k_WindowsNewline); + builder.Append(@" 4").Append(k_WindowsNewline); + builder.Append(@" 0169").Append(k_WindowsNewline); + builder.Append(@" ").Append(allowUnsafe).Append("").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_WindowsNewline); + builder.Append(@" pdbonly").Append(k_WindowsNewline); + builder.Append(@" true").Append(k_WindowsNewline); + builder.Append(@" Temp\bin\Release\").Append(k_WindowsNewline); + builder.Append(@" prompt").Append(k_WindowsNewline); + builder.Append(@" 4").Append(k_WindowsNewline); + builder.Append(@" 0169").Append(k_WindowsNewline); + builder.Append(@" ").Append(allowUnsafe).Append("").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_WindowsNewline); + builder.Append(@" true").Append(k_WindowsNewline); + builder.Append(@" true").Append(k_WindowsNewline); + builder.Append(@" false").Append(k_WindowsNewline); + builder.Append(@" false").Append(k_WindowsNewline); + builder.Append(@" false").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_WindowsNewline); + builder.Append(@" ").Append(k_WindowsNewline); + } + + void SyncSolution(IEnumerable assemblies) + { + SyncSolutionFileIfNotChanged(SolutionFile(), SolutionText(assemblies)); + } + + string SolutionText(IEnumerable assemblies) + { + var fileversion = "11.00"; + var vsversion = "2010"; + + var relevantAssemblies = RelevantAssembliesForMode(assemblies); + string projectEntries = GetProjectEntries(relevantAssemblies); + string projectConfigurations = string.Join(k_WindowsNewline, relevantAssemblies.Select(i => GetProjectActiveConfigurations(ProjectGuid(i.name))).ToArray()); + return string.Format(GetSolutionText(), fileversion, vsversion, projectEntries, projectConfigurations); + } + + static IEnumerable RelevantAssembliesForMode(IEnumerable assemblies) + { + return assemblies.Where(i => ScriptingLanguage.CSharp == ScriptingLanguageFor(i)); + } + + /// + /// Get a Project("{guid}") = "MyProject", "MyProject.csproj", "{projectguid}" + /// entry for each relevant language + /// + string GetProjectEntries(IEnumerable assemblies) + { + var projectEntries = assemblies.Select(i => string.Format( + m_SolutionProjectEntryTemplate, + SolutionGuid(i), + i.name, + Path.GetFileName(ProjectFile(i)), + ProjectGuid(i.name) + )); + + return string.Join(k_WindowsNewline, projectEntries.ToArray()); + } + + /// + /// Generate the active configuration string for a given project guid + /// + string GetProjectActiveConfigurations(string projectGuid) + { + return string.Format( + m_SolutionProjectConfigurationTemplate, + projectGuid); + } + + string EscapedRelativePathFor(string file) + { + var projectDir = ProjectDirectory.Replace('/', '\\'); + file = file.Replace('/', '\\'); + var path = SkipPathPrefix(file, projectDir); + + var packageInfo = m_AssemblyNameProvider.FindForAssetPath(path.Replace('\\', '/')); + if (packageInfo != null) + { + // We have to normalize the path, because the PackageManagerRemapper assumes + // dir seperators will be os specific. + var absolutePath = Path.GetFullPath(NormalizePath(path)).Replace('/', '\\'); + path = SkipPathPrefix(absolutePath, projectDir); + } + + return SecurityElement.Escape(path); + } + + static string SkipPathPrefix(string path, string prefix) + { + if (path.StartsWith($@"{prefix}\")) + return path.Substring(prefix.Length + 1); + return path; + } + + static string NormalizePath(string path) + { + if (Path.DirectorySeparatorChar == '\\') + return path.Replace('/', Path.DirectorySeparatorChar); + return path.Replace('\\', Path.DirectorySeparatorChar); + } + + string ProjectGuid(string assembly) + { + return m_GUIDProvider.ProjectGuid(m_ProjectName, assembly); + } + + string SolutionGuid(Assembly assembly) + { + return m_GUIDProvider.SolutionGuid(m_ProjectName, GetExtensionOfSourceFiles(assembly.sourceFiles)); + } + + static string ProjectFooter() + { + return GetProjectFooterTemplate(); + } + + static string GetProjectExtension() + { + return ".csproj"; + } + + void WriteVSCodeSettingsFiles() + { + var vsCodeDirectory = Path.Combine(ProjectDirectory, ".vscode"); + + if (!m_FileIOProvider.Exists(vsCodeDirectory)) + m_FileIOProvider.CreateDirectory(vsCodeDirectory); + + var vsCodeSettingsJson = Path.Combine(vsCodeDirectory, "settings.json"); + + if (!m_FileIOProvider.Exists(vsCodeSettingsJson)) + m_FileIOProvider.WriteAllText(vsCodeSettingsJson, k_SettingsJson); + } + } + + public static class SolutionGuidGenerator + { + static MD5 mD5 = MD5CryptoServiceProvider.Create(); + + public static string GuidForProject(string projectName) + { + return ComputeGuidHashFor(projectName + "salt"); + } + + public static string GuidForSolution(string projectName, string sourceFileExtension) + { + if (sourceFileExtension.ToLower() == "cs") + + // GUID for a C# class library: http://www.codeproject.com/Reference/720512/List-of-Visual-Studio-Project-Type-GUIDs + return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"; + + return ComputeGuidHashFor(projectName); + } + + static string ComputeGuidHashFor(string input) + { + var hash = mD5.ComputeHash(Encoding.Default.GetBytes(input)); + return new Guid(hash).ToString(); + } + } +} diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/ProjectGeneration.cs.meta b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/ProjectGeneration.cs.meta new file mode 100644 index 0000000..5039705 --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/ProjectGeneration/ProjectGeneration.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 97d6c87381e3e51488b49f5891490b70 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/Unity.com.unity.vscode.Editor.asmdef b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/Unity.com.unity.vscode.Editor.asmdef new file mode 100644 index 0000000..032da7c --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/Unity.com.unity.vscode.Editor.asmdef @@ -0,0 +1,9 @@ +{ + "name": "Unity.VSCode.Editor", + "references": [], + "optionalUnityReferences": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [] +} diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/Unity.com.unity.vscode.Editor.asmdef.meta b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/Unity.com.unity.vscode.Editor.asmdef.meta new file mode 100644 index 0000000..4c94f56 --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/Unity.com.unity.vscode.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8b845b123ab418448a8be2935fa804e0 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeDiscovery.cs b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeDiscovery.cs new file mode 100644 index 0000000..609d2cd --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeDiscovery.cs @@ -0,0 +1,137 @@ +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 m_Installations; + + public CodeEditor.Installation[] PathCallback() + { + if (m_Installations == null) + { + m_Installations = new List(); + 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 + { + 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 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 + } + } +} diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeDiscovery.cs.meta b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeDiscovery.cs.meta new file mode 100644 index 0000000..cbeca1b --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeDiscovery.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 380f7372e785c7d408552e2c760d269d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeScriptEditor.cs b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeScriptEditor.cs new file mode 100644 index 0000000..f1657cd --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeScriptEditor.cs @@ -0,0 +1,257 @@ +using System; +using System.IO; +using System.Linq; +using System.Diagnostics; +using UnityEditor; +using UnityEngine; +using Unity.CodeEditor; + +namespace VSCodeEditor +{ + [InitializeOnLoad] + public class VSCodeScriptEditor : IExternalCodeEditor + { + const string vscode_argument = "vscode_arguments"; + const string vscode_generate_all = "unity_generate_all_csproj"; + const string vscode_extension = "vscode_userExtensions"; + static readonly GUIContent k_ResetArguments = EditorGUIUtility.TrTextContent("Reset argument"); + string m_Arguments; + + IDiscovery m_Discoverability; + IGenerator m_ProjectGeneration; + + static readonly string[] k_SupportedFileNames = { "code.exe", "visualstudiocode.app", "visualstudiocode-insiders.app", "vscode.app", "code.app", "code.cmd", "code-insiders.cmd", "code", "com.visualstudio.code" }; + + static bool IsOSX => Application.platform == RuntimePlatform.OSXEditor; + + static string DefaultApp => EditorPrefs.GetString("kScriptsDefaultApp"); + + static string DefaultArgument { get; } = "\"$(ProjectPath)\" -g \"$(File)\":$(Line):$(Column)"; + + string Arguments + { + get => m_Arguments ?? (m_Arguments = EditorPrefs.GetString(vscode_argument, DefaultArgument)); + set + { + m_Arguments = value; + EditorPrefs.SetString(vscode_argument, value); + } + } + + static string[] defaultExtensions + { + get + { + var customExtensions = new[] { "json", "asmdef", "log" }; + return EditorSettings.projectGenerationBuiltinExtensions + .Concat(EditorSettings.projectGenerationUserExtensions) + .Concat(customExtensions) + .Distinct().ToArray(); + } + } + + static string[] HandledExtensions + { + get + { + return HandledExtensionsString + .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) + .Select(s => s.TrimStart('.', '*')) + .ToArray(); + } + } + + static string HandledExtensionsString + { + get => EditorPrefs.GetString(vscode_extension, string.Join(";", defaultExtensions)); + set => EditorPrefs.SetString(vscode_extension, value); + } + + public bool TryGetInstallationForPath(string editorPath, out CodeEditor.Installation installation) + { + var lowerCasePath = editorPath.ToLower(); + var filename = Path.GetFileName(lowerCasePath).Replace(" ", ""); + var installations = Installations; + if (!k_SupportedFileNames.Contains(filename)) + { + installation = default; + return false; + } + + if (!installations.Any()) + { + installation = new CodeEditor.Installation + { + Name = "Visual Studio Code", + Path = editorPath + }; + } + else + { + try + { + installation = installations.First(inst => inst.Path == editorPath); + } + catch (InvalidOperationException) + { + installation = new CodeEditor.Installation + { + Name = "Visual Studio Code", + Path = editorPath + }; + } + } + + return true; + } + + public void OnGUI() + { + Arguments = EditorGUILayout.TextField("External Script Editor Args", Arguments); + if (GUILayout.Button(k_ResetArguments, GUILayout.Width(120))) + { + Arguments = DefaultArgument; + } + + var prevGenerate = EditorPrefs.GetBool(vscode_generate_all, false); + + var generateAll = EditorGUILayout.Toggle("Generate all .csproj files.", prevGenerate); + if (generateAll != prevGenerate) + { + EditorPrefs.SetBool(vscode_generate_all, generateAll); + } + + m_ProjectGeneration.GenerateAll(generateAll); + + HandledExtensionsString = EditorGUILayout.TextField(new GUIContent("Extensions handled: "), HandledExtensionsString); + } + + public void CreateIfDoesntExist() + { + if (!m_ProjectGeneration.SolutionExists()) + { + m_ProjectGeneration.Sync(); + } + } + + public void SyncIfNeeded(string[] addedFiles, string[] deletedFiles, string[] movedFiles, string[] movedFromFiles, string[] importedFiles) + { + m_ProjectGeneration.SyncIfNeeded(addedFiles.Union(deletedFiles).Union(movedFiles).Union(movedFromFiles).ToList(), importedFiles); + } + + public void SyncAll() + { + AssetDatabase.Refresh(); + m_ProjectGeneration.Sync(); + } + + public bool OpenProject(string path, int line, int column) + { + if (path != "" && !SupportsExtension(path)) // Assets - Open C# Project passes empty path here + { + return false; + } + + if (line == -1) + line = 1; + if (column == -1) + column = 0; + + string arguments; + if (Arguments != DefaultArgument) + { + arguments = m_ProjectGeneration.ProjectDirectory != path + ? CodeEditor.ParseArgument(Arguments, path, line, column) + : m_ProjectGeneration.ProjectDirectory; + } + else + { + arguments = $@"""{m_ProjectGeneration.ProjectDirectory}"""; + if (m_ProjectGeneration.ProjectDirectory != path && path.Length != 0) + { + arguments += $@" -g ""{path}"":{line}:{column}"; + } + } + + if (IsOSX) + { + return OpenOSX(arguments); + } + + var app = DefaultApp; + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = app, + Arguments = arguments, + WindowStyle = app.EndsWith(".cmd", StringComparison.OrdinalIgnoreCase) ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal, + CreateNoWindow = true, + UseShellExecute = true, + } + }; + + process.Start(); + return true; + } + + static bool OpenOSX(string arguments) + { + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "open", + Arguments = $"-n \"{DefaultApp}\" --args {arguments}", + UseShellExecute = true, + } + }; + + process.Start(); + return true; + } + + static bool SupportsExtension(string path) + { + var extension = Path.GetExtension(path); + if (string.IsNullOrEmpty(extension)) + return false; + return HandledExtensions.Contains(extension.TrimStart('.')); + } + + public CodeEditor.Installation[] Installations => m_Discoverability.PathCallback(); + + public VSCodeScriptEditor(IDiscovery discovery, IGenerator projectGeneration) + { + m_Discoverability = discovery; + m_ProjectGeneration = projectGeneration; + } + + static VSCodeScriptEditor() + { + var editor = new VSCodeScriptEditor(new VSCodeDiscovery(), new ProjectGeneration(Directory.GetParent(Application.dataPath).FullName)); + CodeEditor.Register(editor); + + if (IsVSCodeInstallation(CodeEditor.CurrentEditorInstallation)) + { + editor.CreateIfDoesntExist(); + } + } + + static bool IsVSCodeInstallation(string path) + { + if (string.IsNullOrEmpty(path)) + { + return false; + } + + var lowerCasePath = path.ToLower(); + var filename = Path + .GetFileName(lowerCasePath.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar)) + .Replace(" ", ""); + return k_SupportedFileNames.Contains(filename); + } + + public void Initialize(string editorInstallationPath) { } + } +} diff --git a/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeScriptEditor.cs.meta b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeScriptEditor.cs.meta new file mode 100644 index 0000000..a0aa5a4 --- /dev/null +++ b/Library/PackageCache/com.unity.ide.vscode@1.1.4/Editor/VSCodeScriptEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac3f13489022aa34d861a0320a6917b9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: -- cgit v1.2.3