5.9 KiB
LSP-серверы — api.editor
Запуск серверов целиком настраивается Lua-сценарием. Редактор предоставляет только клиент по stdio, синхронизацию документов и доставку диагностики.
Запуск сервера
api.editor:run_lsp({
name = "gopls", -- условное имя для stop/restart
cmd = "gopls", -- путь к бинарнику или имя в PATH
args = { "serve" }, -- аргументы процесса
env = { GOFLAGS = "-mod=mod" }, -- переменные окружения
languages = { "go" }, -- какие languageId обслуживает
watcher = "**/*.go", -- шаблон файлового вотчера
root = ".", -- корень workspace (по умолчанию cwd)
initialization_options = {}, -- initializationOptions сервера
})
| Метод | Описание |
|---|---|
api.editor:run_lsp(config) |
Запустить сервер по описанию |
api.editor:lsp_servers() |
Имена запущенных серверов: { "gopls", ... } |
api.editor:stop_lsp("gopls") |
Остановить сервер; true, если сервер был запущен |
api.editor:restart_lsp("gopls") |
Перезапустить сервер с прежними настройками |
api.editor:on_lsp_diagnostics(delay_ms, fn) |
Обработчик диагностики всех серверов; nil вместо fn удаляет его |
cmd обязателен. Если root не задан или относителен, он отсчитывается от
текущего рабочего каталога процесса. Поле watcher принимает строку, таблицу
или boolean:
watcher = "**/*.go"
watcher = { pattern = "**/*.go", ignore = { "vendor/**" } }
watcher = true -- все файлы, игнорируя только стандартные каталоги сборки
--configменяет только каталогinit.lua, поэтомуroot = "."указывает на текущий каталог запуска — проект должен быть текущим рабочим каталогом.
Автодополнение и подсказки
Автодополнение включается само при вводе идентификатора; Ctrl/Cmd+Space
открывает список вручную. Поведение клавиш описано в keymap.md и
может быть переопределено через api.keymap:map_completion_key.
Документация выбранного элемента показывается второй всплывающей панелью
справа от списка. Наведение мыши показывает Markdown-документацию символа.
Диагностику, которую сервер присылает после правок, редактор подчёркивает волнистой линией: ошибки — красной, предупреждения и остальные сообщения — жёлтой. Подчёркивание работает и при выключенной подсветке синтаксиса.
Обработчик диагностики
api.editor:on_lsp_diagnostics(delay_ms, fn) регистрирует один обработчик на
все LSP-серверы. delay_ms — пауза тишины: если сообщения приходят чаще,
вызовы пропускаются, а обработчик получает последний снимок после того, как
обновления прекратились. Если зарегистрировать обработчик, когда диагностика
уже накоплена, он сработает сразу после этой паузы.
api.editor:on_lsp_diagnostics(1000, function(servers)
for _, entry in ipairs(servers) do
print(entry.server, entry.path, #entry.diagnostics)
end
end)
servers — массив записей по одной на пару «документ, сервер»:
{
server = "gopls", -- имя сервера, приславшего диагностику
uri = "file:///project/main.go", -- URI документа
path = "/project/main.go", -- путь файла; nil для не-file URI
diagnostics = {
{
line = 0, character = 2, -- начало (с нуля, как в LSP)
end_line = 0, end_character = 8,
severity = 1, -- 1 ошибка, 2 предупреждение, 3 info, 4 hint
severity_name = "error", -- error | warning | information | hint
message = "undefined: foo",
source = "gopls",
code = "UndeclaredName",
tags = {}, -- unnecessary, deprecated
},
},
}
Позиции нумеруются с нуля; для отображения прибавляйте единицу к line и
character. Остановка сервера удаляет его сообщения из следующих снимков.
Пример из init.lua с защитой от ошибки запуска:
local gopls_ok, gopls_err = pcall(function()
api.editor:run_lsp({
name = "gopls",
cmd = "gopls",
args = { "serve" },
root = ".",
languages = { "go" },
watcher = { pattern = "**/*.go", ignore = { "vendor/**" } },
initialization_options = {
usePlaceholders = true,
completeUnimported = true,
},
})
end)
if not gopls_ok then
print("[lsp] gopls не запущен: " .. tostring(gopls_err))
end