简体   繁体   English

使用 RESTful Webservice 完成 Monaco 编辑器代码

[英]Monaco Editor Code Completion with RESTful Webservice

I would like to implement a custom CompletionItemProvider for Monaco Editor 0.8.3, that is fetching completion suggestions from a RESTful webservice.我想为 Monaco Editor 0.8.3 实现一个自定义 CompletionItemProvider,即从 RESTful web 服务中获取完成建议。 For this, I would like to use jQuery 3.2.1.为此,我想使用 jQuery 3.2.1。

  • I have implemented a class implementing the monaco.languages.CompletionItemProvider interface.我已经实现了一个实现monaco.languages.CompletionItemProvider接口的类。
  • As calls to the webservice are asynchronous, I cannot directly return CompletionItem[] from the provideCompletionItems() method.由于对 Web 服务的调用是异步的,因此我无法直接从provideCompletionItems()方法返回CompletionItem[] Hence I guess I have to return a monaco.Thenable<monaco.languages.CompletionItem[]> -object.因此我想我必须返回一个monaco.Thenable<monaco.languages.CompletionItem[]>
  • Unfortunately documentation regarding the use of Thenable is very sparse .不幸的是, 关于使用Thenable文档非常稀少。 I guess, monaco.Promise class is kind of default implementation for the Thenable interface.我猜, monaco.Promise类是Thenable接口的默认实现。 As I have found one example using this class , I gave it a shot...由于我发现了一个使用此类的示例,因此我试了一下...

Here is the relevant code (below is the full code)这是相关代码(以下是完整代码)

                return new monaco.Promise<monaco.languages.CompletionItem[]>(function (c, e, p) {
                    req = $.getJSON("/codeeditorapi/objectcompletions/" + objAndProp[0]);
                    req.done(function (data) {
                        console.log("objectcompletions c(data) with " + data);
                        c(data);
                    });
                    req.fail((data) => e(data));
                }, function () {
                    req.abort();
                });

And now the full code of the class现在是该类的完整代码

class MMSObjectModelCompletionProvider implements monaco.languages.CompletionItemProvider
{

    private PVAN:string = "v";//PlantVariableAccessor Name
    public provideCompletionItems(model: monaco.editor.IReadOnlyModel, position: monaco.Position, token: monaco.CancellationToken): monaco.Thenable<monaco.languages.CompletionItem[]> | monaco.languages.CompletionItem[]{
        var line = model.getValueInRange({ startLineNumber: position.lineNumber, startColumn: 1, endLineNumber: position.lineNumber, endColumn: position.column });
        let pos = line.lastIndexOf(this.PVAN+".");
        if (pos < 0 || line.length < pos + this.PVAN.length+1) //+1 for the dot behind
        {
            return [];
        }

        let objAndProp: string[] = line.substr(pos + this.PVAN.length + 1).split(".");
        let ret: monaco.languages.CompletionItem[];
        var req: JQueryXHR;
        switch (objAndProp.length)
        {
            case 3:
                //Only append the value
                return [
                {
                    label: "Value",
                    kind: monaco.languages.CompletionItemKind.Property,
                    detail: "Access Value of plant variable",
                },
                ];
            case 2:
                //objectname finished, search for property
                if (objAndProp[0].length == 0 || objAndProp[1].length == 0) return [];
                return new monaco.Promise<monaco.languages.CompletionItem[]>(function (c, e, p) {
                    req = $.getJSON("/codeeditorapi/propertycompletions/" + objAndProp[0] + "/" + objAndProp[1]);
                    req.done(function (data) {
                        console.log("propertycompletions c(data) with " + data);
                        c(data);
                    });
                    req.fail((data) => e(data));
                }, function () {
                    req.abort();
                });
            case 1:
                //search for object name
                if (objAndProp[0].length == 0) return [];
                return new monaco.Promise<monaco.languages.CompletionItem[]>(function (c, e, p) {
                    req = $.getJSON("/codeeditorapi/objectcompletions/" + objAndProp[0]);
                    req.done(function (data) {
                        console.log("objectcompletions c(data) with " + data);
                        c(data);
                    });
                    req.fail((data) => e(data));
                }, function () {
                    req.abort();
                });
            default: return [];
        }
    }
}

Well, the webservice gets called properly and return the expected array with CompletionItems.好吧,webservice 被正确调用并返回带有 CompletionItems 的预期数组。 I can see the console.log output.我可以看到 console.log 输出。 However, the call c(data) raises somewhere deep in the library the following error.但是,调用c(data)在库深处的某个地方引发了以下错误。

Uncaught Error: Cannot read property 'length' of undefined

TypeError: Cannot read property 'length' of undefined
at Object.S [as compareIgnoreCase] (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:33:4808)
at _ (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:74:21918)
at C (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:74:22403)
at Array.sort (native)
at http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:74:21249
at Object.g [as _notify] (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:35:5529)
at Object.enter (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:35:9107)
at n.Class.derive._creator._run (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:35:10935)
at n.Class.derive._creator._completed (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:35:10376)
at n.Class.define.cancel.then (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:35:12368)
at Object.S [as compareIgnoreCase] (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:33:4808)
at _ (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:74:21918)
at C (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:74:22403)
at Array.sort (native)
at http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:74:21249
at Object.g [as _notify] (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:35:5529)
at Object.enter (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:35:9107)
at n.Class.derive._creator._run (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:35:10935)
at n.Class.derive._creator._completed (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:35:10376)
at n.Class.define.cancel.then (http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:35:12368)
at http://localhost:58254/Scripts/monaco-editor-0.8.3/min/vs/editor/editor.main.js:33:25360

I have no clue, what to do now.我不知道,现在该怎么办。 Any help or hints are appreciated.任何帮助或提示表示赞赏。 Thank you so much!非常感谢!

For anyone still looking for an answer, it looks like the provideCompletionItems method can just return a Promise with the expected value, and Monaco editor shows Loading... in the completion box until the promise resolves.对于仍在寻找答案的任何人来说, provideCompletionItems方法似乎可以只返回具有预期值的 Promise,并且 Monaco 编辑器在完成框中显示Loading...直到 Promise 解决。

So for your case in particular, just return a Promise inside of which you fire your request to the web service.因此,特别是对于您的情况,只需返回一个 Promise,您可以在其中向 Web 服务发出请求。 Also, the provideCompletionItems method should return an object with a suggestions property with an array of your completions.此外, provideCompletionItems方法应该返回一个带有suggestions属性的对象,其中包含您的完成数组。 return { suggestions: [...] }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM