godot/modules/mono/editor/GodotSharpTools/Editor/MonoDevelopInstance.cs

146 lines
4.6 KiB
C#

using System;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
namespace GodotSharpTools.Editor
{
public class MonoDevelopInstance
{
public enum EditorId
{
MonoDevelop = 0,
VisualStudioForMac = 1
}
readonly string solutionFile;
readonly EditorId editorId;
Process process;
public void Execute(string[] files)
{
bool newWindow = process == null || process.HasExited;
List<string> args = new List<string>();
string command;
if (Utils.OS.IsOSX())
{
string bundleId = codeEditorBundleIds[editorId];
if (IsApplicationBundleInstalled(bundleId))
{
command = "open";
args.Add("-b");
args.Add(bundleId);
// The 'open' process must wait until the application finishes
if (newWindow)
args.Add("--wait-apps");
args.Add("--args");
}
else
{
command = codeEditorPaths[editorId];
}
}
else
{
command = codeEditorPaths[editorId];
}
args.Add("--ipc-tcp");
if (newWindow)
args.Add("\"" + Path.GetFullPath(solutionFile) + "\"");
foreach (var file in files)
{
int semicolonIndex = file.IndexOf(';');
string filePath = semicolonIndex < 0 ? file : file.Substring(0, semicolonIndex);
string cursor = semicolonIndex < 0 ? string.Empty : file.Substring(semicolonIndex);
args.Add("\"" + Path.GetFullPath(filePath.NormalizePath()) + cursor + "\"");
}
if (newWindow)
{
process = Process.Start(new ProcessStartInfo()
{
FileName = command,
Arguments = string.Join(" ", args),
UseShellExecute = false
});
}
else
{
Process.Start(new ProcessStartInfo()
{
FileName = command,
Arguments = string.Join(" ", args),
UseShellExecute = false
});
}
}
public MonoDevelopInstance(string solutionFile, EditorId editorId)
{
if (editorId == EditorId.VisualStudioForMac && !Utils.OS.IsOSX())
throw new InvalidOperationException($"{nameof(EditorId.VisualStudioForMac)} not supported on this platform");
this.solutionFile = solutionFile;
this.editorId = editorId;
}
[MethodImpl(MethodImplOptions.InternalCall)]
private extern static bool IsApplicationBundleInstalled(string bundleId);
static readonly IReadOnlyDictionary<EditorId, string> codeEditorPaths;
static readonly IReadOnlyDictionary<EditorId, string> codeEditorBundleIds;
static MonoDevelopInstance()
{
if (Utils.OS.IsOSX())
{
codeEditorPaths = new Dictionary<EditorId, string>
{
// Rely on PATH
{ EditorId.MonoDevelop, "monodevelop" },
{ EditorId.VisualStudioForMac, "VisualStudio" }
};
codeEditorBundleIds = new Dictionary<EditorId, string>
{
// TODO EditorId.MonoDevelop
{ EditorId.VisualStudioForMac, "com.microsoft.visual-studio" }
};
}
else if (Utils.OS.IsWindows())
{
codeEditorPaths = new Dictionary<EditorId, string>
{
// XamarinStudio is no longer a thing, and the latest version is quite old
// MonoDevelop is available from source only on Windows. The recommendation
// is to use Visual Studio instead. Since there are no official builds, we
// will rely on custom MonoDevelop builds being added to PATH.
{ EditorId.MonoDevelop, "MonoDevelop.exe" }
};
}
else if (Utils.OS.IsUnix())
{
codeEditorPaths = new Dictionary<EditorId, string>
{
// Rely on PATH
{ EditorId.MonoDevelop, "monodevelop" }
};
}
}
}
}