← На главную

Emacs 29: eglot встроен, пользователь чинит баги Kotlin/Scala Lisp-советами

21.07.2026 10:04 · hackernews

Emacs 29 сделал eglot встроенным LSP-клиентом по умолчанию. Он лёгкий и быстрый, но минималистичный — если LSP-сервер работает странно, eglot не предлагает миллион тумблеров, а ждёт, что вы разберётесь через Emacs Lisp. Автор разобрал свою конфигурацию eglot из репозитория heks-emacs, которую использует для Scala и Kotlin (и немного Java).

Главный посыл: годами считалось, что для JVM-языков нужен IntelliJ IDEA. Но IntelliJ — монолитная Java-программа, которая жрёт 8+ ГБ RAM и вешает систему при индексации. Emacs с eglot действует по‑другому: eglot — это тонкий транспортный слой, который говорит с серверами по JSON-RPC. Если в IntelliJ баг с автодополнением Kotlin, вы ждёте патча от JetBrains. В Emacs вы пишете 10 строк Lisp-совета, перехватываете JSON-RPC прямо в редакторе и чините баг на лету.

Настройка начинается с хуков: eglot-ensure вешается на все нужные режимы (scala-ts-mode, kotlin-ts-mode, markdown-mode, yaml-mode и т.д.), а eglot-format-buffer — на before-save, чтобы код форматировался автоматически. Клавиши автора — под C-c i (мнемоника «IDE»).

Под :config автор удаляет стандартные определения серверов и добавляет свои: для Scala (Metals) с флагами -Xmx4G и -XX:+UseZGC, для Kotlin — intellij-server --stdio. В eglot-workspace-configuration он передаёт настройки прямо серверам: для Metals включает inlay hints для выведенных типов и параметров, для YAML — маппинг JSON-схем, для Rust — clippy и включение proc macro.

Самые интересные костыли — на уровне JSON-RPC. Один баг Kotlin LSP: сервер возвращает textEdit с пустым newText, из-за чего eglot стирает завершаемое слово. Автор перехватывает и jsonrpc-request, и jsonrpc-async-request, и если видит пустой newText, просто выкидывает textEdit, заставляя eglot использовать обычное префиксное совпадение.

Второй баг — навигация по исходникам Kotlin: сервер возвращает URI в формате jar:///path/to/library.jar!/File.kt. Emacs такое не понимает. Автор вешает :around-совет на eglot-uri-to-path и eglot-path-to-uri — заменяет jar:/// на jar:file:/// и обратно, а jarchive открывает такие jar-файлы как обычные буферы.

Для Scala Metals автор отключает семантическое обновление токенов — оно вызывает мерцание и лишнюю нагрузку на CPU. Он советует eglot-client-capabilities, выставляя :refreshSupport в :json-false.

Всё это работает в изолированных окружениях через Nix flake и direnv. Автор показывает flake.nix для Kotlin и Scala, а затем грузит флейк через .envrc и emacs-direnv, что позволяет динамически переключать контексты LSP. Вывод: eglot не заставляет вас терпеть плохое поведение сервера — вы используете Emacs, поэтому силу даёт Lisp.

Читать оригинал →