VSCode: 获取语言服务器中的编辑器内容

VSCode: obtain editor content in Language Server

我正在尝试为 VS Code 中的新语言开发语言服务器,我正在使用 Microsoft 示例作为参考 (https://github.com/microsoft/vscode-extension-samples/tree/master/lsp-sample)。

在他们的示例中,自动完成是在这段代码中完成的:

connection.onCompletion(
    (_textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => {
        // The pass parameter contains the position of the text document in
        // which code complete got requested. For the example we ignore this
        // info and always provide the same completion items. 
        return [
            {
                label: 'TypeScript',
                kind: CompletionItemKind.Text,
                data: 1
            },
            {
                label: 'JavaScript',
                kind: CompletionItemKind.Text,
                data: 2
            }
        ];
    }
);

正如评论所说,这是一个愚蠢的自动完成系统,因为它总是提供相同的建议。

我可以看到有一个类型为 TextDocumentPositionParams 的输入参数,该类型具有以下接口:

export interface TextDocumentPositionParams {
    /**
     * The text document.
     */
    textDocument: TextDocumentIdentifier;
    /**
     * The position inside the text document.
     */
    position: Position;
}

它有光标位置和一个 TextDocumentIdentifier 但最后一个只有一个 uri 属性.

我想创建一个智能自动完成系统,基于光标位置单词的对象类型。

这个示例非常有限,我有点迷路了。我想我可以阅读 uri 属性 中的文件,并且根据光标位置我可以找出我应该建议的项目。但是当文件没有保存时​​呢?如果我读取文件,我会读取磁盘上的数据,而不是当前显示在编辑器中的数据。

最好的方法是什么?

Language Server Protocol支持文本同步,参见ServerCapabilities中的TextDocumentSyncOptions及相应的方法(textDocument/didChangedidChangedidClose... ).语言服务器通常会在内存中保留所有打开文档的副本。

您链接的示例实际上使用了它,但同步本身被抽象到 vscode-languageserverTextDocuments class 中。因此 server.ts 不需要做比这更多的事情:

let documents: TextDocuments = new TextDocuments();
[...]
documents.listen(connection);

然后您可以简单地使用 documents.get(uri).getText() 来获取编辑器中显示的文本。