VSCode: получить содержимое редактора на Language Server - PullRequest
0 голосов
/ 07 января 2020

Я пытаюсь разработать 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 и, основываясь на позиции курсора, я мог бы определить, какие пункты мне следует предложить. Но как насчет того, когда файл не сохраняется? Если бы я прочитал файл, я бы прочитал данные, которые находятся на диске, а не то, что в данный момент отображается в редакторе.

Какой лучший способ сделать это?

1 Ответ

1 голос
/ 07 января 2020

Протокол Language Server поддерживает синхронизацию текста, см. TextDocumentSyncOptions in ServerCapabilities и соответствующие методы (textDocument/didChange, didChange, didClose ...). Языковой сервер обычно хранит копии всех открытых документов в памяти.

Пример, который вы связали, фактически использует это, но сама синхронизация абстрагируется в класс TextDocuments из vscode-languageserver. В результате server.ts не нужно делать намного больше, чем это:

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

Затем вы можете просто использовать documents.get(uri).getText(), чтобы получить текст, показанный в редакторе.

...