Zed, добавление русского словаря в cSpell

MacOS

Я постепенно перехожу с vs code на zed. Мне для работы с claude code достаточно простой консоли и приложения для просмотра файлов. vs code штука хорошая, но достаточно медленная.

В zed всякие spell checkers подключаются как модули. Их там несколько и у всех есть различные проблемы. Самый простой по подключению к zed, по моему мнению — это cSpell. Но… У него в поставке по умолчанию нет русского словаря. И как его туда впихнуть, совсем непонятно.

Т.е. стандартная рекомендация: создайте файл ~/.cspell.json и добавтье в него:

{
"language": "en-EN,ru-RU",
}

не подходит. Словаря то нет. Да и ошибки в описании локали как то не заметил.

Хорошо, что под рукой есть claude code на этой же машине. Запрос:

Проблема проверка русского языка в Zed. Установлен cspell  есть файл ~/.cspell.json cspell сервер стартует, но все русские слова подчеркиваются как не правильные

В ответ

Проблема ясна. Две причины:

1. Пакет русского словаря не установлен — @cspell/dict-ru_ru отсутствует
2. Неправильные имена словарей в конфиге — cspell использует ru_RU (с подчёркиванием), а не ru-RU. Также en-EN не
  существует, нужен en_US

Вывод cspell trace "привет" подтверждает: русский словарь не подключён, слово не найдено ни в одном словаре.

Исправляем. Сначала установим словарь:

Дальше, в течении 5-ти минут он находит решение и все заработало.

Ниже привожу инструкцию, сгенеированную им для устранения прболемы на MacOs.

# Добавление русского языка в cspell (Zed editor)

## Проблема

cspell в Zed по умолчанию не включает русский словарь. Пакет `@cspell/dict-ru_ru` не входит в `@cspell/cspell-bundled-dicts`, поэтому даже при указании `"language": "en,ru"` русские слова не распознаются.

## Решение (пошагово)

### 1. Установить пакет русского словаря

```bash
cd ~/Library/Application\ Support/Zed/extensions/work/cspell
npm install @cspell/dict-ru_ru
```

Словарь устанавливается в node_modules расширения cspell для Zed.

### 2. Настроить cspell конфиг

Создать/обновить `~/.cspell.json` (глобальный конфиг для всех проектов):

```json
{
  "language": "en,ru",
  "dictionaryDefinitions": [
    {
      "name": "ru-ru",
      "path": "~/Library/Application Support/Zed/extensions/work/cspell/node_modules/@cspell/dict-ru_ru/ru_ru.trie.gz"
    }
  ],
  "dictionaries": ["ru-ru"]
}
```

### 3. Перезапустить Zed или перезагрузить cspell LSP

## Ключевые моменты

- **Имена словарей**: русский словарь регистрируется как `"ru-ru"` (нижний регистр, дефис). НЕ `"ru-RU"`.
- **Английский**: `Английский bundled и включается автоматически через `"language": "en,ru"`.
- **`import` не работает** для абсолютных путей к небандленным словарям — используй `dictionaryDefinitions` + `dictionaries`.
- **`language`** задаёт локаль для languageSettings, но без `dictionaryDefinitions` словарь не подключится, т.к. он не bundled.
- **Глобальный конфиг**: `~/.cspell.json` — cspell ищет конфиг вверх по дереву директорий.
- **Путь Zed extension**: `~/Library/Application Support/Zed/extensions/work/cspell/node_modules/`
- **cspell-ext.json** словаря находится в `@cspell/dict-ru_ru/cspell-ext.json`, но `import` из конфига его не подхватывает.

## Проверка

```bash
cd ~/Library/Application\ Support/Zed/extensions/work/cspell
node -e "
async function main() {
  const lib = await import('cspell-lib');
  const defaults = await lib.getDefaultBundledSettingsAsync();
  const config = await lib.searchForConfig(process.env.HOME + '/');
  const merged = lib.mergeSettings(defaults, config || {});
  const s = lib.constructSettingsForText(merged, 'привет мир', 'markdown');
  const dict = await lib.getDictionary(s);
  console.log('привет:', dict.has('привет'));  // true
  console.log('мир:', dict.has('мир'));        // true
  console.log('ошибко:', dict.has('ошибко'));  // false
}
main();
"
```

Windows

Процедура почти идентична, но пути другие, плюс есть пара нюансов с оболочками (PowerShell против Git Bash) и с тем, в каком файле лежат настройки в актуальной версии cspell.

Дальше предполагается, что общую идею вы уже поняли из Linux-версии, поэтому здесь акцент на отличиях для Windows.

Предварительные требования

  • Zed с установленным из галереи расширением cspell;
  • Node.js и npm (Zed и так использует их для расширений, поэтому обычно уже стоят).
npm --version

Где лежит расширение на Windows

В Linux это ~/.local/share/zed/extensions/work/cspell, а на Windows

%LOCALAPPDATA%\Zed\extensions\work\cspell

Для пользователя auser полный путь выглядит так:

C:\Users\auser\AppData\Local\Zed\extensions\work\cspell

В примерах ниже используется именно он — подставьте своё имя пользователя.

Шаг 1. Устанавливаем словарь

PowerShell:

cd $env:LOCALAPPDATA\Zed\extensions\work\cspell
npm install @cspell/dict-ru_ru

Git Bash:

cd "$LOCALAPPDATA/Zed/extensions/work/cspell"
npm install @cspell/dict-ru_ru

После выполнения в node_modules\@cspell\dict-ru_ru\ появится файл ru_ru.trie.gz — это и есть словарь.

Шаг 2. Правим конфиг bundled-словарей

Файл cspell-default.json. В актуальной версии cspell (8.19+) этот файл превратился в тонкую обёртку, которая просто импортирует реальные настройки из cspell-default.config.js. Поэтому править нужно именно .config.js.

Полный путь:

node_modules\@cspell\cspell-bundled-dicts\cspell-default.config.js

2.0. Резервная копия (обязательно)

PowerShell:

cd $env:LOCALAPPDATA\Zed\extensions\work\cspell\node_modules\@cspell\cspell-bundled-dicts
Copy-Item cspell-default.config.js cspell-default.config.js.bak

Git Bash:

cd "$LOCALAPPDATA/Zed/extensions/work/cspell/node_modules/@cspell/cspell-bundled-dicts"
cp cspell-default.config.js cspell-default.config.js.bak

2.1. Локаль по умолчанию

-    language: 'en',
+    language: 'en,ru',

2.2. Добавляем словарь в активный список

-    dictionaries: ['companies', 'softwareTerms', 'public-licenses', 'filetypes'],
+    dictionaries: ['companies', 'softwareTerms', 'public-licenses', 'filetypes', 'ru-ru'],

2.3. Подключаем cspell-ext.json русского словаря

В массиве import находим строку с dict-rust и добавляем сразу после неё импорт русского словаря (внимание на подчёркивания — именно _ru_ru):

         '@cspell/dict-rust/cspell-ext.json',
+        '@cspell/dict-ru_ru/cspell-ext.json',
         '@cspell/dict-shell/cspell-ext.json',

Шаг 3. Проверяем, что настройки применились

Самый простой способ убедиться, что правки прочитались, — прямо в Zed открыть cspell-default.config.js и сверить три изменённых блока. Если хочется программно, удобнее всего из Git Bash (PowerShell плохо переваривает многострочные node -e с кавычками):

cd "$LOCALAPPDATA/Zed/extensions/work/cspell" && node --input-type=module -e "import { getDefaultSettings } from 'cspell-lib';
const s = await getDefaultSettings();
console.log('language:', s.language);
console.log('ru-ru active:', (s.dictionaries || []).includes('ru-ru'));
const ru = (s.dictionaryDefinitions || []).find(d => d.name === 'ru-ru');
console.log('ru-ru path:', ru ? ru.path : 'NOT FOUND');"

Ожидаемый вывод (путь приведён для пользователя auser):

language: en,
ruru-ru active: true
ru-ru path: C:\Users\auser\AppData\Local\Zed\extensions\work\cspell\node_modules\@cspell\dict-ru_ru\ru_ru.trie.gz

В PowerShell без Git Bash можно хотя бы убедиться, что строки попали в файл:

cd $env:LOCALAPPDATA\Zed\extensions\work\cspell\node_modules\@cspell\cspell-bundled-dicts
Select-String -Path cspell-default.config.js -Pattern "en,ru","'ru-ru'","dict-ru_ru"

Должны увидеть все три совпадения.

Шаг 4. Перезапускаем Zed

Закройте Zed полностью — не reload через командную палитру, а именно закройте все окна и откройте заново. Нужно, чтобы перезапустился LSP-сервер cspell и подхватил новые настройки.

Откройте markdown-файл с русским текстом. Корректные слова (приветпредложение) подчёркиваться не должны, опечатки (опечятка) — должны.

Нюансы и отличия от MacOS/Linux

  1. Пути. ~/.local/share/zed/... → %LOCALAPPDATA%\Zed\.... В JSON/JS-строках обратные слеши надо экранировать (\\) либо использовать прямые (/) — Windows понимает оба варианта.
  2. Где настройки. В актуальной версии cspell реальные настройки лежат в cspell-default.config.js, а cspell-default.json только импортирует его. Если у вас cspell постарше — правьте cspell-default.json, как в оригинальной статье.
  3. Оболочка. PowerShell и cmd плохо переваривают многострочные команды с кавычками. Для установок и копирований они вполне годятся, а для проверок через node -e удобнее Git Bash. Сами правки конфига можно делать в любом редакторе — хоть в самом Zed.
  4. package.json расширения. npm install сам допишет @cspell/dict-ru_ru в зависимости расширения, поэтому при будущих обновлениях словарь подтянется автоматически и переустанавливать его вручную не нужно. Но: при крупном обновлении самого расширения, когда node_modules пересоздаётся с нуля, правки cspell-default.config.js слетят вместе с .bak-копией. Поэтому полезно держать ещё одну копию правленого файла где-то вне node_modules (например, в D:\backup\cspell-default.config.js) и при апдейте быстро возвращать.
  5. Кодировка. Сохраняйте cspell-default.config.js в UTF-8 без BOM. Zed по умолчанию так и делает, а вот классический Блокнот может добавить BOM, и тогда .js-модуль не загрузится.