0

我正在尝试将语言服务器开发为 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;
}

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

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

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

最好的方法是什么?

4

1 回答 1

3

语言服务器协议支持文本同步,参见TextDocumentSyncOptionsinServerCapabilities和相应的方法 ( textDocument/didChange, didChange, didClose...)。语言服务器通常会将所有打开文档的副本保存在内存中。

您链接的示例实际上使用了这个,但是同步本身被抽象到TextDocumentsvscode-languageserver. 因此server.ts,不需要做更多的事情:

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

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

于 2020-01-07T13:57:09.300 回答