Создание плагина для Intellij IDEA. Заметки и мелкие советы

Полгода назад или около того я загорелся-таки идей написать свой плагин для Intellij IDEA. Согласно задумке, он должен был считать, сколько времени разработчик потратил на проект (всего, за день, за сеанс) и отображать результат на диаграмме. Никакой магии, но такая функция здорово помогла бы мне рассчитывать время работы.



Пролистав каталог существующих плагинов, я все же нашел один подобный. Но никаких диаграмм он не рисовал, открывался через два выпадающих списка — что жуть, как неудобно, — да и на вид оказался довольно скудным.



Короче, я еще больше укрепился в вере, что мой плагин был бы полезен, и приступил к работе. Сразу хочу сказать, что материалов по разработке плагинов Intellij IDEA не просто мало, а их почти что нет.

Но кое-что все же раскопать удалось.

Полезные ссылки



Документация от JetBrains

Форум разработчиков плагинов для Intellij Platform

Коротко и понятно о том, где взять исходный код IDE

Очень подробный цикл статей на Хабре от @Lucyfer

Java API Examples


Мелкие советы


Я решил не рассказывать о таких вещах, как настройка среды для разработки плагина, конфигурационном файле и др., так как все немногие статьи в рунете посвящены именно этому. За время создания плагина я много раз спотыкался о неочевидные (мне, во всяком случае) особенности Intellij IDEA. Знай я о них раньше, дело пошло бы намного быстрее. Поэтому поделюсь некоторыми моментами, которые могут сэкономить вам порядочно времени.

Добавляем свой CustomStatusBarWidget


Для удобства я решил дополнить Status Bar небольшим элементом, который отображал бы сколько времени было потрачено за текущий сеанс работы в среде, не отвлекая при этом разработчика от редактора. Интерфейс StatusBar содержит перегруженный метод addWidget(), принимающий CustomStatusBarWidget параметр:

public interface StatusBar extends StatusBarInfo, Disposable {
...
    void addWidget(@NotNull StatusBarWidget var1);

    void addWidget(@NotNull StatusBarWidget var1, @NotNull String var2);

    void addWidget(@NotNull StatusBarWidget var1, @NotNull Disposable var2);

    void addWidget(@NotNull StatusBarWidget var1, @NotNull String var2, @NotNull Disposable var3);
...
 }

Получить же сам StatusBar проекта можно следующим образом:

statusBar = WindowManager.getInstance().getStatusBar(currentProject);

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

Спасение пришло отсюда. То есть, виджет можно добавить относительно других следующим образом:

statusBar.addWidget(myWidget1,"before " + IdeMessagePanel.FATAL_ERROR);
statusBar.addWidget(myWidget2, "after Encoding");
statusBar.addWidget(myWidget3,"after InsertOverwrite");
statusBar.addWidget(myWidget4,"after Position");

Имплементируем CustomStatusBarWidget:

    class Widget implements CustomStatusBarWidget{
        
        private JLabel myLabel = new JLabel("00:00:00");

        @Override
        public JComponent getComponent() {
           return myLabel;
        }

        @NotNull
        @Override
        public String ID() {
            return null;
        }

        @Nullable
        @Override
        public WidgetPresentation getPresentation(@NotNull PlatformType platformType) {
            return null;
        }

        @Override
        public void install(@NotNull StatusBar statusBar) {

        }

        @Override
        public void dispose() {

        }
    }

Добавим наш виджет на StatusBar, дополним JLabel иконкой…



Получение ToolBar'a действий из Java кода


Подробно про саму систему действий в плагинах Intellij IDEA можно почитать тут.
Получение компонента при помощи ActionManager.

    private JComponent createActionToolBar(AnAction ...actions){
        DefaultActionGroup actionGroup = new DefaultActionGroup();
        for(AnAction anAction : actions){
            actionGroup.add(anAction);
        }
        ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar("Tempore.MainPanel", actionGroup, false);
        return toolbar.getComponent();
    }

Адрес проекта, в котором работает плагин


Путь к проекту можно получить с помощью экземпляра класса Project. Например, путь к папке .idea проекта:

String path = currentProject.getProjectFile().getParent().getPath();

Получение компонентов из метода actionPerformed()


Из параметра AnActionEvent можно получить доступ к компонентам:

Project currentProject = DataKeys.PROJECT.getData(actionEvent.getDataContext());
VirtualFile currentFile = DataKeys.VIRTUAL_FILE.getData(actionEvent.getDataContext());
Editor editor = DataKeys.EDITOR.getData(actionEvent.getDataContext());
StatusBar statusBar = WindowManager.getInstance().getStatusBar(DataKeys.PROJECT.getData(actionEvent.getDataContext()));
                  .

Всплывающие сообщения


Простое сообщение с информацией или сообщение об ошибке можно добавить на StatusBar следующим образом:

                                    JBPopupFactory.getInstance()
                                            .createHtmlTextBalloonBuilder("You have been working for two hours! Recommend to have a break ", MessageType.INFO, null)
                                            .setFadeoutTime(7500)
                                            .createBalloon()
                                            .show(RelativePoint.getCenterOf(statusBar.getComponent()),
                                                    Balloon.Position.atRight);


Выглядит вот так:


Совместимость со средами Intellij Platform


Так как подсчет времени работы над проектом полезен не только в Intellij IDEA, я решил сделать плагин совместимым с другими средами Intellij Platform. Для этого нужно добавить тег в файле plugin.xml:

<idea-plugin version="0.5.5b">
  ...
  <depends>com.intellij.modules.lang</depends>
  ...
</idea-plugin>

Теперь помимо Intellij IDEA плагин подходит еще и для RubyMine, WebStorm, PhpStorm, PyCharm и AppCode.

Итоги


Примерно за месяц, мне удалось создать плагин, который следит за тем, сколько времени вы тратите на свои проекты, советует сделать перерыв, если вы пишете код нон-стоп несколько часов и рисует диаграмму потраченных часов за каждый день.
Так же он останавливается, если активность в среде прекратилась больше, чем на 5 минут и запускается, когда пользователь снова принялся за работу.



При желании, сам плагин можно скачать тут.

Надеюсь, кому-то эта статья поможет разобраться с некоторыми аспектами разработки и избавит от бессонных ночей за чтением API.
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 17

    +2
    хм, полгода назад WakaTime уже был, однако wakatime.com
      0
      WakaTime очень мощный, это да. Но (!) без Python'a он работать не будет, к тому же, там нет такого приятного глазу виджета на Status Bar.
        +1
        RescueTime подсчитает и время на сайты (разделяя их на продуктивные/не очень)
      +1
      Скажите, а есть ли синхронизация, т.к. на работе и дома использую разные?

      P.S. Инетересыный плагин, уже пробую.

      P.S.S И еще бы статистику сколько набрано символов за сессию.
        0
        Спасибо.
        Статистику символов за сессию добавлю в ближайших версиях.
        Можно поподробнее про синхронизацию?
        Данные о времени для каждого проекта хранятся в папке самого проекта, так что если проект синхронизируете, то и статистика тоже будет синхронизироваться.
        0
        Как насчет исходных кодов? Планируется открывать?
          0
          Да, в скором времени выложу на github.
          0
          У меня ошибка goo.gl/xcOEqj
            0
            Спасибо большое. Можно подробнее? Для какой среды устанавливали, какую версию плагина, удалось ли запустить проект с плагином? Если можно, ответьте на почту ubermensch.dev@gmail.com.
              0
              Ошибка возникает из-за конфликта версий IDEA. Плагин совместим с IDE сборки 40.131 и выше. Проверьте версию своей IDE.image
                0
                Ошибка исправлена в новой версии плагина.
                +1
                Сделайте разделение статистики по проектам, и я вам буду очень благодарен! В идеале конечно что-то типа marketplace.eclipse.org/content/rabbit хотелось бы.
                  0
                  Спасибо.Интересный плагин, я попробую придумать что-то в этом роде. Разделение статистики, в смысле, сколько времени было потрачено на несколько проектов или же в конкретном проекте?
                    0
                    На каждом проекте. Суммарно тоже интересно.
                      0
                      Хорошая идея. Обязательно добавлю в ближайших версиях.
                  0
                  Очень интересно, спасибо!

                  Давно хотел попробовать написать плагин для идеи. Жду исходников, помогу с пулл-реквестами.
                    0
                    Рад, что понравилось. Скоро открою код

                  Only users with full accounts can post comments. Log in, please.