Автор Xulun
В статье Быстрый запуск подключаемых модулей VSCode: протокол языкового сервера мы представили базовую структуру и некоторые преимущества протокола LSP, а также принцип трехстороннего установления связи, связанный с использованием протокола.
В этой части этой серии руководств мы начнем с простейшего функционального протокола из множества различных протоколов LSP, который используется для «отправки уведомления в VSCode».
Сообщение окна LSP
Что касается протокола LSP, вы можете видеть, что предоставляются три протокола, связанных с окнами, а именно следующие протоколы:
- окно / Уведомление о ShowMessage
- window / showMessage Запрос
- window / logMessage Уведомление
Мы можем использовать функцию Connection.window.sendxxxMessage
для отправки сообщений клиенту. В зависимости от степени серьезности сообщения можно разделить на три различных уровня: информация, предупреждение и ошибка.
Например, мы можем отправить сообщение клиенту после завершения трехстороннего рукопожатия между клиентом и сервером (то есть после onInitialized
).
connection.onInitialized(() => {
connection.window.showInformationMessage('Hello World! form server side');
});
Результат показан следующим образом:
Автозавершение кода
Давайте «разогреемся» с помощью окна уведомления, чтобы проверить сбой соединения. Затем мы переходим непосредственно к одной из тем, которые нас больше всего интересуют: автозавершение кода.
Форма завершения кода на самом деле очень проста. Входными данными является TextDocumentPositionParams
, а выходными данными - массивом CompletionItem
. Эта функция зарегистрирована в connection.onCompletion
:
connection.onCompletion(
(_textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => {});
Основная структура данных, используемая при автозавершении кода, показана на следующем рисунке:
Свойство «kind» определяется перечислением, которое является одним из многих доступных типов.
Не позволяйте этому вас запугать. Давайте посмотрим на простой пример. На самом деле, базовый метод реализации довольно прост:
connection.onCompletion( (_textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => { connection.console.log('[xulun]Position:' + _textDocumentPosition.textDocument);
return [ { label: 'TextView', kind: CompletionItemKind.Text, data: 1 }, { label: 'Button', kind: CompletionItemKind.Text, data: 2 }, { label: 'ListView', kind: CompletionItemKind.Text, data: 3 } ]; } )
Детали завершения
Помимо textDocument/completion
для заполнения информации, LSP также поддерживает запрос completionItem/resolve
. И вход, и выход CompletionItem
, и возвращается дополнительная информация.
Поддержка запроса completionItem/resolve
может быть зарегистрирована методом connection.onCompletionResolve
:
connection.onCompletionResolve(
(item: CompletionItem): CompletionItem => {
if (item.data === 1) {
item.detail = 'TextView';
item.documentation = 'TextView documentation';
} else if (item.data === 2) {
item.detail = 'Button';
item.documentation = 'JavaScript documentation';
} else if (item.data === 3) {
item.detail = 'ListView';
item.documentation = 'ListView documentation';
}
return item;
}
)
Эффект такой:
Информация о местоположении в параметрах завершения
Входной параметр содержит информацию о местоположении для отправки запроса на завершение. Мы можем использовать эту информацию для управления информацией, которую необходимо заполнить.
Вот пример:
connection.onCompletion(
(_textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => {
return [
{
label: 'TextView' + _textDocumentPosition.position.character,
kind: CompletionItemKind.Text,
data: 1
},
{
label: 'Button' + _textDocumentPosition.position.line,
kind: CompletionItemKind.Text,
data: 2
},
{
label: 'ListView',
kind: CompletionItemKind.Text,
data: 3
}
];
}
)
В это время мы не только завершаем имя виджета, но также добавляем текущий номер строки или номер столбца.
Ниже приводится операция завершения Button. Текущий номер строки будет добавлен к информации о завершении. Завершение запускается в строке 934, поэтому подсказка для завершения изменяется на Button933: