Lua 的丰富 Intellisense

Rich Intellisense for Lua

我正在为我的 C# 程序使用 Monaco 编辑器,我想知道如何为 Lua 添加丰富的智能感知。 例如,如果我输入一些东西,它会要求输入它。

首先,我必须说这显然并不容易,需要付出巨大的努力。基本上,你必须自己分析代码,然后根据你通过分析收集到的信息提出建议。

我无法详细说明您可以或应该如何分析代码,因为这是一项艰巨的任务。当您分析代码时,您将必须了解什么是什么,而您(可能)无法通过一些简单的正则表达式来做到这一点。一个非常复杂的例子是 TypeScript integration but there are more simple examples, for example the HTML plugin。我只能建议去那里看看以获取灵感。

分析完代码后,基本上就可以开始了。然后,您可以猜测用户下一步想做什么,或者,例如,建议他们当前正在访问的对象的方法或字段。

然后您可以建议完成,这是通过将 JSON 对象交给 Monaco 来完成的(实际上是一个 TypeScript class,但稍后会详细介绍)。有一个 example at the Monaco Playground 显示了如何做到这一点。一个简约的提供者可能看起来像这样:

monaco.languages.registerCompletionItemProvider ("lua", {    // Or any other language...
  provideCompletionItems: (model, position) => {
    // Retrieve the text until the current cursor's position, anything
    // after that doesn't really matter.
    var textToMatch = model.getValueInRange ({
      startLineNumber: 1,
      startColumn: 1,
      endLineNumber: position.lineNumber,
      endColumn: position.column
    });

    // Return JSON array containing all completion suggestions.
    return {
      suggestions: [
        // Example: io.write ()
        {
          label: "io.write (string)",
          kind: monaco.languages.CompletionItemKind.Function,
          documentation: "Writes a string to stdout.",
          insertText: "io.write (\"\")"  // Escape JSON as needed.
        },  // Other items.
      ]
    };
  }
});

查看关于 CompletionItemKind for the different types of completion items and on CompletionItemProvider for the "class" which we hand over as a JSON object to registerCompletionItemProvider (). The Monaco documentation has all these different types and classes because Monaco is originally written in TypeScript 的摩纳哥文档,但这些 class 类型和类型也可以与普通的旧 JSON 对象相似。

您基本上可以通过调用所有不同的 register...Provider () 函数 documented here.

"construct" "rich" IntelliSense 提供程序

如果你想要真正有用的 IntelliSense,那么我建议不要忘记 registerSignatureHelpProvider () 方法,当鼠标悬停在某个类型上时它会显示 "peek definition" windows有可用的定义。

总之,这是一项非常繁琐的工作。如果您查看负责 TypeScript IntelliSense 的文件(TypeScript 集成存储库中的src/lib/typescriptServices.js),它的大小为 6.51 MB。尽管它还包含一个格式化程序等,但它会让您对所需的工作以及为什么我不能在这里详细介绍实现 IntelliSense 有一个很好的印象。

可以考虑连接一个Lualanguage server into Monaco via the help of TypeFox's monaco-languageclient库。不过,这仍然不容易。

在当前版本 0.17.1 中,返回的对象中需要额外的 range 属性:

return {
   suggestions: [
   // Example: io.write ()
   {
       label: "io.write (string)",
       kind: monaco.languages.CompletionItemKind.Function,
       documentation: "Writes a string to stdout.",
       insertText: "io.write (\"\")",  // Escape JSON as needed.
       range: {
          startLineNumber: position.lineNumber,
          endLineNumber: position.lineNumber,
          startColumn: position.column,
          endColumn: position.column
       }
   },  // Other items.
   ]
};