123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- 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_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;
- }
- EditorGUILayout.LabelField("Generate .csproj files for:");
- EditorGUI.indentLevel++;
- SettingsButton(ProjectGenerationFlag.Embedded, "Embedded packages", "");
- SettingsButton(ProjectGenerationFlag.Local, "Local packages", "");
- SettingsButton(ProjectGenerationFlag.Registry, "Registry packages", "");
- SettingsButton(ProjectGenerationFlag.Git, "Git packages", "");
- SettingsButton(ProjectGenerationFlag.BuiltIn, "Built-in packages", "");
- #if UNITY_2019_3_OR_NEWER
- SettingsButton(ProjectGenerationFlag.LocalTarBall, "Local tarball", "");
- #endif
- SettingsButton(ProjectGenerationFlag.Unknown, "Packages from unknown sources", "");
- RegenerateProjectFiles();
- EditorGUI.indentLevel--;
- HandledExtensionsString = EditorGUILayout.TextField(new GUIContent("Extensions handled: "), HandledExtensionsString);
- }
- void RegenerateProjectFiles()
- {
- var rect = EditorGUI.IndentedRect(EditorGUILayout.GetControlRect(new GUILayoutOption[] { }));
- rect.width = 252;
- if (GUI.Button(rect, "Regenerate project files"))
- {
- m_ProjectGeneration.Sync();
- }
- }
- void SettingsButton(ProjectGenerationFlag preference, string guiMessage, string toolTip)
- {
- var prevValue = m_ProjectGeneration.AssemblyNameProvider.ProjectGenerationFlag.HasFlag(preference);
- var newValue = EditorGUILayout.Toggle(new GUIContent(guiMessage, toolTip), prevValue);
- if (newValue != prevValue)
- {
- m_ProjectGeneration.AssemblyNameProvider.ToggleProjectGeneration(preference);
- }
- }
- 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) || !File.Exists(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) { }
- }
- }
|