Update Messaging library and add Godot completion providers

This commit is contained in:
Ignacio Roldán Etcheverry
2020-06-13 13:09:47 +02:00
parent 91ace0246c
commit 88f88d80fd
15 changed files with 376 additions and 180 deletions

9
.editorconfig Normal file
View File

@@ -0,0 +1,9 @@
root = true
[*.cs]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
insert_final_newline = true
csharp_indent_case_contents_when_block = false

View File

@@ -7,7 +7,7 @@ using MonoDevelop.Core.Execution;
using MonoDevelop.Debugger;
using MonoDevelop.Ide;
namespace GodotAddin
namespace GodotAddin.Debugging
{
public class GodotDebuggerEngine : DebuggerEngineBackend
{

View File

@@ -8,15 +8,18 @@ using System.Threading.Tasks;
using Mono.Debugging.Client;
using Mono.Debugging.Soft;
using GodotAddin.Utils;
using GodotTools.IdeMessaging.Requests;
using System.Collections.Generic;
using GodotTools.IdeMessaging;
namespace GodotAddin
namespace GodotAddin.Debugging
{
public class GodotDebuggerSession : SoftDebuggerSession
{
private bool _attached;
private NetworkStream _godotRemoteDebuggerStream;
private GodotExecutionCommand _godotCmd;
private Process _process;
public void SendReloadScripts()
{
@@ -30,7 +33,7 @@ namespace GodotAddin
break;
case ExecutionType.PlayInEditor:
case ExecutionType.Attach:
_godotCmd.GodotIdeClient.SendReloadScripts();
_godotCmd.GodotIdeClient.SendRequest<ReloadScriptsResponse>(new ReloadScriptsRequest());
break;
default:
throw new NotImplementedException(_godotCmd.ExecutionType.ToString());
@@ -50,13 +53,24 @@ namespace GodotAddin
string godotPath = _godotCmd.GodotIdeClient.GodotEditorExecutablePath;
if (string.IsNullOrEmpty(godotPath) || !File.Exists(godotPath))
return Settings.GodotExecutablePath;
if (!string.IsNullOrEmpty(godotPath) && File.Exists(godotPath))
{
// If the setting is not yet assigned any value, set it to the currently connected Godot editor path
if (string.IsNullOrEmpty(Settings.GodotExecutablePath))
Settings.GodotExecutablePath.Value = godotPath;
return godotPath;
}
return godotPath;
return Settings.GodotExecutablePath;
}
protected override async void OnRun(DebuggerStartInfo startInfo)
private void EndSessionWithError(string errorMessage)
{
MonoDevelop.Ide.MessageService.ShowError(errorMessage);
EndSession();
}
protected override void OnRun(DebuggerStartInfo startInfo)
{
var godotStartInfo = (GodotDebuggerStartInfo)startInfo;
@@ -69,14 +83,24 @@ namespace GodotAddin
_attached = false;
StartListening(godotStartInfo, out var assignedDebugPort);
string host = "127.0.0.1";
var godotMessagingClient = _godotCmd.GodotIdeClient;
if (!await _godotCmd.GodotIdeClient.SendPlay(host, assignedDebugPort))
if (!godotMessagingClient.IsConnected)
{
Exit();
EndSessionWithError("No Godot editor instance connected");
return;
}
string host = "127.0.0.1";
var playRequest = new DebugPlayRequest { DebuggerHost = host, DebuggerPort = assignedDebugPort };
_ = godotMessagingClient.SendRequest<DebugPlayResponse>(playRequest)
.ContinueWith(t =>
{
if (t.Result.Status != GodotTools.IdeMessaging.MessageStatus.Ok)
EndSessionWithError($"Received Play response with status: {MessageStatus.Ok}");
});
// TODO: Read the editor player stdout and stderr somehow
break;
@@ -114,7 +138,27 @@ namespace GodotAddin
$",address={host}:{assignedDebugPort}" +
",server=n";
var process = Process.Start(processStartInfo);
_process = new Process { StartInfo = processStartInfo };
try
{
if (!_process.Start())
{
EndSessionWithError("Failed to start Godot process");
return;
}
}
catch (System.ComponentModel.Win32Exception e)
{
EndSessionWithError($"Failed to start Godot process: {e.Message}");
return;
}
if (_process.HasExited)
{
EndSessionWithError($"Godot process exited with code: {_process.ExitCode}");
return;
}
// Listen for StdOut and StdErr
@@ -123,8 +167,10 @@ namespace GodotAddin
Name = "Godot StandardOutput Reader",
IsBackground = true
};
stdOutThread.Start(new ThreadStartArgs {
IsStdErr = false, Stream = process.StandardOutput
stdOutThread.Start(new ThreadStartArgs
{
IsStdErr = false,
Stream = _process.StandardOutput
});
var stdErrThread = new Thread(OutputReader)
@@ -132,11 +178,15 @@ namespace GodotAddin
Name = "Godot StandardError Reader",
IsBackground = true
};
stdErrThread.Start(new ThreadStartArgs {
IsStdErr = true, Stream = process.StandardError
stdErrThread.Start(new ThreadStartArgs
{
IsStdErr = true,
Stream = _process.StandardError
});
OnDebuggerOutput(false, $"Godot PID:{process.Id}{Environment.NewLine}");
_process.Exited += (sender, args) => EndSession();
OnDebuggerOutput(false, $"Godot PID:{_process.Id}{Environment.NewLine}");
break;
}
@@ -161,6 +211,7 @@ namespace GodotAddin
// There is no library to decode this messages, so
// we just pump buffer so it doesn't go out of memory
var readBytes = await _godotRemoteDebuggerStream.ReadAsync(buffer, 0, buffer.Length);
_ = readBytes;
}
}
@@ -178,9 +229,16 @@ namespace GodotAddin
protected override void OnExit()
{
if (_attached)
{
base.OnDetach();
}
else
{
base.OnExit();
if (_process != null && !_process.HasExited)
_process.Kill();
}
}
private void OutputReader(object args)

View File

@@ -1,6 +1,6 @@
using Mono.Debugging.Soft;
namespace GodotAddin
namespace GodotAddin.Debugging
{
public class GodotDebuggerStartInfo : SoftDebuggerStartInfo
{

View File

@@ -1,11 +1,12 @@
using MonoDevelop.Core.Execution;
using GodotTools.IdeMessaging;
using MonoDevelop.Core.Execution;
namespace GodotAddin
namespace GodotAddin.Debugging
{
public class GodotExecutionCommand : ExecutionCommand
{
public GodotExecutionCommand(string godotProjectPath, ExecutionType executionType,
string workingDirectory, GodotMonoDevelopClient godotIdeClient)
string workingDirectory, Client godotIdeClient)
{
GodotProjectPath = godotProjectPath;
ExecutionType = executionType;
@@ -16,7 +17,7 @@ namespace GodotAddin
public string GodotProjectPath { get; }
public ExecutionType ExecutionType { get; }
public string WorkingDirectory { get; }
public GodotMonoDevelopClient GodotIdeClient { get; }
public Client GodotIdeClient { get; }
}
public enum ExecutionType

View File

@@ -1,7 +1,7 @@
using System.Net;
using Mono.Debugging.Soft;
namespace GodotAddin
namespace GodotAddin.Debugging
{
public class GodotSoftDebuggerArgs : SoftDebuggerRemoteArgs
{

View File

@@ -1,6 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net471</TargetFramework>
<TargetFramework>net472</TargetFramework>
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<ItemGroup>
<AddinReference Include="MonoDevelop.Debugger" />
@@ -8,6 +13,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="MonoDevelop.Addins" Version="0.4.7" />
<PackageReference Include="GodotTools.IdeMessaging" Version="1.0.*" />
<PackageReference Include="GodotTools.IdeMessaging" Version="1.1.1" />
</ItemGroup>
</Project>
<ItemGroup>
<Folder Include="GodotMessaging\" />
<Folder Include="Debugging\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="GodotCompletionProviders" Version="1.0.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,40 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using GodotTools.IdeMessaging;
using GodotTools.IdeMessaging.Requests;
using MonoDevelop.Core;
using MonoDevelop.Ide;
using MonoDevelop.Ide.Gui;
namespace GodotAddin.GodotMessaging
{
public class MessageHandler : ClientMessageHandler
{
private static void DispatchToGuiThread(Action action)
{
var d = new SendOrPostCallback((target) => action());
DispatchService.SynchronizationContext.Send(d, null);
}
protected override Task<Response> HandleOpenFile(OpenFileRequest request)
{
DispatchToGuiThread(() =>
{
var fileOpenInfo = new FileOpenInformation(new FilePath(request.File),
project: null /* autodetect */,
line: request.Line ?? 0,
column: request.Column ?? 0,
options: OpenDocumentOptions.Default
);
IdeApp.OpenFiles(new[] { fileOpenInfo });
// Make the Ide window grab focus
IdeApp.Workbench.Present();
});
return Task.FromResult<Response>(new OpenFileResponse { Status = MessageStatus.Ok });
}
}
}

View File

@@ -1,102 +0,0 @@
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using GodotTools.IdeMessaging;
using MonoDevelop.Core;
using MonoDevelop.Ide;
using MonoDevelop.Ide.Gui;
namespace GodotAddin
{
public class GodotMonoDevelopClient : DefaultClient
{
private class MonoDevelopLogger : ILogger
{
public void LogDebug(string message)
{
LoggingService.LogDebug(message);
}
public void LogInfo(string message)
{
LoggingService.LogInfo(message);
}
public void LogWarning(string message)
{
LoggingService.LogWarning(message);
}
public void LogError(string message)
{
LoggingService.LogError(message);
}
public void LogError(string message, Exception e)
{
LoggingService.LogError(message, e);
}
}
private static string DetermineIdentity() => // TODO: Proper detection of whether we are running on VSMac or MD
RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "VisualStudioForMac" : "MonoDevelop";
public GodotMonoDevelopClient(string godotProjectDir)
: base(DetermineIdentity(), godotProjectDir, new MonoDevelopLogger())
{
}
public string GodotEditorExecutablePath => GodotIdeMetadata.EditorExecutablePath;
private static void DispatchToGuiThread(Action action)
{
var d = new SendOrPostCallback((target) => action());
DispatchService.SynchronizationContext.Send(d, null);
}
protected override async Task OpenFile(string file)
{
await OpenFile(file, line: 0, column: 0);
}
protected override async Task OpenFile(string file, int line)
{
await OpenFile(file, line, column: 0);
}
protected override Task OpenFile(string file, int line, int column)
{
DispatchToGuiThread(() =>
{
var fileOpenInfo = new FileOpenInformation(new FilePath(file),
project: null /* autodetect */,
line: line,
column: column,
options: OpenDocumentOptions.Default
);
IdeApp.OpenFiles(new[] {fileOpenInfo});
// Make the Ide window grab focus
IdeApp.Workbench.Present();
});
return Task.CompletedTask;
}
public Task<bool> SendPlay()
{
return WriteMessage(new Message("Play"));
}
public Task<bool> SendPlay(string debuggerHost, int debuggerPort)
{
return WriteMessage(new Message("Play", debuggerHost, debuggerPort.ToString()));
}
public Task<bool> SendReloadScripts()
{
return WriteMessage(new Message("ReloadScripts"));
}
}
}

View File

@@ -6,49 +6,89 @@ namespace GodotAddin
{
public class GodotOptionsPanel : OptionsPanel
{
private readonly FileEntry _godotExeFileEntry = new FileEntry();
private readonly Gtk.CheckButton _alwaysUseExeCheckButton = new Gtk.CheckButton();
private readonly FileEntry _godotExeFile = new FileEntry();
private readonly Gtk.CheckButton _alwaysUseExe = new Gtk.CheckButton { BorderWidth = 10 };
private readonly Gtk.CheckButton _provideNodePathCompletion = new Gtk.CheckButton { BorderWidth = 10 };
private readonly Gtk.CheckButton _provideInputActionCompletion = new Gtk.CheckButton { BorderWidth = 10 };
private readonly Gtk.CheckButton _provideResourcePathCompletion = new Gtk.CheckButton { BorderWidth = 10 };
private readonly Gtk.CheckButton _provideScenePathCompletion = new Gtk.CheckButton { BorderWidth = 10 };
private readonly Gtk.CheckButton _provideSignalNameCompletion = new Gtk.CheckButton { BorderWidth = 10 };
private void AddSection(Gtk.VBox vbox, string text)
{
var hbox = new Gtk.HBox();
var sectionLabel = new Gtk.Label
{
Text = $"<b>{GettextCatalog.GetString(text)}</b>",
UseMarkup = true,
Xalign = 0
};
hbox.PackStart(sectionLabel, false, false, 0);
vbox.PackStart(hbox, false, false, 0);
}
private static void AddFileProperty(Gtk.VBox vbox, string labelText, FileEntry fileEntry, ConfigurationProperty<string> property)
{
var alignment = new Gtk.Alignment(0f, 0f, 1f, 1f) { LeftPadding = 24 };
var innerVBox = new Gtk.VBox();
alignment.Add(innerVBox);
var hbox = new Gtk.HBox(false, 6);
var label = new Gtk.Label
{
Text = GettextCatalog.GetString(labelText),
Xalign = 0
};
hbox.PackStart(label, false, false, 0);
fileEntry.Path = property.Value;
hbox.PackStart(fileEntry, true, true, 0);
innerVBox.PackStart(hbox, false, false, 0);
vbox.PackStart(alignment, false, false, 0);
}
private static void AddCheckProperty(Gtk.VBox vbox, string labelText, Gtk.CheckButton checkButton, ConfigurationProperty<bool> property)
{
var hbox = new Gtk.HBox();
checkButton.Active = property.Value;
hbox.PackStart(checkButton, false, false, 0);
var label = new Gtk.Label
{
Text = GettextCatalog.GetString(labelText),
Xalign = 0
};
hbox.PackStart(label, true, true, 0);
vbox.PackStart(hbox, false, false, 0);
}
public override Control CreatePanelWidget()
{
var vbox = new Gtk.VBox { Spacing = 6 };
var generalSectionLabel = new Gtk.Label
{
Text = $"<b>{GettextCatalog.GetString("General")}</b>",
UseMarkup = true,
Xalign = 0
};
AddSection(vbox, "Debugging");
vbox.PackStart(generalSectionLabel, false, false, 0);
AddCheckProperty(vbox, "Always use this executable.", _alwaysUseExe, Settings.AlwaysUseConfiguredExecutable);
AddFileProperty(vbox, "Godot executable:", _godotExeFile, Settings.GodotExecutablePath);
var godotExeHBox = new Gtk.HBox { BorderWidth = 10, Spacing = 6 };
AddSection(vbox, "Code completion");
var godotExeLabel = new Gtk.Label
{
Text = GettextCatalog.GetString("Godot executable:"),
Xalign = 0
};
godotExeHBox.PackStart(godotExeLabel, false, false, 0);
_godotExeFileEntry.Path = Settings.GodotExecutablePath.Value;
godotExeHBox.PackStart(_godotExeFileEntry, true, true, 0);
vbox.PackStart(godotExeHBox, false, false, 0);
var alwaysUseExeHBox = new Gtk.HBox { BorderWidth = 10, Spacing = 6 };
var alwaysUseExeLabel = new Gtk.Label
{
Text = GettextCatalog.GetString("Always use this executable:"),
Xalign = 0
};
alwaysUseExeHBox.PackStart(alwaysUseExeLabel, false, false, 0);
_alwaysUseExeCheckButton.Active = Settings.AlwaysUseConfiguredExecutable.Value;
alwaysUseExeHBox.PackStart(_alwaysUseExeCheckButton, true, true, 0);
vbox.PackStart(alwaysUseExeHBox, false, false, 0);
AddCheckProperty(vbox, "Provide node path completions.", _provideNodePathCompletion, Settings.ProvideNodePathCompletions);
AddCheckProperty(vbox, "Provide input action completions.", _provideInputActionCompletion, Settings.ProvideInputActionCompletions);
AddCheckProperty(vbox, "Provide resource path completions.", _provideResourcePathCompletion, Settings.ProvideResourcePathCompletions);
AddCheckProperty(vbox, "Provide scene path completions.", _provideScenePathCompletion, Settings.ProvideScenePathCompletions);
AddCheckProperty(vbox, "Provide signal name completions.", _provideSignalNameCompletion, Settings.ProvideSignalNameCompletions);
vbox.ShowAll();
@@ -57,8 +97,14 @@ namespace GodotAddin
public override void ApplyChanges()
{
Settings.GodotExecutablePath.Value = _godotExeFileEntry.Path;
Settings.GodotExecutablePath.Value = _godotExeFileEntry.Path;
Settings.GodotExecutablePath.Value = _godotExeFile.Path;
Settings.AlwaysUseConfiguredExecutable.Value = _alwaysUseExe.Active;
Settings.ProvideNodePathCompletions.Value = _provideNodePathCompletion.Active;
Settings.ProvideInputActionCompletions.Value = _provideInputActionCompletion.Active;
Settings.ProvideResourcePathCompletions.Value = _provideResourcePathCompletion.Active;
Settings.ProvideScenePathCompletions.Value = _provideScenePathCompletion.Active;
Settings.ProvideSignalNameCompletions.Value = _provideSignalNameCompletion.Active;
}
}
}

View File

@@ -1,7 +1,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using GodotAddin.Debugging;
using GodotAddin.GodotMessaging;
using GodotCompletionProviders;
using GodotTools.IdeMessaging;
using MonoDevelop.Core;
using MonoDevelop.Core.Execution;
using MonoDevelop.Ide;
@@ -26,6 +31,9 @@ namespace GodotAddin
ExecutionType.Attach
};
public Client GodotMessagingClient { get; private set; }
public MonoDevelopLogger Logger { get; } = new MonoDevelopLogger();
private static SolutionItemRunConfiguration GetRunConfiguration(ExecutionType type)
{
switch (type)
@@ -41,7 +49,16 @@ namespace GodotAddin
}
}
private GodotMonoDevelopClient _godotIdeClient;
private void OnClientConnected()
{
// If the setting is not yet assigned any value, set it to the currently connected Godot editor path
if (string.IsNullOrEmpty(Settings.GodotExecutablePath))
{
string godotPath = GodotMessagingClient?.GodotEditorExecutablePath;
if (!string.IsNullOrEmpty(godotPath) && File.Exists(godotPath))
Settings.GodotExecutablePath.Value = godotPath;
}
}
protected override void OnItemReady()
{
@@ -55,9 +72,15 @@ namespace GodotAddin
try
{
_godotIdeClient?.Dispose();
_godotIdeClient = new GodotMonoDevelopClient(godotProjectDir);
_godotIdeClient.Start();
string DetermineIdentity() => // TODO: Proper detection of whether we are running on VSMac or MD
RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "VisualStudioForMac" : "MonoDevelop";
GodotMessagingClient?.Dispose();
GodotMessagingClient = new Client(DetermineIdentity(), godotProjectDir, new MessageHandler(), new MonoDevelopLogger());
GodotMessagingClient.Connected += OnClientConnected;
GodotMessagingClient.Start();
BaseCompletionProvider.Context = new GodotProviderContext(this);
}
catch (Exception e)
{
@@ -84,7 +107,7 @@ namespace GodotAddin
var executionType = ExecutionTypes[runConfigurationIndex];
if (executionType == ExecutionType.PlayInEditor && !_godotIdeClient.IsConnected)
if (executionType == ExecutionType.PlayInEditor && !GodotMessagingClient.IsConnected)
LoggingService.LogError($"Cannot launch editor player because the Godot Ide Client is not connected");
string godotProjectPath = GetGodotProjectPath();
@@ -93,7 +116,7 @@ namespace GodotAddin
godotProjectPath,
executionType,
Path.GetDirectoryName(godotProjectPath),
_godotIdeClient
GodotMessagingClient
);
}
@@ -128,9 +151,9 @@ namespace GodotAddin
{
if (runConfiguration == GetRunConfiguration(ExecutionType.PlayInEditor))
{
// 'Play in Editor' requires the Godot Ide Client to be connected
// to a server and the selected run configuration to be 'Debug'.
if (!_godotIdeClient.IsConnected || IdeApp.Workspace.ActiveConfigurationId != "Debug")
// 'Play in Editor' requires the Godot Ide Client to be connected to the server and
// the selected run configuration to be 'Debug' (editor/editor player configuration).
if (!GodotMessagingClient.IsConnected || IdeApp.Workspace.ActiveConfigurationId != "Debug")
return false;
}
@@ -155,6 +178,7 @@ namespace GodotAddin
}
}
}
await base.OnExecuteCommand(monitor, context, configuration, executionCommand);
}
@@ -162,7 +186,7 @@ namespace GodotAddin
{
base.Dispose();
_godotIdeClient?.Dispose();
GodotMessagingClient?.Dispose();
}
}
}

View File

@@ -0,0 +1,57 @@
using System;
using System.Threading.Tasks;
using GodotCompletionProviders;
using GodotTools.IdeMessaging;
using GodotTools.IdeMessaging.Requests;
using ILogger = GodotCompletionProviders.ILogger;
namespace GodotAddin
{
internal class GodotProviderContext : IProviderContext
{
private readonly GodotProjectExtension _extension;
public GodotProviderContext(GodotProjectExtension package)
{
_extension = package;
}
public ILogger GetLogger() => _extension.Logger;
public bool AreCompletionsEnabledFor(CompletionKind completionKind)
{
return completionKind switch
{
CompletionKind.NodePaths => Settings.ProvideNodePathCompletions,
CompletionKind.InputActions => Settings.ProvideInputActionCompletions,
CompletionKind.ResourcePaths => Settings.ProvideResourcePathCompletions,
CompletionKind.ScenePaths => Settings.ProvideScenePathCompletions,
CompletionKind.Signals => Settings.ProvideSignalNameCompletions,
_ => false
};
}
public bool CanRequestCompletionsFromServer()
{
var godotMessagingClient = _extension.GodotMessagingClient;
return godotMessagingClient != null && godotMessagingClient.IsConnected;
}
public async Task<string[]> RequestCompletion(CompletionKind completionKind, string absoluteFilePath)
{
var godotMessagingClient = _extension.GodotMessagingClient;
if (godotMessagingClient == null)
throw new InvalidOperationException();
var request = new CodeCompletionRequest { Kind = (CodeCompletionRequest.CompletionKind)completionKind, ScriptFile = absoluteFilePath };
var response = await godotMessagingClient.SendRequest<CodeCompletionResponse>(request);
if (response.Status == MessageStatus.Ok)
return response.Suggestions;
GetLogger().LogError($"Received code completion response with status '{response.Status}'.");
return new string[] { };
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
using MonoDevelop.Core;
namespace GodotAddin
{
public class MonoDevelopLogger : GodotTools.IdeMessaging.ILogger, GodotCompletionProviders.ILogger
{
public void LogDebug(string message)
{
LoggingService.LogDebug(message);
}
public void LogInfo(string message)
{
LoggingService.LogInfo(message);
}
public void LogWarning(string message)
{
LoggingService.LogWarning(message);
}
public void LogError(string message)
{
LoggingService.LogError(message);
}
public void LogError(string message, Exception e)
{
LoggingService.LogError(message, e);
}
}
}

View File

@@ -5,11 +5,14 @@
id="MonoDevelop.MicroFramework.Debugger"
name="Debugger for Godot"
features="Breakpoints, Pause, Stepping, DebugFile, ConditionalBreakpoints, Tracepoints, Catchpoints, Disassembly"
type="GodotAddin.GodotDebuggerEngine" />
type="GodotAddin.Debugging.GodotDebuggerEngine" />
</Extension>
<Extension path="/MonoDevelop/Ide/GlobalOptionsDialog">
<Section id="Godot" _label="Godot Engine" insertafter="VersionControl">
<Section id="Godot" _label="Godot" insertafter="VersionControl">
<Section id="GodotGeneral" _label="General" fill="true" class="GodotAddin.GodotOptionsPanel" />
</Section>
</Extension>
<Extension path="/MonoDevelop/Ide/TypeService/MefHostServices">
<Assembly file="GodotCompletionProviders.dll"/>
</Extension>
</ExtensionModel>

View File

@@ -21,10 +21,25 @@ namespace GodotAddin
return string.Empty;
}
public static readonly ConfigurationProperty<string> GodotExecutablePath =
ConfigurationProperty.Create("Godot.GodotExecutable", DetermineDefaultGodotPath());
public static readonly ConfigurationProperty<bool> AlwaysUseConfiguredExecutable =
ConfigurationProperty.Create("Godot.AlwaysUseConfiguredExecutable", false);
ConfigurationProperty.Create("Godot.Debugging.AlwaysUseConfiguredExecutable", false);
public static readonly ConfigurationProperty<string> GodotExecutablePath =
ConfigurationProperty.Create("Godot.Debugging.GodotExecutable", DetermineDefaultGodotPath());
public static ConfigurationProperty<bool> ProvideNodePathCompletions { get; set; } =
ConfigurationProperty.Create("Godot.CodeCompletion.ProvideNodePathCompletions", true);
public static ConfigurationProperty<bool> ProvideInputActionCompletions { get; set; } =
ConfigurationProperty.Create("Godot.CodeCompletion.ProvideInputActionCompletions", true);
public static ConfigurationProperty<bool> ProvideResourcePathCompletions { get; set; } =
ConfigurationProperty.Create("Godot.CodeCompletion.ProvideResourcePathCompletions", true);
public static ConfigurationProperty<bool> ProvideScenePathCompletions { get; set; } =
ConfigurationProperty.Create("Godot.CodeCompletion.ProvideScenePathCompletions", true);
public static ConfigurationProperty<bool> ProvideSignalNameCompletions { get; set; } =
ConfigurationProperty.Create("Godot.CodeCompletion.ProvideSignalNameCompletions", true);
}
}