Monaco 编辑器的 registerCompletionItemProvider 移除了默认的本地变量补全。

14
在 Monaco Editor 中,如果使用标准的初始化,例如:
monaco.editor.create(document.getElementById("container"), {
    value: "",
    language: "csharp"
});

将拥有开箱即用的本地变量代码补全功能。例如,使用上面所述的标准初始化方式,并像这样输入代码:

string testVariable = "This is a string";
int aValue = 123;

代码补全功能将识别"testVariable"和"aValue"两个变量,并在代码补全列表中显示它们。

但是,如果我们在初始化中添加registerCompletionItemProvider,就像这样:

//Custom Code Completion function
function createCompleters() {
    return [
        {
            label: 'customFunction1',
            kind: monaco.languages.CompletionItemKind.Function,
            documentation: "My first Custom Function",
            insertText: 'customFunction1()'
        },
        {
            label: 'customFunction2',
            kind: monaco.languages.CompletionItemKind.Function,
            documentation: "My second Custom Function",
            insertText: 'customFunction2()'
        }
    ];
}
//Register the custom completion function into Monaco Editor    
monaco.languages.registerCompletionItemProvider('csharp', {
    provideCompletionItems: function(model, position) {
        return createCompleters();
    }
});
//Continue with the Standard initialization here...
monaco.editor.create(document.getElementById("container"), {
    value: "",
    language: "csharp"
});

此时,本地变量将不再被识别,只有注册的函数被识别。

我如何注册自定义代码完成并仍然保留本地变量完成?谢谢!


你能解决这个问题吗?我也遇到了同样的问题。 - Matt Hintzke
3个回答

2
这条开放式的VSCode问题评论(This comment)很好地解释了该问题。简而言之,CompletionItems是从提供程序列表中获取的,每个提供程序根据其对语言的特定性进行评分。 OPs Provider具体针对'csharp'。一种可能的解决方案是将注册从以下更改: monaco.languages.registerCompletionItemProvider('csharp', {monaco.languages.registerCompletionItemProvider('*', { 在我的情况下,这允许我的自定义建议与基于单词的建议混合使用。 \o/

1

这并不是直接回答问题的方法
几年前我也遇到了同样的问题,并偶然发现了这个 StackOverflow 的问题。由于我在其他地方都没有找到任何答案,因此我在 Monaco 编辑器存储库中提出了一个相同的查询。

我没有找到一种方法来显示一些自定义建议以及 Monaco 默认建议。

我从Alexandru Dima那里得到了这个回复。

我不相信目前可以做到3。 但是从这里的代码https://github.com/microsoft/vscode/blob/8758dc9dddf95f358eb93c969353e5cf245ed1e4/src/vs/editor/contrib/suggest/suggest.ts#L180-L181的阅读中,我可以推断出单词完成提供者位于与自定义完成提供者不同的组中,一旦返回结果,该过程就会停止并且不会被调用。
我无法弄清楚是什么创建了分组,但是我可以在这里看到 -- https://github.com/microsoft/vscode/blob/8758dc9dddf95f358eb93c969353e5cf245ed1e4/src/vs/editor/common/services/editorWorkerServiceImpl.ts#L76 -- 单词完成提供程序已使用 * 作为选择器进行注册。
您可以尝试将您的完成提供程序也注册为 *,然后检查传入的模型并检查它是否具有您的语言,并且仅在它是您的语言时返回结果...也许这会使您的自定义完成提供程序放置在与默认单词完成提供程序相同的组中?
在同一线程中,一些人想出了一些方法来实现。就我个人而言,我没有测试过它们,因为我已经停止了这项工作。但是对于那些遇到这种情况并尝试使用所声称的解决方案进行实验并将其作为答案放在这里以供未来访问者参考,那将是很好的。

在 GitHub 的讨论串中提到的黑科技
第一个
第二个


1
你需要添加一些可以与你的功能相匹配的东西。如果你匹配了所有这些,你将只找到在你的createCompleters()函数中的那些功能。我还没有找到如何根据返回的建议和本地变量进行搜索的方法。下面的代码可以工作,在playground中尝试并开始键入“cu”。我知道这不是完整的答案,但希望能帮助你入门。
//Custom Code Completion function
function createCompleters() {
    return [
        {
            label: 'customFunction1',
            kind: monaco.languages.CompletionItemKind.Function,
            documentation: "My first Custom Function",
            insertText: 'customFunction1()'
        },
        {
            label: 'customFunction2',
            kind: monaco.languages.CompletionItemKind.Function,
            documentation: "My second Custom Function",
            insertText: 'customFunction2()'
        }
    ];
}
//Register the custom completion function into Monaco Editor    
monaco.languages.registerCompletionItemProvider('csharp', {
    provideCompletionItems: function(model, position) {

        var textUntilPosition = model.getValueInRange({startLineNumber: position.lineNumber, startColumn: 1, endLineNumber: position.lineNumber, endColumn: position.column});
        var match = textUntilPosition.match(/cu/gim);
        var suggestions = match ? createCompleters() : [];
        return {
            suggestions: suggestions
        };

        return createCompleters();
    }
});
//Continue with the Standard initialization here...
monaco.editor.create(document.getElementById("container"), {
    value: "",
    language: "csharp"
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接