Что такое Ataman?

Ataman – это мой плагин для IDE-шек на базе Intellij. Единственное его предназначение – сделать возможным использование leader key биндингов в моём основном рабочем инструменте – Android Studio.

Leader что?

Leader key, или, как его ещё называют, sticky key – это подход к горячим клавишам, популярный среди пользователей олдскульных редакторов Emacs и Vim. Для того чтобы запустить биндинг, нужно нажать клавишу leader и затем по очереди последовательность клавиш, которая и будет командой.

Emacs и Vim? Это же что-то для дедов

Этим текстовым редакторам действительно дофига лет. Они появились на свет более сорока лет назад, задолго до Java, Intellij и тем более Android Studio. Но им есть что предложить разработчику, попивающему смузи пока его макбук пыхтит, собирая сотни LOC в apk-файл.

Обязательный комикс xkcd про Emacs
https://xkcd.com/378/
https://xkcd.com/378/

Чем обычные биндинги не угодили?

В Intellij очень страшные биндинги, которые могут задействовать до трёх клавиш-модификаторов и клавиши F-ряда. Это какое-то издевательство над пальцами разработчиков. Чтобы переименовать символ нужно зажать Shift+F6, вытянув пальцы в раскоряку. Я когда учился играть на гитаре так сильно пальцы не утруждал. Вызов меню рефакторинга на Windows это Ctrl+Alt+Shift+T. Четыре пальца напрягаются и завидуют пальцам пользователей macos, которым досталось мирное ^T. Кстати, почему T? От Refac[t]or? А чёрт его знает, логики здесь не ищите, использовали свободные клавиши. Не удивительно, что запомнить все биндинги считается тяжелой задачей, для которой пишут специальные плагины типа Key Promoter X, который находится в топе на Jetbrains Marketplace c 2,6M скачиваний.

А чем leader key лучше?

Допустим, я выбрал в качестве лидера Ctrl+L. И хочу вызвать меню рефакторинга. Я могу это сделать нажав три клавиши по очереди:

  • Ctrl+L: leader клавиша

  • с: префикс для группы биндингов для работы с кодом, как в слове [c]ode

  • r: рефакторинг, как в слове [r]efactor

Так как в один момент времени нажата лишь одна клавиша, мои пальчики счастливы. Счастлив и мой мозг, для которого теперь вместо какого-то набора модификаторов и какой-то случайной буквы нужно запомнить одну точку входа во все биндинги и красивую мнемонику. Я даже когда прожимаю это, у меня в голове звучит голос, проговаривая то что я собираюсь сделать: “[c]ode [r]efactor”

Префиксы какие-то. Зачем они нужны?

На клавиатуре всё-таки не хватает символов для того чтобы охватить все нужные биндинги. На 36 буквах и цифрах стандартной qwerty особо не разгуляешься. Обычно пространство доступных сочетаний клавиш расширяют при помощи модификаторов, но с leader key мне доступен гораздо более приятный инструмент - префиксы. Так как каждая клавиша нажимается отдельно, я могу объединять биндинги в группы. Про одну из них я рассказал выше – это [c]ode. Туда я закинул всё что связано с кодом. Вот некоторые из моих биндингов, с подписанными мнемониками:

  • <leader> [c]ode re[f]ormat – отформатирует файл

  • <leader> [c]ode [t]ype_info – информация о типе выражения под курсором

  • <leader> [c]ode [i]mplementation – переход к реализации интерфейса/метода

Моя группа биндингов [c]ode выглядит вот так
Моя группа биндингов [c]ode выглядит вот так

Я и так могу воспользоваться Ctrl+Shift+A и найти нужный мне экшн. И мнемоники не нужны

Я тоже пользуюсь поиском по экшнам, он даже у меня забинден на <leader> [s]earch [a]ctions. Но он достаточно медленный и ожидание пока прогрузится поиск по всем экшнам для того чтобы переименовать переменную выбивает меня из сладкого состояния потока, когда решение уже у тебя в голове и его только лишь осталось перенести в исходник. В этот момент хочется чувствовать себя повелителем машин, который чёткими движениями пальцев повелевает им выполнять нудную работу, а не ждать пока они эту самую нудную работу доделают. Поэтому для тех экшнов, которые нужны постоянно без удобных биндингов не обойтись.

Окей, убедил. Как пользоваться Ataman?

После того как скачаешь плагин, привяжи экшн Ataman: Leader Key к удобной для себя клавише. Можно использовать Ctrl+L из примера выше, можно что-нибудь поинтереснее. Мой знакомый приловчился использовать Tab Tab используя second stroke биндинг. Этот экшн является точкой входа в твои биндинги. Изначально там будет только один биндинг q a f, создающий и открывающий твой конфиг в файле ~/.atamanrc.conf.

Конфиг? Я что, должен ещё и сам придумать эти биндинги?

Я люблю Leader Key за мнемоники, которые помогают мне запомнить все эти биндинги. Вы конечно же можете взглянуть на мой конфиг для вдохновения. Но мои биндинги частично построены на моём опыте использования Doom Emacs, откуда я и взял идею leader key. В них есть специфичные для Emacs термины, типа [b]uffer для табов или [y]ank для копирования. Я привык, а кому-то может показаться неудобно. Поэтому я очень советую вам самим придумать себе свой идеальный конфиг.

Странный формат для конфига. Это типа JSON?

Для конфига используется формат HOCON – это очень классная надстройка над JSON, которая сделана специально для конфигов, но не такая бесячая, как YAML. А всё благодаря тому что вместо значащих отступов для вложенности используются фигурные скобки. Документацию к HOCON можно почитать в репозитории проекта. Ещё советую поставить плагин HOCON для Intellij, с автоформатом редактировать конфиг приятнее.

Ладно, а что за схема такая странная?

Я воспользовался гибкостью HOCON чтобы сделать конфиг удобным для чтения и редактирования. Корневым элементом конфига является группа биндингов bindings, которая по сути словарь биндингов к их определениям. Каждый биндинг может либо вызывать экшон либо быть префиксом для группы биндингов. У любого биндинга должен быть ключ description, который будет показываться в попапе, чтобы всегда можно было подсмотреть, что же там делает q d w a. Префиксы также имеют ключ bindings, прямо как в корне файла и дальше всё идёт по рекурсии. Биндинги экшонов же имеют ключ actionId, в котором лежит id нужного мне экшона. Пример конфига генерируется при первом использовании Ataman.

Пример конфига
bindings { # корень всего конфига
  c { # группа биндингиов, начинающаяся с префикса 'c'
    description: Code...
    bindings {
      # биндинги привязываются к экшонам через actionId
      r { actionId: RefactoringMenu, description: Refactor this... }
      f { actionId: ReformatCode, description: Reformat code }
      c { # группы биндингов могут вкладываться друг в друга
        description: Compile/Run...
        bindings { 
          a { actionId: RunAnything, description: Run Anything... }
          r { actionId: ReRun, description: Rerun last build }
        }
        # actionId: ... -- лучше так не делать, тут уже есть binding
      }
    }
  }
}

Где брать actionId?

actionId нужного вам экшена можно легко нагуглить, например здесь или здесь. Кроме того, в плагине IdeaVim, который я также рекомендую попробовать, есть режим трекинга айдишников. Просто включаю его – и каждый экшен сопровождается его айдишником во всплывашке справа внизу IDE. Если хочется такую же фичу в Ataman – я охотно принимаю пулл-реквесты.

IdeaVim? Ataman с ним интегрируется?

Да! Ataman вообще возник в ответ на фрустрацию от того, что IdeaVim не умеет в leader-key вне активного Editor. Если фокус перешел на Logcat или дерево проекта – все мои биндинги превращались в тыкву. Я давно хотел показать прелесть leader key подхода людям, не знакомым с Vim, поэтому идея написать отдельный плагин быстро была воплощена в жизнь. Для того чтобы использовать в качестве лидера традиционные для Vim SPACE или BACK_SLASH, в Ataman есть специальный экшн Transparent Leader, который работает как лидер только если ваш фокус вне текстового поля. В конфиге же IdeaVim следует прописать обычный экшон, который будет работать несмотря на фокус на Editor.

nnoremap <Space> :action LeaderAction<cr>
vnoremap <Space> :action LeaderAction<cr>

Конец

На этом всё, скачивайте плагин, ставьте звёздочки на гитхабе и в Jetbrains Marketplace, пишите отзывы и заводите на ишшьюсы на баги и хотелки.

Комментарии (39)


  1. TheKnight
    04.10.2021 23:59
    +4

    Вызов меню рефакторинга на Windows это Ctrl+Alt+Shift+T.

    Си-мажорный септаккорд, он же B7(или H7 в другой традиции записи), выглядит настолько же устрашающе :)


    1. slovak
      05.10.2021 22:46

      И при этом берется на первом-втором ладу довольно легко.


      1. TheKnight
        31.10.2021 00:20

        Именно поэтому я и привел в пример его, а не что-то более сложное, типа F#m7.


  1. miksir
    05.10.2021 01:51

    Как альтернатива, хотя где-то и более "многоклавишная", есть Find Action


  1. some_x
    05.10.2021 05:46
    +2

    Не понял проблему, неудобные биндинги по умолчанию? Так можно настроить. Тем более у jetbrains обычно несколько keymap-ов на выбор. Например в keymap resharper rename это F2.

    Зачем вам больше 36-ти биндингов, вы реально ими пользуетесь каждый день? КМК ходовых биндингов на каждый день нужно намного меньше: rename, go to everything, go to everywhere, go to declaration/implementation, comment/uncomment, fold/unfold... что ещё? ну может ещё 2-3 биндинга. Для всего остального можно пользоваться клавишей контекстно меню.

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


  1. zhulan0v
    05.10.2021 07:44
    +2

    Хорошая идея


  1. lkoida
    05.10.2021 08:20
    +1

    Ух ты, интересно. Надо будет попробовать.


  1. Darkwing4
    05.10.2021 08:20
    +1

    Тоже пользуюсь KeyPromt X, специально во всех IDE от JB выставил одинаковую раскладку и переучился на нее (rider, pycharm и т.д.), но все ровно конца и края этим хоткеям нет, да и нечастые хоткеи часто забываются. Однозначно попробую ваш плагин, спасибо за статью, очень интересный подход.

    А можно ссылку на гитхаб?

    И можно ли сделать leader key доступным, когда окно intellij не в фокусе (на Ctrl + shift + L, например)?


    1. Mishkun Автор
      05.10.2021 08:31

      Ссылочка на гитхаб вот https://github.com/Mishkun/ataman-intellij

      Насчёт того чтобы открывать лидер когда окно не в фокусе, я не знаю о такой возможности, и быстрый поиск по API ничего не дал. Будь у intellij какой-нибудь daemon, которому можно было слать экшоны - это стало бы возможно, но его нет


      1. SquareRootOfZero
        05.10.2021 10:28

        Так через AutoHotKey какой-нибудь, наверное, можно сделать? Типа, если пришла комбинация кнопок, и intellij присутствует в списке активных процессов, и его окно не в фокусе — передать этому окну фокус и повторить комбинацию кнопок туда.


  1. ionicman
    05.10.2021 10:41
    -1

    Ни разу не возникало описываемой автором проблемы при работе JB. Все базовое на хоткеях, в которых не больше 3 кнопок. Нажать их вообще не проблема. Все что нужно реже - вынесено на тулбар иконками. Все что ещё более редко - всегда проще либо мышкой нажать в соотв. меню, либо поиском и нажать. Я, естественно, за то, чтобы плагинов было как можно больше, но смысла вот такого - честно - не понимаю. И если оно что-то и сэкономит -то, имхо, какие-то крохи.


    1. artem_larin
      05.10.2021 10:45

      А вот мне лично клавиш Идеи "не хватает", т.е. все базовые сочетания уже заняты, и если я хочу забиндить доп.действия, приходится извращаться, и о мнемонике уж говорить и не стоит вообще. Появляются всякие абстрактные Ctrl+Alt+Shift+Буква. В том же Виме проблема решена изящно - мнемоникой, поэтому, работая в Виме, в уме я каждый раз мысленно конструирую команды Вима как предложения на его "языке" - это очень удобно.


      1. some_x
        05.10.2021 10:46

        Вы серьёзно используете десятки хоткеев каждый день?


        1. artem_larin
          05.10.2021 11:18
          +2

          Ну да. У меня около 20 кастомных комбинаций, и по максимуму использую дефолтные комбинации, коих тоже несколько десятков. Это же удобнее и быстрее, чем "работа мышкой", разве это не очевидно? Что вас тут смущает?))

          Ну так я еще спамлю в джетбрейнс тикеты по поводу того, что не все экшны байндятся))


          1. some_x
            05.10.2021 13:48
            +1

            Не могу представить что это за действия в таком бешенном количестве. Пытался посчитать здесь: https://habr.com/ru/post/581536/comments/#comment_23554900


            1. artem_larin
              05.10.2021 15:07

              Какие действия? Вот возьмем для примера ежедневные действия:

              Навигация:
              1. F2 / Shift+F2
              2. Ctrl+Shift+Bk
              3. Ctrl+Alt+Left/Right
              4. Ctrl+Shift+F (и в диалоге поиска: Alt+S, Alt+P)
              5-10. работа с результатами поиска: Alt+3, Alt+Down, Ctrl+Enter, Del, Ctr+Alt+Up/Down
              11. Ctrl+G
              12-13. Ctrl+Shift+Цифра/Ctrl+Цифра

              Навигация по структуре и вызовам:
              14. Ctrl+U
              15. Alt+F7
              16. Ctrl+Shift+F7
              17. Ctrl+Alt+B
              18. Ctrl+Shift+B
              19. Ctrl+B
              20. Ctrl+F12
              21. Alt+Up/Down
              22. Alt+Left/Right
              23. Ctrl+E
              24. Alt+F1
              25. Ctrl+Shift+F8

              Работа с гитом:
              26. Ctrl+Shift+Alt+Up/Down
              27. Ctrl+Alt+Shift+Z
              28. Ctrl+Alt+Z
              29. Ctrl+D (в окне истории)

              Запуск и компиляция:
              30.Ctrl+F9
              31-32. Alt+Shift+F9/F10
              33-34. Ctrl+Shift+F9,F10

              Настройки:
              35. Ctrl+Alt+S
              36. Ctrl+Alt+Shift+S

              Создание и рефакторинг:
              37. Alt+Ins
              38. Ctrl+Alt+M

              Редактирование текста:
              39. Ctrl+W/Ctrl+Shift+W
              40. Ctrl+D
              41. Ctrl+Z/Ctrl+Shift+Z

              Работа с окнами:
              42. Ctrl+Shift+F12

              Комбинации плагинов:
              43-44. FunkySearch: Ctrl+Shift+S/Ctrl+Shift+D

              Копирование:
              45. Ctrl+Shift+C

              Просмотр:
              46. Ctrl+Q
              47. Ctrl+Shift+I

              Поиск:
              48. F3/Shift+F3

              Всякая всячина:
              49. F4
              50. F5
              51. Shift+F6
              52. Клавиши тулзовых окон: Alt+1, Alt+9, Alt+0 и т.д.
              53. Ctrl+Space
              54. Ctrl+J и Tab
              55. Ctrl+M
              56. Ctrl+Up/Down
              57. Alt+Home

              И еще пара десятков кастомных комбинаций на доп.действия, такие как увеличить/уменьшить размер шрифта (полезно при демонстрациях экрана), pin/unpin окон типа Search Results, скопировать строку, Close All Notifications, и т.д.

              Это то, что сходу вспомнилось, т.е. это частые ежедневные действия. И еще может десяток-другой редких действий. Вот и выходит примерно 70-80 комбинаций. При анализе конечно можно увидеть, что половина этих хоткеев относятся к классическим, типа Ctrl+Z/Ctrl+Shift+Z - это классические undo/redo. Таким анализом не занимался, но даже если половину указанных выше хоткеев списать на "классику", останется ещё 30-40 хоткеев, которые не имеют мнемоник и для которых данный плагин будет уместен. Например, хоткеи типа Ctrl+J или Ctrl+Alt+B вообще не имеют мнемоник и запоминаются чисто "на мышечной памяти" от постоянно употребления.


              1. ionicman
                05.10.2021 20:33
                -1

                А почему эти действия нельзя выполнять тычком мышки?

                Таже навигация по гиту?

                У меня хоткеев для частого использования около 20, все остальное - это действия мышкой, если надо.

                Т. е. если мне надо структуру или гит за исключением коммита - это делается мышой. Она для этого и дана.


                1. vtb_k
                  06.10.2021 08:42

                  Потому что когда привык "в вим" — мышка вызывает лишь ненависть и боль


                1. artem_larin
                  06.10.2021 11:21

                  >мне надо структуру или гит
                  90% этих задач прекрасно делаются клавиатурой, часто это быстрее и удобнее чем мышкой. Хотя с гитом мне больше нравится работать в SmartGit, он тоже позволяет работать с помощью клавиш - делать и мерж, и изучение изменений, и прочие операции.


        1. Mishkun Автор
          05.10.2021 12:57
          +3

          На самом деле замечал, что многие вещи, если их сделать проще в использовании, становятся внезапно нужными и даже необходимыми. Я до того как начал пользоваться Emacs вообще не понимал, как люди пишут кастомные плагины для IDE и что там вообще можно такого сделать. Это потому что в IntelliJ написать плагин – создать и настроить проект, разобраться в API, почитать доки, помучать gradle. А в Emacs – это добавить пару строчек в свой конфиг. Но решения находятся, есть замечательный LivePlugin, который сильно упрощает написание таких мелочей. Ataman так и родился, как один класс в конфиге LivePlugin.

          Суть моего спича выше в том, что если уменьшить трение, то многие вещи начинают быть удобнее. В моём конфиге несколько десятков биндингов и то, я каждую неделю добавляю новые


    1. essome
      05.10.2021 14:53

      Я не знаю как можно закрывать таб ctrl + f4 вместо ctrl + w


  1. artem_larin
    05.10.2021 10:42
    +1

    Конгениально, будем пробовать!


  1. vba
    05.10.2021 10:49

    Я когда учился играть на гитаре так сильно пальцы не утруждал.

    Вы хотите сказать что после работы в IDEA обучение игре на гитаре будет легче.


  1. vba
    05.10.2021 12:09

    Подскажите, пожалуйста, как написать баиндинг что бы запускать External Tool, по имени? Спасибо.


    1. Mishkun Автор
      05.10.2021 13:01

      "Tool_External Tools_Имя Твоего External Tool с Пробелами"


  1. shafirov
    05.10.2021 12:12

    Попробуйте Quick Lists: Settings / Appearance & Behavior / Quick List
    Затем задать leading shortcut на Quick List в Settings / Keymap


    1. Mishkun Автор
      05.10.2021 13:02

       От квиклистов этот плагин отличает две важные вещи:

      1) В квиклистах нужно либо использовать 0-9 для выбора либо quicksearch. Циферки не запомнишь толком, а квиксёрч для меня это слишком медленно и не сильно лучше чем поиск по экшонам. Я прокликиваю биндинги быстрее чем атаман успевает отрисоваться =)

      2) Я пользуюсь IdeaVim и мой leader key это пробел. Поэтому без специального хака с Transparent Leader который проверяет нет ли редактируемого поля в фокусе не обойтись. Я вообще этот плагин сделал для того чтобы лидер использовать вне редактора, так-то можно и в IdeaVim конфиге лидер прописать, но он работает только в активном editor-е, а если сместить фокус на какой-нибудь logcat, то нет


      1. shafirov
        05.10.2021 13:19

        Разумно, да. Про первый пункт особенно согласен. Можно было бы улучшить конфигурирование Quick List и разрешить указывать мнемоники, но вообще функциональностью Quick List настолько редко пользуются, к сожалению, поэтому всегда находятся задачи поважнее


        1. Mishkun Автор
          05.10.2021 14:27

          Лучше уж отрефакторить Second Stroke биндинги, чтобы можно было их делать больше двух =)


  1. buldo
    05.10.2021 13:34

    Ого, пользовался таким в Visual Studio и не знал что это такая распространённая фича. Хотя там комбинации все сильно короткие


  1. indestructable
    05.10.2021 14:19

    Подскажите, где взять ActionIds для Rider?


    1. aulitin
      05.10.2021 17:20
      +1

      как вариант - включить internal mode и сделать help -> Find action -> dump keyboard shortcuts


      1. indestructable
        06.10.2021 10:57

        Спасибо, частично получилось. В отчете не все экшены, возможно, .только те, на которые назначены шорткаты.


  1. ris58h
    05.10.2021 17:35

    Идея хорошая и вроде как в windows это должно работать по нажатию Alt - вы попадаете в меню и там уже переходите по подпунктам нажимая соответствующие клавиши.


    1. Mishkun Автор
      05.10.2021 17:51

      Если ты имеешь в виду клавишу, которая открывает контекстное меню – Ataman не ограничен лишь им. Ты можешь прописать в конфиге любой экшн, а не только доступные из текущего контекстного меню


      1. ris58h
        06.10.2021 12:12

        Я про верхнее меню (контекстное - это про правый клик мышью).

        Тут хорошая статья есть про шорткаты и удобство http://xahlee.info/kbd/banish_key_chords.html. Пункт "Microsoft's Alt Key System" как раз про то что я описал.


        1. Mishkun Автор
          06.10.2021 15:11
          +1

          Статья (да и весь блог) классны, схоронил


  1. EdPavlov
    07.10.2021 16:02
    +1

    Это то, чего мне не хватало для полного клавиатурного счастья! Спасибо огромное! :)


  1. sarmanovcom
    16.11.2021 08:12

    Чётко получилось, это мега удобно, спасибо!!!