Elixir LSP в Claude Code: настройка для контейнеров

Image description

Суть проблемы

Claude Code имеет встроенный LSP tool, но он несовместим с Lexical (новый официальный LS) из-за client/registerCapability. Совместим только ElixirLS (старый, сторонний).


Архитектура решения

Claude Code (LSP tool)
        │
        │ JSON-RPC / stdio
        ▼
elixir-lsp плагин
        │ запускает
        ▼
/opt/elixir-ls/language_server.sh   ← ElixirLS бинарник
        │
        │ анализирует
        ▼
Elixir проект (mix.exs)
.elixir_ls/   ← кэш индекса (персистентный)

Что нужно установить

1. ElixirLS бинарник

# В Dockerfile или setup скрипте
RUN mkdir -p /opt/elixir-ls && \
    cd /opt/elixir-ls && \
    curl -L https://github.com/elixir-lsp/elixir-ls/releases/download/v0.30.0/elixir-ls-v0.30.0.zip \
      -o elixir-ls.zip && \
    unzip elixir-ls.zip && \
    rm elixir-ls.zip && \
    chmod +x language_server.sh

# Добавить в PATH
ENV PATH="/opt/elixir-ls:$PATH"

Версию проверить на: https://github.com/elixir-lsp/elixir-ls/releases

2. Плагин elixir-lsp в Claude Code

# Установить плагин (внутри контейнера, один раз)
claude plugin install elixir-lsp

После установки плагин регистрирует ElixirLS как LSP-сервер для .ex, .exs, .heex, .eex, .leex.


Что происходит при старте сессии

claude запускается
    │
    ├─ читает плагины → находит elixir-lsp
    │
    ├─ спавнит: /opt/elixir-ls/language_server.sh
    │           (отдельный OS-процесс)
    │
    └─ ElixirLS инициализируется:
           1. Читает mix.exs
           2. Компилирует зависимости (первый раз ~2-5 мин)
           3. Строит индекс символов
           4. Пишет кэш → .elixir_ls/
           5. Готов (~9000+ символов для PhoenixKit)

Важно: Первый запуск в новом контейнере медленный. Последующие — быстрые (кэш из .elixir_ls/).


Проверка работоспособности

После старта сессии Claude Code — попросить выполнить проверку:

Use the LSP tool to run documentSymbol on lib/.ex

Ожидаемый результат:

  • Список функций файла → LSP активен
  • Ошибка “No LSP server” → ElixirLS не найден или не запустился

Для полной проверки — workspaceSymbol (возвращает тысячи символов после индексации):

Use the LSP tool: workspaceSymbol on any project file

Типичные проблемы

Симптом Причина Решение
“No LSP server available” ElixirLS не найден в PATH Проверить /opt/elixir-ls/language_server.sh, добавить в PATH
“requires restart” после /reload-plugins Нормально — LSP стартует при следующем запуске claude Перезапустить claude (не TMUX)
workspaceSymbol → 0 результатов Индексация ещё не завершена Подождать 1-2 мин, повторить
LSP зависает навсегда Попытка использовать Lexical вместо ElixirLS Lexical несовместим, использовать только ElixirLS
Медленная индексация Первый запуск, нет .elixir_ls/ кэша Нормально, ждать 2-5 мин

Персистентность кэша между сессиями

Контейнер
├── /opt/elixir-ls/          ← монтировать или билдить в image
│   └── language_server.sh
│
└── /app/                    ← проект
    └── .elixir_ls/          ← МОНТИРОВАТЬ как volume
        ├── build/           (скомпилированные .beam)
        └── dialyzer/        (PLT файлы, большие)

Если .elixir_ls/ не персистентный — каждое пересоздание контейнера = полная переиндексация.

# docker-compose.yml
volumes:
  - ./:/app
  - elixir_ls_cache:/app/.elixir_ls   # ← важно

volumes:
  elixir_ls_cache:

Минимальный чеклист

  • [ ] ElixirLS установлен в /opt/elixir-ls/ (или любой PATH-доступный путь)
  • [ ] Плагин elixir-lsp установлен: claude plugin install elixir-lsp
  • [ ] .elixir_ls/ персистентный (volume или не в gitignore если нужен кэш)
  • [ ] Первый запуск — подождать индексацию (1-5 мин)
  • [ ] Lexical НЕ использовать с LSP tool — несовместим