Редакторы и IDE JetBrains IDE: индексация, рефакторинги, инспекции, когда они окупаются
0%

JetBrains IDE: индексация, рефакторинги, инспекции, когда они окупаются

JetBrains IDE: индексация, рефакторинги, инспекции, когда они окупаются

Спор «IDE против редактора» почти всегда ведут не о том. Обсуждают потребление памяти, скорость запуска и цену лицензии — то есть издержки. А продукт, за который эти издержки платятся, остаётся за кадром, потому что он невидимый.

Продукт у JetBrains ровно один: постоянно поддерживаемая в актуальном состоянии семантическая модель вашего проекта. Всё остальное — рефакторинги, инспекции, навигация, автодополнение, отладчик, который знает, что за объект перед вами, — это приложения поверх этой модели. Индексация — цена её построения. Гигабайты RAM — цена её хранения.

Поэтому статья устроена так: сначала разбираем, что именно строится и почём, потом — что из этого вырастает, потом — честная арифметика, когда сумма сходится, а когда нет. Если вы ещё не читали про пять слоёв редактора и про LSP, обзор трека даёт нужный контекст.

1. Что вообще строит IntelliJ Platform

Все IDE JetBrains — IntelliJ IDEA, PyCharm, GoLand, WebStorm, Rider, CLion, RubyMine, PhpStorm, DataGrip, а также Android Studio от Google — это одна и та же платформа (open source, github.com/JetBrains/intellij-community) с разными наборами плагинов поддержки языков. Различия между продуктами — маркетинговые и языковые, архитектура одна.

Модель кода в IntelliJ Platform

Разберём пирамиду снизу вверх, потому что каждый слой объясняет одну из «странностей» IDE.

VFS (Virtual File System). Платформа не работает с диском напрямую. Она держит персистентный снимок дерева файлов: пути, размеры, timestamp, содержимое. Отсюда два наблюдаемых эффекта: IDE замечает внешние изменения не мгновенно (нужен refresh, обычно он случается при возврате фокуса в окно), и IDE знает историю файла даже без Git — Local History живёт как раз на VFS.

PSI (Program Structure Interface). Полное синтаксическое дерево файла плюс механизм разрешения ссылок: этот идентификатор save в строке 42 указывает вот на этот метод вот этого класса. PSI строится лениво и живёт в памяти. Именно PSI отличает IDE от текстового поиска: Ctrl+B на user.save() попадает в реализацию, а не в первое совпадение по слову.

Stub-деревья. Ключевая оптимизация. Хранить PSI всех файлов проекта в памяти невозможно, а перепарсивать по требованию — медленно. Поэтому для каждого файла сохраняется урезанное дерево: только объявления (классы, методы, поля, сигнатуры, модификаторы), без тел методов. Оно сериализуется на диск. Чтобы дать автодополнение по классу из чужой библиотеки, IDE поднимает stub, а не парсит файл целиком.

Инвертированные индексы. FileBasedIndex — набор отображений «ключ → множество файлов». Индекс имён классов, индекс имён методов, индекс всех слов в коде (IdIndex, он же основа быстрого Find in Files), индексы, которые регистрируют плагины под свои задачи. Это самое дорогое в построении и самое ценное в использовании.

Стоит явно проговорить отличие от LSP-подхода, потому что на нём держится половина разницы в ощущениях. Языковой сервер обычно отвечает на вопросы про открытые файлы и про то, что смог быстро дотянуть по зависимостям. IntelliJ строит глобальный инкрементальный индекс всего проекта заранее. Отсюда Find Usages, который находит использования в модуле, который вы никогда не открывали, и Rename, который честно знает полный список мест. И отсюда же — минуты индексации на входе.

2. Жизненный цикл индексации и dumb mode

Состояния, между которыми ходит IDE, стоит понимать буквально: половина вопросов «почему не работает автодополнение» отвечается одним взглядом на статус-бар.

Два практических следствия.

Первое: dumb mode — это не «IDE зависла». Это явный контракт платформы (DumbService), при котором функциональность, требующая индексов, отключена, а всё остальное работает. Плагин, который в dumb mode лезет в индекс, получает исключение — поэтому «умные» действия выключены, а не тихо врут.

Второе: индексы персистентны и инкрементальны. Второе открытие того же проекта не стоит почти ничего. Реальные потери случаются, когда вы это свойство ломаете.

Открытие большого проекта: куда уходят минуты

Самая дорогая привычка в экосистеме JetBrains — рефлекторный File | Invalidate Caches and Restart на любую странность. Он выбрасывает всё: VFS, stub-и, индексы. Вы платите холодный старт заново. В подавляющем большинстве случаев проблема лечится дешевле: переимпортом модели сборки (Reload All Gradle Projects), проверкой, что у модуля правильно выставлен SDK, или Repair IDE (File | Repair IDE) — он чинит по нарастающей, начиная с самого щадящего шага.

Как измерить и ускорить индексацию у себя

Не гадайте — платформа пишет подробные отчёты. Каталог ~/.cache/JetBrains/<Продукт><Версия>/indexing-diagnostic/<проект>/ содержит HTML-отчёты по каждому запуску индексации: сколько времени ушло на сканирование, сколько на индексацию, разбивка по индексаторам и топ самых дорогих файлов.

# Найти последние отчёты индексации (Linux; на macOS путь ~/Library/Caches/JetBrains/...)
ls -lt ~/.cache/JetBrains/IntelliJIdea*/indexing-diagnostic/*/ | head -20

# Сколько места занимают индексы и кеши — иногда это десятки гигабайт
du -sh ~/.cache/JetBrains/*
du -sh ~/.local/share/JetBrains/*   # плагины и конфигурация

Почти всегда виноват не «проект большой», а конкретные каталоги. Типичные обжоры: node_modules в нескольких копиях, сгенерированный код (protobuf, GraphQL, OpenAPI-клиенты, build/generated), дампы данных и минифицированные бандлы, случайно попавшие в проект.

Рычаги, по убыванию отдачи:

Рычаг Что делает Когда применять
`Mark Directory as Excluded` каталог полностью выпадает из индексации и поиска
.gitignore-совместимые исключения в конфиге сборщика тот же эффект, но переносится между разработчиками всегда, когда исключение общее для команды
idea.max.intellisense.filesize порог, после которого файл не анализируется семантически (по умолчанию ~2500 КБ) сгенерированные монстры на 40 тыс. строк
Shared indexes индексы JDK и проекта строятся один раз и раздаются готовыми большая команда, монорепозиторий, частые новички
Больше -Xmx меньше GC-пауз при индексации и анализе если в Activity Monitor видно давление на память
Быстрый SSD и исключение каталога IDE из антивируса снимает I/O-узкое место Windows с корпоративным EDR — там эффект бывает кратным

Про shared indexes стоит сказать отдельно, потому что это самая недоиспользуемая корпоративная фича. Индексы JDK JetBrains раздаёт со своего CDN автоматически. Индексы вашего проекта можно построить один раз в CI и выложить на внутренний HTTP-сервер или в S3 — разработчики скачают готовые вместо того, чтобы каждый жёг по три минуты CPU. Документация: Shared indexes. На команде из 30 человек с еженедельными переключениями крупных веток это буквально человеко-дни в квартал.

Память настраивается через Help | Change Memory Settings (пишет в пользовательский *.vmoptions; править файл в каталоге установки — плохая идея, его затрёт обновление):

# ~/.config/JetBrains/IntelliJIdea2026.1/idea64.vmoptions
-Xmx6g
-XX:+UseG1GC
-XX:ReservedCodeCacheSize=768m
-XX:SoftRefLRUPolicyMSPerMB=50
-Dsun.io.useCanonCaches=false
# файлы больше этого размера (КБ) не получают семантический анализ
-Didea.max.intellisense.filesize=5000

Не ставьте -Xmx в половину машины «на всякий случай»: слишком большая куча удлиняет полные сборки мусора и делает паузы заметнее. Начните с 4–6 ГБ на серьёзный JVM-проект, 2–3 ГБ на типичный фронтенд, и смотрите на индикатор памяти (включается в Settings | Appearance | Show memory indicator) и на Help | Diagnostic Tools | Activity Monitor — он показывает, какой именно подсистеме или плагину принадлежит CPU.

3. Рефакторинги: почему они не то же самое, что «переименовать текст»

Здесь находится главная ценность, за которую платят. Разберём на самом простом примере — Rename, потому что все думают, что понимают, как он работает.

Наивная реализация — текстовая замена. Она ломается на первом же омониме: save есть у пяти классов, id есть везде. Чуть менее наивная — LSP-rename по одному языковому серверу: он корректен в пределах того, что сервер видит, но обычно ничего не знает про строку "UserService" в Spring-конфиге, про имя бина в XML, про упоминание класса в persistence.xml и про Java-класс, который дёргается из Kotlin.

Что делает IntelliJ:

Три вещи в этой схеме делают разницу и заслуживают того, чтобы их назвать вслух:

  1. Индекс сужает, PSI подтверждает. Дешёвая операция отсекает 99% файлов, дорогая применяется к остатку. Это стандартная стратегия «фильтр — верификатор», и она же объясняет, почему без индексов рефакторинги недоступны.
  2. Расширяемость через процессоры. RenameProcessor и его коллеги — точки расширения: плагин Spring добавляет знание про XML и аннотации, плагин JPA — про JPQL-строки, плагин Kotlin — про кросс-языковые ссылки. Поэтому переименование Java-класса чинит Kotlin-код, а переименование колонки в сущности предлагает поправить нативный SQL.
  3. Атомарность. Рефакторинг — одна транзакция и одна запись в Undo. Это ровно то, чего нет у связки sed + компилятор: там отката нет, есть только git checkout.

Набор, который реально стоит выучить

Учить все шестьдесят рефакторингов бессмысленно. Практическая отдача сосредоточена примерно в восьми. Клавиши даны для стандартного keymap (Windows/Linux; на macOS — Cmd вместо Ctrl и свои сочетания, но Ctrl+Alt+Shift+TCtrl+T работает везде).

Рефакторинг Клавиши Что делает и почему руками хуже
Refactor This Ctrl+Alt+Shift+T меню всех применимых в текущей точке — единственный хоткей, который обязателен
Rename Shift+F6 все ссылки, включая другие языки, строки, конфиги; проверка конфликтов
Extract Method Ctrl+Alt+M сам считает параметры, возвращаемое значение, находит дубликаты того же кода и предлагает заменить их вызовом
Extract Variable / Field / Parameter Ctrl+Alt+V / F / P правильно расставляет final, выбирает точку объявления, предлагает заменить все вхождения выражения
Change Signature Ctrl+F6 меняет порядок и типы параметров во всех вызовах разом, умеет подставлять значения по умолчанию в существующие вызовы
Inline Ctrl+Alt+N обратная операция; незаменима, чтобы разобрать чужой слой абстракции, который ничего не абстрагирует
Move F6 переносит класс/файл между пакетами, чинит импорты, обновляет строковые ссылки
Type Migration Ctrl+Shift+F6 меняет тип и распространяет изменение по цепочке: List<String>Set<String> вместе со всеми сигнатурами вокруг

Type Migration — самый недооценённый. Смена типа поля обычно рвётся волной по десяткам сигнатур; вручную это полдня механической правки с риском пропустить ветку.

Из наблюдений за тем, как люди работают: главный барьер — не незнание клавиш, а привычка редактировать текст вместо структуры. Симптом простой. Если вы переименовываете переменную двойным кликом и набором нового имени — вы не пользуетесь IDE, вы пользуетесь Notepad с подсветкой, за который переплатили.

Structural Search and Replace: когда нужно своё правило

Иногда нужен рефакторинг, которого нет в меню: «замени все вызовы logger.info("..." + x) на параметризованные». Регулярка тут врёт (она не знает про вложенные скобки и переносы), а писать плагин — дорого. Промежуточный инструмент — SSR (Edit | Find | Search Structurally), поиск по шаблону PSI, а не по тексту.

# Шаблон поиска (Java):
$logger$.info($msg$ + $arg$)

# Ограничения на переменные шаблона:
#   $logger$ : Expression type = org.slf4j.Logger
#   $msg$    : Text = регулярка ".*"   (только строковые литералы)
#   $arg$    : Count = 1..1

# Шаблон замены:
$logger$.info($msg$ + " {}", $arg$)

Ключевое отличие от grep: $logger$ с ограничением по типу найдёт переменную любого имени — log, LOGGER, this.logger — и не найдёт одноимённое поле чужого класса. SSR-шаблон можно сохранить как собственную инспекцию с уровнем серьёзности и quick-fix’ом, положить в профиль проекта и получить командное правило, которое подсвечивается в редакторе и падает в CI. Документация: Structural search and replace.

4. Инспекции: статический анализ, встроенный в набор текста

Инспекция — не то же самое, что предупреждение компилятора, и не то же самое, что линтер.

  • Компилятор обязан быть быстрым и не имеет права на ложные срабатывания в ошибках.
  • Линтер (ESLint, Checkstyle, go vet) работает пачкой в CI, часто по AST одного файла.
  • Инспекция работает по PSI всего проекта, в фоне, на каждом нажатии клавиши, и почти всегда несёт с собой quick-fix — то есть автоматическое исправление.

Технически интересная часть — инспекции на анализе потока данных. IntelliJ гоняет абстрактную интерпретацию по графу потока управления и отслеживает диапазоны значений, nullability и достижимость. Так рождаются сообщения вида «условие x != null всегда истинно» и «NullPointerException возможен здесь».

// Аннотации из org.jetbrains.annotations — топливо для анализа потоков данных.
// Без них IDE вынуждена догадываться; с ними она делает выводы.
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Contract;

public final class UserService {

    // @Contract говорит: если аргумент null, результат тоже null; функция чистая.
    @Contract(value = "null -> null; !null -> !null", pure = true)
    public static @Nullable String normalize(@Nullable String raw) {
        return raw == null ? null : raw.trim().toLowerCase();
    }

    public void register(@NotNull String email) {
        String norm = normalize(email);
        // IDE знает из @Contract: email не-null → norm не-null.
        // Поэтому подсветит проверку ниже как «условие всегда ложно» — код мёртвый.
        if (norm == null) {
            throw new IllegalStateException("недостижимо");
        }
        repository.save(norm);
    }
}

Здесь важен не столько сам пример, сколько принцип: аннотации контрактов — это способ передать анализатору знание, которого нет в типах. В Kotlin эту роль играет система типов с nullability, в Go — соглашения, в TypeScript — strictNullChecks. В Java без аннотаций анализ вынужден быть консервативным и потому шумным.

Профили инспекций как командный артефакт

Профиль по умолчанию у JetBrains разумный, но настроенный «под всех». Ценность появляется, когда команда фиксирует свой профиль в репозитории.

<!-- .idea/inspectionProfiles/Project_Default.xml -->
<component name="InspectionProjectProfileManager">
  <profile version="1.0">
    <option name="myName" value="Project Default" />

    <!-- Поднимаем до ошибки то, что для нас недопустимо -->
    <inspection_tool class="NullableProblems" enabled="true" level="ERROR"
                     enabled_by_default="true" />
    <inspection_tool class="ConstantValue" enabled="true" level="WARNING"
                     enabled_by_default="true" />
    <inspection_tool class="ResultOfMethodCallIgnored" enabled="true" level="ERROR"
                     enabled_by_default="true" />
    <inspection_tool class="SqlResolve" enabled="true" level="WARNING"
                     enabled_by_default="true" />

    <!-- Гасим то, что для нашего стиля шум -->
    <inspection_tool class="SpellCheckingInspection" enabled="false"
                     enabled_by_default="false" />
    <inspection_tool class="UnnecessaryLocalVariable" enabled="false"
                     enabled_by_default="false" />
  </profile>
</component>
<!-- .idea/inspectionProfiles/profiles_settings.xml — чтобы профиль применялся автоматически -->
<component name="InspectionProjectProfileManager">
  <settings>
    <option name="PROJECT_PROFILE" value="Project Default" />
    <version value="1.0" />
  </settings>
</component>

Точечное подавление — там, где инспекция права в общем случае, но не в этом:

// Подавление на одну строку. ОБЯЗАТЕЛЬНО с объяснением — иначе через год никто не поймёт.
//noinspection ResultOfMethodCallIgnored -- вызов нужен ради побочного эффекта прогрева кеша
warmupCache();

Правило гигиены: пустое подавление без комментария — техдолг, который невозможно пересмотреть. Ревьюеру стоит цепляться к //noinspection без объяснения так же, как к закомментированному коду.

Те же инспекции в CI

Инспекция, которая живёт только в IDE, — это рекомендация. Инспекция в CI — это правило. Есть два пути, и выбор между ними прагматичный.

Первый путь — бесплатный и грубый. IDE запускается без интерфейса и печатает отчёт:

# Headless-инспекции. Требуется установленная IDE и виртуальный дисплей на голом Linux.
# Синтаксис: idea.sh inspect <проект> <профиль> <каталог-результатов> [опции]
xvfb-run /opt/idea/bin/idea.sh inspect \
    "$PWD" \
    "$PWD/.idea/inspectionProfiles/Project_Default.xml" \
    "$PWD/inspection-results" \
    -format json \
    -d "$PWD/src/main/java" \
    -v1

Подводные камни здесь настоящие: запуск занимает время холодного старта плюс индексацию, нужен GUI-стек, а сравнивать результат с «было» придётся самому. Годится для ночной сборки, плохо годится для проверки каждого PR.

Второй путь — Qodana, продукт JetBrains, который упаковывает те же инспекции в docker-образы, отдаёт SARIF, умеет baseline (игнорировать существующие проблемы и падать только на новых) и вешает аннотации на строки в PR.

# .github/workflows/qodana.yml
name: Qodana
on:
  pull_request:
  push:
    branches: [main]

jobs:
  qodana:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
      checks: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0        # baseline и анализ изменений требуют полной истории
      - uses: JetBrains/qodana-action@v2025.1
        with:
          args: --baseline,qodana.sarif.json
        env:
          QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
# qodana.yaml в корне проекта
version: "1.0"
linter: jetbrains/qodana-jvm:latest
profile:
  path: .idea/inspectionProfiles/Project_Default.xml   # ровно то же, что в IDE
exclude:
  - name: All
    paths:
      - build/generated
      - src/test/resources
failureConditions:
  severityThresholds:
    critical: 0        # ни одной новой критической проблемы
    high: 5

Практический совет по внедрению: начинайте с baseline, а не с нуля. Включить полный профиль на легаси-проекте — это 4000 предупреждений и мгновенная потеря доверия к инструменту. Baseline фиксирует текущее состояние как «принято» и заставляет падать только на новых проблемах; долг разбирается отдельными задачами.

По деньгам: у Qodana есть бесплатный Community-тир с ограниченным набором линтеров, платные тарифы считаются по активным контрибьюторам — актуальные условия. Сравнение с SonarQube честнее всего свести к одному критерию: если команда и так живёт в JetBrains IDE, Qodana ценна тем, что в редакторе и в CI работает буквально один движок, и класса проблем «у меня локально зелено, а CI ругается» не возникает. Если IDE в команде разные — преимущество испаряется, и Sonar с его более широкой языковой матрицей может подойти лучше.

5. Конфигурация, которую стоит завести с первого дня

Что из .idea/ коммитить

Самый частый источник грязных диффов. Каталог .idea/ смешивает командные настройки и личное состояние окна. Разделять надо явно:

# .gitignore — рекомендация близка к официальному шаблону JetBrains
.idea/*

# Коммитим ТОЛЬКО то, что общее для команды:
!.idea/codeStyles/
!.idea/inspectionProfiles/
!.idea/runConfigurations/
!.idea/scopes/
!.idea/copyright/
!.idea/externalDependencies.xml
!.idea/encodings.xml

# Никогда не коммитим — это личное состояние и источник конфликтов:
.idea/workspace.xml
.idea/tasks.xml
.idea/usage.statistics.xml
.idea/shelf/
.idea/httpRequests/
.idea/dictionaries/
*.iws
out/

runConfigurations/ заслуживает отдельного внимания: конфигурация запуска приложения с нужными переменными окружения, профилями и аргументами, лежащая в репозитории, — это исполняемая документация. Новый человек нажимает Run и получает работающее приложение вместо чтения README пятилетней давности.

Стиль кода: .editorconfig вместо проприетарного формата

JetBrains IDE полностью поддерживают .editorconfig, включая расширенный набор свойств с префиксом ij_ — и это правильный выбор, потому что файл читают и другие редакторы.

# .editorconfig
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4
max_line_length = 120

[*.{yml,yaml,json}]
indent_size = 2

[*.java]
# Специфичные для IntelliJ свойства: работают в IDE, игнорируются другими редакторами
ij_java_class_count_to_use_import_on_demand = 999   # запрещаем import *
ij_java_names_count_to_use_import_on_demand = 999
ij_java_imports_layout = $*,|,java.**,|,javax.**,|,*
ij_continuation_indent_size = 8

[*.kt]
ij_kotlin_allow_trailing_comma = true
ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL

[Makefile]
indent_style = tab

Включите Settings | Editor | Code Style | Enable EditorConfig support, и IDE будет подчиняться файлу вместо своих настроек. import * из-за class_count_to_use_import_on_demand — реально самый частый источник бессмысленных конфликтов в JVM-командах, где половина людей на IDEA, а половина нет.

Горячие клавиши, которые окупаются в первую неделю

Действие Windows/Linux Зачем
Search Everywhere Shift Shift одна точка входа: файлы, классы, действия, настройки
Find Action Ctrl+Shift+A делает ненужным знание остальных хоткеев
Go to Declaration Ctrl+B навигация по смыслу, а не по тексту
Go to Implementation Ctrl+Alt+B по интерфейсу — в реализации
Find Usages Alt+F7 обратный вопрос: кто это зовёт
Recent Files Ctrl+E 90% навигации в реальной работе — это возврат
Show Context Actions Alt+Enter quick-fix, генерация, «сделай мне красиво»
Refactor This Ctrl+Alt+Shift+T вход во все рефакторинги
Extend Selection Ctrl+W расширение выделения по узлам PSI, а не по словам
Run Anything Ctrl Ctrl запуск задач сборщика и конфигураций без мыши

Совет по обучению: Help | Productivity Guide показывает, какими фичами вы уже пользуетесь и как часто, а плагин Key Promoter X ругается при каждом клике мышью по действию, у которого есть клавиша. Две недели раздражения — и мышечная память есть.

Плагины: короткий разумный список

Ставить много плагинов — плохая стратегия: каждый добавляет к старту, к индексации и к шансу словить несовместимость при обновлении. Отдача, проверенная временем:

  • IdeaVim — модальное редактирование в JetBrains-IDE. Лучшая эмуляция Vim среди всех «vim-режимов»; понимает .ideavimrc, регистры, макросы, текстовые объекты и умеет маппить команды на действия IDE.
  • Key Promoter X — тренажёр горячих клавиш.
  • Rainbow Brackets, Indent Rainbow — дёшево и заметно снижает утомляемость на вложенном коде.
  • GitToolBox — inline blame и статус ветки прямо в редакторе.
  • String Manipulation — конвертации регистров и кодировок, которые иначе делают в браузере.
  • .env files support, Makefile Language — мелочи, закрывающие дыры в подсветке.

Про AI Assistant и агентные фичи скажу отдельно и коротко, потому что вокруг них шум: это отдельная подписка (входит в All Products Pack), встроенная в те же PSI-механизмы — контекст модели собирается из модели кода, а не только из открытого файла. Оценивать это стоит по той же логике, что и остальное в статье: сколько времени экономит против того, сколько стоит. Общий разбор инструментария — в треке AI Engineering.

.ideavimrc — если вы пришли из Vim

Практичный подход: не пытайтесь превратить IDE в Neovim. Берите модальное редактирование из Vim, а навигацию и рефакторинги — из IDE. Про сам Vim подробно в основах Vim и продвинутом Vim.

" ~/.ideavimrc
" Базовое поведение
set number relativenumber
set scrolloff=5
set incsearch
set hlsearch
set ignorecase smartcase
set clipboard+=unnamedplus     " общий буфер обмена с системой
set surround                   " эмуляция vim-surround
set commentary                 " gcc / gc{motion}
set NERDTree                   " навигация по дереву в vim-стиле
set which-key
set timeoutlen=500
set ideajoin                   " J использует умное склеивание строк из IDE

let mapleader = " "

" ГЛАВНЫЙ ПРИНЦИП: не переписывать IDE, а дотянуться до её действий.
" Список имён действий: :actionlist
nnoremap <leader>f  :action GotoFile<CR>
nnoremap <leader>s  :action GotoSymbol<CR>
nnoremap <leader>a  :action GotoAction<CR>
nnoremap <leader>u  :action FindUsages<CR>
nnoremap <leader>r  :action RenameElement<CR>
nnoremap <leader>rr :action Refactorings.QuickListPopupAction<CR>
nnoremap <leader>e  :action ShowErrorDescription<CR>
nnoremap <leader>=  :action ReformatCode<CR>
nnoremap <leader>o  :action OptimizeImports<CR>
nnoremap <leader>d  :action Debug<CR>
nnoremap <leader>b  :action ToggleLineBreakpoint<CR>
nnoremap <leader>gs :action Git.Menu<CR>

" Навигация по ошибкам и по истории переходов
nnoremap ]e :action GotoNextError<CR>
nnoremap [e :action GotoPreviousError<CR>
nnoremap <C-o> :action Back<CR>
nnoremap <C-i> :action Forward<CR>

" Ctrl+W из IDE полезнее vim-аналога: расширение выделения по узлам PSI
vnoremap <C-w> :action EditorSelectWord<CR>

" Быстрый reload конфига
nnoremap <leader>vr :source ~/.ideavimrc<CR>

Честное замечание: IdeaVim покрывает большинство повседневного Vim, но не всё. Сложные :g/pattern/normal и часть Ex-команд ведут себя иначе, плагинов Vim-экосистемы нет — есть только несколько встроенных эмуляций. Если ваш рабочий процесс держится на десятке Vim-плагинов, IdeaVim будет ощущаться теснее, чем оригинал.

6. Экономика: когда тяжёлая IDE окупается

Теперь честная арифметика. У JetBrains IDE есть три статьи расходов:

  1. Деньги. Личная подписка на один продукт — порядка 100 $–200 в год, All Products Pack — порядка 250 $–290, коммерческие лицензии заметно дороже, но дешевеют на второй и третий год непрерывной подписки (актуальный прайс).
  2. Железо. 16 ГБ RAM — практический минимум для комфортной работы с большим проектом, 32 ГБ — если рядом ещё Docker с базой и фронтенд-сборка. Плюс десятки гигабайт под кеши.
  3. Внимание. Индексация после переключения веток, окно, которое не открывается за 200 мс, привычка ждать.

Выгода же зависит от двух факторов сильнее, чем от всех остальных вместе: насколько богата статическая структура вашего кода и насколько велик проект.

Разберём логику квадрантов, потому что она важнее самой картинки.

Верх-право — окупается почти всегда. Java/Kotlin/C# в большом проекте: типы плотные, абстракций много, кодовая база превышает то, что помещается в голову. Здесь Find Usages по интерфейсу, Change Signature по методу с 60 вызовами и инспекции nullability экономят часы в неделю. Лицензия окупается за один сложный рефакторинг.

Низ-право — самый спорный квадрант. Большой проект на языке без типов (нетипизированный PHP, старый Python, JS без TypeScript). IDE честно старается, но выводить структуру ей не из чего: динамическая диспетчеризация, магические методы, всё решается в рантайме. Вы платите полную цену индексации, а получаете процентов сорок пользы. Практический вывод неожиданный, но правильный: вложиться в типы выгоднее, чем вложиться в IDE. Перевод проекта на TypeScript или добавление type hints и mypy в Python поднимает вас в верхний квадрант — и заодно улучшает работу любого другого инструмента, включая Neovim с LSP.

Низ-лево — оверкилл. Скрипты, конфиги, DevOps-обвязка, короткие ноутбуки. Здесь преимущество за быстрым запуском, а не за глубоким анализом.

Сравнение по осям, без фанатизма

Критерий JetBrains IDE VS Code + расширения Neovim + LSP
Время до первой строки кода минуты (установка + индексация) минуты часы—дни на конфигурацию
Холодный старт на большом проекте 1–5 мин 10–40 с 2–10 с
RAM на большом проекте 3–8 ГБ 1–3 ГБ 0.3–1.5 ГБ
Кросс-языковые рефакторинги сильнейшая сторона зависит от расширения, обычно слабее практически нет
Глубина статического анализа «из коробки» очень высокая средняя, набирается плагинами равна возможностям LSP-сервера
Отладчик зрелый, с evaluate-выражениями и условными точками хороший, DAP рабочий, требует настройки
Работа с БД встроенный полноценный клиент расширения внешние утилиты
Профилировщик, анализ памяти встроены в Ultimate/Rider внешние инструменты внешние инструменты
Единообразие в команде высокое (профили в репозитории) среднее низкое, каждый со своим конфигом
Цена подписка бесплатно бесплатно
Работа по SSH Remote Development / Gateway Remote-SSH, зрелая нативно, тривиально
Расширяемость своими правилами SSR + плагины на JVM расширения на TS Lua + внешние линтеры

Строку «работа по SSH» стоит пояснить, потому что это исторически слабое место, которое починили. Remote Development запускает полноценный бэкенд IDE на удалённой машине — там же, где исходники, — а локально работает тонкий JetBrains Client. Индексация и сборка едят ресурсы сервера. Архитектурно это тот же приём, что и VS Code Remote, но JetBrains-версия традиционно более чувствительна к задержкам сети: при RTT свыше ~80 мс редактирование ощущается вязким. Проверяйте на своей сети до того, как перестраивать процесс.

Сколько это в деньгах на самом деле

Не нужно точной модели, нужен порядок величины. Час разработчика в 2026 году стоит компании от 20 до 100+ долларов в зависимости от рынка. All Products Pack — это порядка двух-трёх часов работы в год. Чтобы лицензия окупилась, инструмент должен экономить около 15 минут в месяц. Любой человек, делающий хотя бы один нетривиальный рефакторинг в квартал, эту планку берёт с запасом.

Реальные аргументы против лежат не в цене лицензии, а в другом:

  • Ресурсы машины. Если у вас 8 ГБ RAM, IDE будет свопиться, и никакая семантика этого не окупит. Апгрейд железа — предварительное условие.
  • Смешанный стек. Прыгать между шестью языками в одном окне — не самая сильная сторона JetBrains; продукты заточены под основной язык, а плагины к другим языкам слабее профильных IDE.
  • Организационное трение. Закупка лицензий в большой компании иногда занимает больше времени, чем экономит инструмент в первый год. Это реальный аргумент, и он не технический.
  • Личное предпочтение скорости. Есть люди, для которых задержка в 150 мс на любое действие — постоянный источник раздражения, перевешивающий любую функциональность. Это не иррационально.

Что изменилось в 2025–2026: лицензии и продуктовая линейка

Три изменения, которые стоит знать, потому что они меняют старые выводы.

Единый дистрибутив IntelliJ IDEA. Начиная с версии 2025.3 (декабрь 2025) отдельной Community Edition больше нет: скачивается одна сборка, которая бесплатно работает и в коммерческих, и в некоммерческих проектах, а подписка разблокирует платные возможности. При этом бесплатный набор шире, чем был в Community: добавились базовая подсветка Spring и Jakarta EE, мастер создания Spring Boot проекта, подключение к базам данных и просмотр схем, полная поддержка SQL. Исходники платформы остаются открытыми. Детали — в анонсе JetBrains и FAQ.

Бесплатные некоммерческие лицензии. С конца 2024 года WebStorm и Rider бесплатны для некоммерческого использования — обучение, open source без коммерческой выгоды, хобби, создание контента — с полным набором платных функций (анонс). Ограничение простое и его нужно читать буквально: работать по этой лицензии над коммерческим проектом нельзя.

Fleet закрыт. Лёгкий редактор JetBrains, который позиционировался как ответ VS Code, снят с распространения 22 декабря 2025 года. Официальная причина — две общего назначения линейки IDE размывали фокус и не давали достаточной ценности, чтобы оправдать существование обеих (пост). Платформа Fleet переиспользуется в новом продукте, ориентированном на агентную разработку. Практический вывод для выбора инструмента: лёгкой альтернативы внутри экосистемы JetBrains сейчас нет, ставка сделана на одну тяжёлую линейку. Если вам нужен именно лёгкий редактор — смотрите в сторону новой волны редакторов.

7. Типичные ошибки

Держать проект открытым «корнем от всего». Открытие ~/work вместо конкретного репозитория заставляет индексировать всё подряд. Открывайте проект, а не каталог с проектами.

Не исключать генерируемый код. build/generated, target/generated-sources, вывод protobuf и OpenAPI. Один сгенерированный файл на 50 тыс. строк способен добавить минуту к каждой индексации.

Invalidate Caches как рефлекс. Разбирайтесь в причине: чаще всего это рассинхрон модели сборки, а не порча индексов. Начинайте с Reload Project и Repair IDE.

Коммитить .idea/workspace.xml. Гарантированный конфликт на каждом merge и непредсказуемое состояние окон у коллег.

Ставить 25 плагинов. Каждый — риск при обновлении IDE и вклад в старт. Раз в полгода проходите список и удаляйте то, чем не пользовались.

Пользоваться IDE как редактором. Если вы навигируете по файлам через дерево проекта, переименовываете двойным кликом и ищете по Ctrl+F вместо Alt+F7 — вы платите за семантику и не потребляете её. Это самая дорогая ошибка из списка, потому что она невидима.

Игнорировать подсветку. Жёлтые и серые волны в правом жёлобе — не украшение. Раз в неделю пройдитесь Alt+Enter по файлу, над которым работаете. Если предупреждений тысячи и они бессмысленны — настройте профиль, а не отключайте инспекции целиком.

Отключать анализ, чтобы «ускорить». Power Save Mode выключает инспекции и фоновой анализ. Это аварийный режим для ноутбука на 8% батареи, а не рабочий.

Мини-итог

  • JetBrains IDE продаёт семантическую модель проекта: VFS → PSI → stub-деревья → инвертированные индексы. Индексация — цена входа, всё остальное — следствие.
  • Индексы персистентны и инкрементальны. Дорого только первое открытие; дорогим его делает привычка сбрасывать кеши и неисключённый генерируемый код. Мерьте по отчётам в indexing-diagnostic/, а не по ощущениям.
  • Рефакторинги надёжны потому, что работают по ссылкам PSI и расширяются процессорами плагинов: индекс сужает круг кандидатов, PSI подтверждает, всё применяется одной транзакцией с preview и откатом.
  • Инспекции — это статический анализ на каждом нажатии клавиши, с анализом потоков данных и quick-fix’ами. Настоящую пользу они дают, когда профиль лежит в репозитории и тот же профиль гоняется в CI (headless-инспекции или Qodana с baseline).
  • Окупаемость определяется богатством статической структуры и размером проекта. Java, Kotlin, C#, большой TypeScript — почти всегда да. Скрипты и динамика на маленьких проектах — скорее нет. На большом проекте без типов выгоднее вложиться в типы, чем в IDE.
  • Ландшафт 2026 года: единый бесплатно-работающий дистрибутив IntelliJ IDEA, бесплатные некоммерческие лицензии для WebStorm и Rider, закрытый Fleet.

Источники

Что дальше

Мы разобрали IDE, которая выиграла спор о тяжёлых средах разработки. Но она выиграла не на пустом месте: до неё было целое поколение IDE, задавшее и стандарты, и антипаттерны. Eclipse с его моделью плагинов OSGi, NetBeans, Visual Studio классических версий — они никуда не делись, и в некоторых нишах остаются лучшим или единственным выбором.

Eclipse, NetBeans и наследие: где они остались и почему

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

Статья описывает общий случай. Если у вас частный — можно разобрать его отдельно, платно. А если не хватает целого материала, предложите тему: её оплачивают вскладчину, и она выходит открытой для всех.

Доска запросов