Resolves #38 Add CodeLens Providers

Cleans-up the CommandHandler to take objects again
This commit is contained in:
Michael A. Hawker 2020-04-06 01:29:26 -07:00
Родитель 783fbd4d94
Коммит e9d40d4993
13 изменённых файлов: 201 добавлений и 10 удалений

Просмотреть файл

@ -11,7 +11,7 @@ namespace Monaco
/// <summary>
/// Action delegate for <see cref="CodeEditor.AddCommandAsync(int, CommandHandler)"/> and <see cref="CodeEditor.AddCommandAsync(int, CommandHandler, string)"/>.
/// </summary>
public delegate void CommandHandler([ReadOnlyArray] string[] parameters);
public delegate void CommandHandler([ReadOnlyArray] object[] parameters);
/// <summary>
/// This file contains Monaco IEditor method implementations we can call on our control.
@ -122,7 +122,23 @@ namespace Monaco
public IAsyncOperation<string> AddCommandAsync(int keybinding, CommandHandler handler, string context)
{
var name = "Command" + keybinding;
_parentAccessor.RegisterActionWithParameters(name, (parameters) => { handler?.Invoke(parameters); });
_parentAccessor.RegisterActionWithParameters(name, (parameters) =>
{
if (parameters != null && parameters.Length > 0)
{
object[] args = new object[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
args[i] = JsonConvert.DeserializeObject<object>(parameters[i]);
}
handler?.Invoke(args);
}
else
{
handler?.Invoke(new object[] {});
}
});
return InvokeScriptAsync<string>("addCommand", new object[] { keybinding, name, context }).AsAsyncOperation();
}

Просмотреть файл

@ -22,6 +22,7 @@
<div id="container" onkeydown="keyDown(event)"></div>
<script src="ms-appx-web:///Monaco/monaco-editor/min/vs/loader.js"></script>
<script src="ms-appx-web:///Monaco/ts-helpermethods/registerCodeLensProvider.js"></script>
<script src="ms-appx-web:///Monaco/ts-helpermethods/registerColorProvider.js"></script>
<script src="ms-appx-web:///Monaco/ts-helpermethods/registerCompletionItemProvider.js"></script>
<script src="ms-appx-web:///Monaco/ts-helpermethods/otherScriptsToBeOrganized.js"></script>

Просмотреть файл

@ -0,0 +1,17 @@
using Newtonsoft.Json;
namespace Monaco.Languages
{
public sealed class CodeLens
{
[JsonProperty("command", NullValueHandling = NullValueHandling.Ignore)]
public Command Command { get; set; }
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
public string Id { get; set; }
[JsonProperty("range", NullValueHandling = NullValueHandling.Ignore)]
public IRange Range { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,11 @@
namespace Monaco.Languages
{
using Newtonsoft.Json;
public sealed class CodeLensList // IDisposible?
{
[JsonProperty("lenses", NullValueHandling = NullValueHandling.Ignore)]
public CodeLens[] Lenses { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,15 @@
using Monaco.Editor;
using System;
using System.ComponentModel;
using Windows.Foundation;
namespace Monaco.Languages
{
public interface CodeLensProvider
{
IAsyncOperation<CodeLensList> ProvideCodeLensesAsync(IModel model);
IAsyncOperation<CodeLens> ResolveCodeLensAsync(IModel model, CodeLens codeLens);
}
}

Просмотреть файл

@ -44,6 +44,43 @@ namespace Monaco
return null;
}
public IAsyncAction RegisterCodeLensProviderAsync(string languageId, CodeLensProvider provider)
{
if (_editor.TryGetTarget(out CodeEditor editor))
{
editor._parentAccessor.RegisterEvent("ProvideCodeLenses" + languageId, async (args) =>
{
var list = await provider.ProvideCodeLensesAsync(editor.GetModel());
if (list != null)
{
return JsonConvert.SerializeObject(list);
}
return null;
});
editor._parentAccessor.RegisterEvent("ResolveCodeLens" + languageId, async (args) =>
{
if (args != null && args.Length >= 1)
{
var lens = await provider.ResolveCodeLensAsync(editor.GetModel(), JsonConvert.DeserializeObject<CodeLens>(args[0]));
if (lens != null)
{
return JsonConvert.SerializeObject(lens);
}
}
return null;
});
return editor.InvokeScriptAsync("registerCodeLensProvider", new object[] { languageId }).AsAsyncAction();
}
return null;
}
public IAsyncAction RegisterColorProviderAsync(string languageId, DocumentColorProvider provider)
{
if (_editor.TryGetTarget(out CodeEditor editor))

Просмотреть файл

@ -210,6 +210,9 @@
<Compile Include="Monaco\IRange.cs" />
<Compile Include="Monaco\KeyCode.cs" />
<Compile Include="Monaco\KeyMod.cs" />
<Compile Include="Monaco\Languages\CodeLens.cs" />
<Compile Include="Monaco\Languages\CodeLensList.cs" />
<Compile Include="Monaco\Languages\CodeLensProvider.cs" />
<Compile Include="Monaco\Languages\Command.cs" />
<Compile Include="Monaco\Languages\CompletionContext.cs" />
<Compile Include="Monaco\Languages\ColorPresentation.cs" />
@ -266,6 +269,10 @@
<TypeScriptCompile Include="ts-helpermethods\Monaco.Helpers.ParentAccessor.ts">
<SubType>Designer</SubType>
</TypeScriptCompile>
<TypeScriptCompile Include="ts-helpermethods\registerCodeLensProvider.ts">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</TypeScriptCompile>
<TypeScriptCompile Include="ts-helpermethods\registerColorProvider.ts">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>

Просмотреть файл

@ -29,11 +29,11 @@ var addAction = function (action: monaco.editor.IActionDescriptor) {
};
var addCommand = function (keybindingStr, handlerName, context) {
return editor.addCommand(parseInt(keybindingStr), (args) => {
return editor.addCommand(parseInt(keybindingStr), function () {
let objs = [];
if (args) {
for (let i = 0; i < args.length; i++) {
objs.push(JSON.stringify(args[i]));
if (arguments) { // Use arguments as Monaco will pass each as it's own parameter, so we don't know how many that may be.
for (let i = 1; i < arguments.length; i++) { // Skip first one as that's the sender?
objs.push(JSON.stringify(arguments[i]));
}
}
Parent.callActionWithParameters(handlerName, objs);
@ -124,4 +124,4 @@ var keyDown = function (event) {
event.stopImmediatePropagation();
return false;
}
};
};

Просмотреть файл

@ -0,0 +1,22 @@
///<reference path="../monaco-editor/monaco.d.ts" />
declare var Parent: ParentAccessor;
var registerCodeLensProvider = function (languageId) {
return monaco.languages.registerCodeLensProvider(languageId, {
provideCodeLenses: function (model, token) {
return Parent.callEvent("ProvideCodeLenses" + languageId, []).then(result => {
if (result) {
return JSON.parse(result);
}
});
},
resolveCodeLens: function (model, codeLens, token) {
return Parent.callEvent("ResolveCodeLens" + languageId, [JSON.stringify(codeLens)]).then(result => {
if (result) {
return JSON.parse(result);
}
});
}
// TODO: onDidChange, don't know what this does.
});
}

Просмотреть файл

@ -0,0 +1,55 @@
using Monaco;
using Monaco.Editor;
using Monaco.Languages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Windows.Foundation;
namespace MonacoEditorTestApp.Helpers
{
public class EditorCodeLensProvider : CodeLensProvider
{
private string _commandId;
public EditorCodeLensProvider(string commandId)
{
_commandId = commandId;
}
public IAsyncOperation<CodeLensList> ProvideCodeLensesAsync(IModel model)
{
return AsyncInfo.Run(async delegate (CancellationToken cancellationToken)
{
return new CodeLensList()
{
Lenses = new CodeLens[] {
new CodeLens()
{
Id = "Second Line",
Range = new Range(2, 1, 3, 1),
Command = new Command()
{
Id = _commandId,
Title = "Second Line Command",
Arguments = new object[] { "Arg 1" , 5, new float[] { 4.5f, 0.3f } }, // Note: This 3rd element array will come back as a JArray TODO?
Tooltip = "This is a CodeLens Command"
}
}
}
};
});
}
public IAsyncOperation<CodeLens> ResolveCodeLensAsync(IModel model, CodeLens codeLens)
{
return AsyncInfo.Run(delegate (CancellationToken cancelationToken) {
return Task.FromResult(codeLens);
});
}
}
}

Просмотреть файл

@ -8,6 +8,7 @@ using System.Diagnostics;
using System.Linq;
using Windows.Storage;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.Popups;
using Windows.UI.Text;
using Windows.UI.Xaml;
@ -101,6 +102,15 @@ namespace MonacoEditorTestApp
var available_languages = Editor.Languages.GetLanguagesAsync();
//Debugger.Break();
// Code Lens Action
string cmdId = await Editor.AddCommandAsync(0, async (args) =>
{
var md = new MessageDialog("You hit the CodeLens command " + args[0].ToString());
await md.ShowAsync();
});
await Editor.Languages.RegisterCodeLensProviderAsync("csharp", new EditorCodeLensProvider(cmdId));
await Editor.Languages.RegisterColorProviderAsync("csharp", new ColorProvider());
await Editor.Languages.RegisterCompletionItemProviderAsync("csharp", new LanguageProvider());
@ -264,8 +274,7 @@ namespace MonacoEditorTestApp
// You can now do this with a Command as well, see above.
// Skip await, so we can read intercept value.
#pragma warning disable CS4014
Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, async () =>
_ = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, async () =>
{
var md = new MessageDialog("You Hit Ctrl+Enter!");
await md.ShowAsync();
@ -273,7 +282,6 @@ namespace MonacoEditorTestApp
// Refocus on CodeEditor
Editor.Focus(FocusState.Programmatic);
});
#pragma warning restore CS4014
// Intercept input so we don't add a newline.
e.Handled = true;

Просмотреть файл

@ -96,6 +96,7 @@
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="Helpers\EditorCodeLensProvider.cs" />
<Compile Include="Helpers\ColorProvider.cs" />
<Compile Include="Helpers\EditorHoverProvider.cs" />
<Compile Include="Helpers\LanguageProvider.cs" />

Просмотреть файл

@ -17,6 +17,7 @@ The following Monaco Editor features are currently supported by this component b
- [Markers](https://microsoft.github.io/monaco-editor/api/modules/monaco.editor.html#setmodelmarkers) and [Decorations](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.imodeldeltadecoration.html) (See #35)
- [Actions](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandalonecodeeditor.html#addaction) and [Commands](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandalonecodeeditor.html#addcommand)
- Basic [Language Features](https://code.visualstudio.com/api/language-extensions/programmatic-language-features)
- [CodeLens](https://microsoft.github.io/monaco-editor/api/modules/monaco.languages.html#registercodelensprovider) (onDidChange not supported)
- [Color](https://microsoft.github.io/monaco-editor/api/modules/monaco.languages.html#registercolorprovider)
- [CompletionItem](https://microsoft.github.io/monaco-editor/api/modules/monaco.languages.html#registercompletionitemprovider) (IntelliSense, Snippets)
- [Hover](https://microsoft.github.io/monaco-editor/api/modules/monaco.languages.html#registerhoverprovider)