Открыть сервис

Language Server Protocol

Language Server Protocol (LSP, Протокол языкового сервера) — это открытый протокол на основе JSON-RPC, определяющий взаимодействие между редактором кода или интегрированной средой разработки (IDE) и сервером, предоставляющим функции анализа исходного кода. LSP стандартизирует обмен данными для таких операций, как автодополнение, переход к определению, поиск ссылок, диагностика ошибок и рефакторинг, независимо от конкретного языка программирования и клиентского приложения.

История

До появления LSP каждый редактор или IDE требовал написания отдельного плагина для поддержки каждого языка программирования. Это приводило к дублированию усилий: разработчики языковых инструментов были вынуждены адаптировать свои решения под множество сред (Visual Studio Code, Emacs, Vim, Atom, Sublime Text, JetBrains и другие).

Протокол был разработан компанией Microsoft в 2016 году для проекта Visual Studio Code. Первая спецификация (версия 3.0) была опубликована в июне 2016 года. Идея заключалась в том, чтобы вынести логику анализа кода из редактора в отдельный процесс — языковой сервер, который общается с редактором через стандартизированный протокол. Это позволило Microsoft сосредоточиться на улучшении поддержки множества языков в VS Code, а сообществу — создавать универсальные серверы, работающие с любыми клиентами.

В 2017 году спецификация LSP была передана в комитет по стандартизации. В 2021 году Microsoft выпустила версию 3.17, которая добавила поддержку семантических токенов, встроенных фрагментов кода и улучшенную диагностику. На 2024 год актуальной является версия 3.18, находящаяся в стадии черновика.

Архитектура

Протокол реализует модель «клиент-сервер». Роль клиента выполняет редактор кода или IDE, роль сервера — отдельный процесс, запускаемый для каждого языка программирования.

Клиентская часть

Клиент (редактор) отвечает за:

  • Запуск и управление жизненным циклом языкового сервера (запуск, остановка, перезапуск).
  • Отображение результатов анализа (подсветка ошибок, автодополнение, подсказки).
  • Обработку пользовательских действий (ввод текста, открытие/закрытие файлов, перемещение курсора) и отправку соответствующих запросов серверу.

Серверная часть

Языковой сервер — это независимое приложение, которое содержит логику анализа конкретного языка. Он получает от клиента:

  • Текущее содержимое открытых файлов.
  • Позицию курсора.
  • События изменения текста.

Сервер обрабатывает эти данные и возвращает клиенту структурированные ответы: список возможных завершений, определение символа, диагностические сообщения (ошибки, предупреждения) и т.д.

Транспортный уровень

Обмен данными осуществляется по протоколу JSON-RPC 2.0 через:

  • Стандартный ввод/вывод (stdio) — наиболее распространённый способ, когда сервер запускается как дочерний процесс редактора.
  • TCP-сокеты — используется для удалённых серверов или в средах, где не поддерживается stdio.
  • Каналы (pipes) — на платформах, где они доступны.

Каждое сообщение состоит из заголовка (Content-Length: <число>\r\n\r\n) и тела в формате JSON.

Основные возможности

Протокол определяет несколько категорий запросов и уведомлений:

Диагностика

Сервер может асинхронно отправлять клиенту список ошибок, предупреждений и информационных сообщений для открытых файлов. Клиент отображает их в виде подчёркиваний или значков на полях редактора.

  • Переход к определению — поиск места объявления символа.
  • Поиск ссылок — все места использования символа в проекте.
  • Просмотр реализации — для интерфейсов и абстрактных классов.
  • Просмотр типа — получение информации о типе выражения.

Автодополнение

Сервер предлагает список возможных завершений на основе контекста (тип переменной, импорты, доступные методы). Клиент может отображать их с иконками, описаниями и документацией.

Рефакторинг

  • Переименование символа — глобальное переименование с учётом области видимости.
  • Извлечение метода/переменной — создание новой функции или переменной на основе выделенного фрагмента.
  • Организация импортов — автоматическое добавление/удаление импортов.

Семантическая подсветка

Версия 3.17 ввела поддержку семантических токенов. Сервер может передавать клиенту информацию о типе токена (ключевое слово, тип, функция, переменная, параметр) и его модификаторах (статический, абстрактный, депрекейтед). Клиент использует это для более точной подсветки синтаксиса.

Прочие возможности

  • Подсказки при наведении — отображение документации и типов при наведении курсора на символ.
  • Форматирование кода — запрос на форматирование всего файла или выделенного фрагмента.
  • Свёртка кода — определение областей, которые можно свернуть (функции, классы, блоки).
  • Сниппеты — встраивание шаблонов кода с заполняемыми полями.

Реализации

На 2024 год существует множество языковых серверов, реализующих LSP для различных языков программирования:

ЯзыкСерверРазработчик
Pythonpyright, python-lsp-serverMicrosoft, сообщество
JavaScript/TypeScripttypescript-language-serverMicrosoft
Rustrust-analyzerСообщество Rust
GogoplsGoogle
Javaeclipse.jdt.lsEclipse Foundation
C/C++clangdLLVM Project
Kotlinkotlin-language-serverСообщество
RubysolargraphСообщество
PHPintelephense, phpactorСообщество
Haskellhaskell-language-serverСообщество

Большинство современных редакторов поддерживают LSP «из коробки» или через плагины: Visual Studio Code, Neovim, Emacs (через eglot или lsp-mode), Sublime Text (через LSP-пакет), Helix, Zed, Kate, GNOME Builder и другие.

Преимущества и недостатки

Преимущества

  • Универсальность — один сервер работает с любым клиентом, поддерживающим LSP.
  • Снижение затрат — разработчикам языковых инструментов не нужно писать отдельные плагины для каждого редактора.
  • Модульность — языковой сервер может быть написан на любом языке, независимо от языка редактора.
  • Изоляция — сервер работает в отдельном процессе, что повышает стабильность редактора (сбой сервера не приводит к падению редактора).

Недостатки

  • Задержки — при каждом изменении текста клиент отправляет данные серверу, что может вызывать задержки на больших файлах или медленных серверах.
  • Сложность отладки — диагностика проблем взаимодействия клиента и сервера требует понимания JSON-RPC и протокола.
  • Ограниченная функциональность — не все возможности редактора могут быть реализованы через LSP (например, сложные рефакторинги или визуальные инструменты).

Влияние на экосистему

Внедрение LSP привело к значительному упрощению разработки языковых инструментов. До его появления поддержка нового языка в редакторе требовала месяцев работы; теперь достаточно написать один сервер, и он будет работать во всех популярных средах. Это способствовало появлению качественных инструментов для многих языков, включая нишевые (например, ReasonML, OCaml, F#).

Протокол также стимулировал развитие альтернативных протоколов, таких как Debug Adapter Protocol (DAP) для отладки и Profile Adapter Protocol (PAP) для профилирования, построенных по аналогичной архитектуре.

Источники

  • Microsoft. LSP Specification (версия 3.17). Официальная документация.
  • Microsoft. Language Server Protocol Overview. 2016.
  • GitHub. LSP Specification Repository. История изменений и обсуждения.
  • Статья «How the Language Server Protocol changed the editor landscape» на сайте InfoQ.
  • Документация rust-analyzer, gopls, clangd.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →