Зачастую, в ответ на вопрос "Как переназначить клавиши на macOS?" советуют использовать сторонний софт, например, Karabiner-Elements, но простое переназначение клавиш возможно и нативными средствами.

Задача

Уже много лет я переназначаю Esc на CapsLock во всех ОС, которыми пользуюсь (писал об этом в Не мучайте свой мизинец). В macOS это можно сделать прямо в настройках. Для macOS Ventura это System Settings > Keyboard > Keyboard Shortcuts... > Modifier Keys. Получается, освобождается клавиша Esc, которую можно было бы чем-то занять.

Для macOS есть популярный аналог Terminal - iTerm2. Одна из его фишек - Hotkey Window - выпадающее окно терминала (как в Quake, где оно появляется по нажатию на ~), которое вызывается по горячей клавише, заданной пользователем. Отличная возможность для освободившейся клавиши Esc!

В итоге, на CapsLock должен быть Esc, а по нажатию на Esc - выпадать терминал.

Решение

Переназначим CapsLock на Esc, а Esc на F13. В настройках iTerm2 укажем F13 как клавишу для активации Hotkey Window.

Почему F13, а не тот же CapsLock или что-то ещё? Просто это неиспользуемая клавиша, а использование CapsLock может поменять нам регистр в самый неподходящий момент, если iTerm2 не запущен.

Почему не сторонний софт

Можно было бы использовать Karabiner-Elements (я проверял - работает), но это сторонний софт, который требует доступ к Accessibility, а ещё он размазан по системе так, что его не так-то просто удалить (это я тоже проверил на себе). Да и зачем это всё, когда можно воспользоваться нативными механизмами ОС?

hidutil

Согласно Technical Note TN2450, для переназначения клавиш в macOS можно воспользоваться инструментом командной строки hidutil. Ниже пример кода для того чтобы поменять местами клавиши A и B:

$ hidutil property --set '{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc":0x700000004,"HIDKeyboardModifierMappingDst":0x700000005},{"HIDKeyboardModifierMappingSrc":0x700000005,"HIDKeyboardModifierMappingDst":0x700000004}]}'

В этом примере мы устанавливаем значение свойства UserKeyMapping - это массив из пар HIDKeyboardModifierMappingSrc и HIDKeyboardModifierMappingDst. HIDKeyboardModifierMappingSrc - это какую клавишу мы переопределяем, а HIDKeyboardModifierMappingDst - та клавиша, код которой мы хотим воспроизвести. Код клавиши - это шестнадцетиричное число полученное путём применения операции ИЛИ к числу 0x700000000 и значению клавиши. Таблицу значений для клавиш можно посмотреть тут.

В нашем случае, нужно поменять CapsLock (0x700000039) на Esc (0x700000029), а Esc (0x700000029) на F13 (0x700000068):

hidutil property --set '{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc":0x700000039,"HIDKeyboardModifierMappingDst":0x700000029},{"HIDKeyboardModifierMappingSrc":0x700000029,"HIDKeyboardModifierMappingDst":0x700000068}]}'

Теперь в настройках iTerm2 выбираем профиль, который хотим использовать в выпадающей консоли. Ставим галочку A hotkey opens a dedicated window with this profile в настройках профиля (Preferences > Profiles > Ваш профайл > Keys > General) назначаем F13 в качестве горячей клавиши для Hotkey Window (Preferences > Profiles > Ваш профайл > Keys > General > Configure Hotkey Window > Hotkey).

Результат работы: выпадающий терминал по нажатию Esc.
Результат работы: выпадающий терминал по нажатию Esc.

Внимание: если у вас в настройках клавиатуры macOS (для macOS Ventura этоSystem Settings > Keyboard > Keyboard Shortcuts... > Modifier Keys) CapsLock уже переназначен, то это не заработает. Необходимо убрать это переназначение.

Запуск при логине

Настройки сделанные с помощью hidutil будут сброшены после перезагрузки. Чтобы этого не случилось, настроим запуск этой команды при логине.

Есть несколько способов это сделать. Я использовал LaunchAgent. Для этого в директории ~/Library/LaunchAgents/ создадим plist файл (в моём случае ris58h.KeyRemapping.plist). Содержимое файла:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>ris58h.KeyRemapping</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/hidutil</string>
        <string>property</string>
        <string>--set</string>
        <string>{"UserKeyMapping":[
          {
            "HIDKeyboardModifierMappingSrc": 0x700000039,
            "HIDKeyboardModifierMappingDst": 0x700000029
          },
          {
            "HIDKeyboardModifierMappingSrc": 0x700000029,
            "HIDKeyboardModifierMappingDst": 0x700000068
         }
        ]}</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

Label - некоторый уникальный идентификатор LaunchAgent-а.

ProgramArguments - массив из элементов команды, которую мы хотим выполнить.

RunAtLoad - флаг для запуска при загрузке.

Теперь наши настройки будут применены даже после перезагрузки.

UPDATES:

  • Для создания plist файла можно использовать https://hidutil-generator.netlify.app/

  • На SO есть пример с тем, как переназначить клавиши конкретной клавиатуры, если у вас их несколько (к вызову hidutil нужно добавить параметр с идентификатором устройства: --matching '{"ProductID":0x123}') https://stackoverflow.com/a/58981641/9137155

  • @legos в комментарии указал на настройки внешнего вида консоли в iTerm2

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


  1. FreeNickname
    26.10.2022 15:54
    +1

    Промазал между нужного пункта во втором опросе. -1 за "Да", +1 за "Да с консолью") Quake-образная консоль была едва ли не первым, что я искал, как сделать, когда заполучил мак :) Правда, я забиндил косноль на Cmd + "кнопка слева от единички" (отличается в разных раскладках, вроде как). А Karabiner-Elements использую для адаптации виндовой клавиатуры к маковской раскладке, когда работаю с внешней клавиатурой, при этом чтобы не перекосячить родную ноутбучную клавиатруру. Через стандартные системные настройки не получается, а в глубины консоли для этого я не лез :)


    1. ris58h Автор
      26.10.2022 16:44

      для адаптации виндовой клавиатуры к маковской раскладке

      Можно подробнее? Речь про раскладку Russian - PC?

      забиндил косноль на Cmd + "кнопка слева от единички"

      Cmd+~ - это ж переключение окон активного приложения. Что вместо этого используете?


      1. FreeNickname
        26.10.2022 16:51

        Нет, это-то я знаю, как поменять системными средствами, но это и не нужно) Речь про спец. кнопки (забыл, как они правильно называются). На маке нижний ряд кнопок:
        fn - control - option (alt) - command - space - command - option (alt) - стрелки
        На моей виндовой клавиатуре
        ctrl - win - alt - space - alt - ctrl

        Мне удобно, чтобы было как на маковой, слева и справа от пробела вначале cmd, потом alt. Но, во-первых, стандартными средствами (по крайней мере, через UI) можно только оба ctrl превратить в cmd, а мне левый ctrl тоже нужен. Это во-первых, а во-вторых, если я превращу ctrl в cmd, то на основной ноутбучной клавиатуре ctrl тоже превратится в cmd, а мне там ничего не нужно трогать.

        Karabiner-Elements как раз позволяет перебиндить клавиши для конкретной клавиатуры, плюс отдельно биндить левый/правый ctrl / alt / win.

        А, ну ещё на виндовой клавиатуре и на маковой та самая кнопка для показа консоли в другом месте, ещё её перебиндил :)

        TL;DR: маковская клавиатура остаётся как есть, а спец. клавиши на виндовой максимально трансформируются в маковую.


        1. ris58h Автор
          26.10.2022 17:02
          +1

          Нашел на SO пример для переназначения под конкретную клавиатуру: https://stackoverflow.com/a/58981641/9137155 . Сам пока не проверял.

          P.S.: я там свой комент выше вопросом дополнил. Продублирую:

          Cmd+~ - это ж переключение окон активного приложения. Что вместо этого используете?


          1. FreeNickname
            26.10.2022 18:55

            У меня русская маковая клавиатура, на ней слева от единицы не ~, а апостроф, больше/меньше и плюс/минус) А тильда слева от Z/Я. Но при этом на виндовой клавиатуре тильда слева от единички, а "непонятно что" слева от буквы Я, т.е. они перепутаны и, опять же, надо биндить для конкретной клавиатуры, чтобы работало единообразно. Одно время, помнится, я тильду биндил на "слева от единички", т.к. это привычнее. Но, честно говоря, переключение окон активного приложения у меня не особо прижилось, поэтому как кнопкой ввода я пользуюсь этими двумя кнопками нечасто. Только когда в Markdown надо что-нибудь зачеркнуть :)

            Спасибо за ссылку!


            1. ris58h Автор
              27.10.2022 12:46

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


  1. legos
    26.10.2022 22:15
    +1

    Спасибо! Это именно то, чего всегда не хватало.

    Настроил без всяких переназначений, на ту кнопку, где на PC-клавиатуре была тильда - слева от 1 (символ параграфа).

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


    1. ris58h Автор
      27.10.2022 00:02

      Не заметил в статье в статье упоминания дополнительных настроек

      Похоже, они у меня по-умолчанию выставились, хоть я и на новом профиле проверял.

      Прикладываю скрины настроек.

      Спасибо. Добавлю в статью.


    1. citius
      27.10.2022 00:20

      >Настроил без всяких переназначений, на ту кнопку, где на PC-клавиатуре была тильда - слева от 1 (символ параграфа).

      Как именно настроил, можно детали? Я уже сломался весь, не работает.


      1. ris58h Автор
        27.10.2022 00:39
        +1

        А что уже сделали и что не работает?

        Нужно:

        • Профиль для Hotkey Window в iTerm2 (можно использовать текущий или создать новый профиль, можно через Preferences > Keys > Hotkey > Create a Dedicated Hotkey Window).

        • В настройках в профиле задать Hotkey (Preferences > Profile > Нужный профиль > Keys > General > Configure Hotkey Window > Hotkey).

        • Настроить внешний вид окна, если нужно.


        1. citius
          27.10.2022 00:45

          Мне нужно на системном уровне поменять кнопку §/± (слева от 1), чтобы она генерила `/~.
          Сейчас в системе по дефолту вообще нет возможности ввести символ тильды, кнопка слева от Z генерит `/˜ - не та тильда.

          Раньше я в целом не без костылей, но решал проблему с помощью Karabiner-Elements, но сейчас он фактически сломан. Отключать SIP не хочется (а на корпоративном ноуте и в принципе нельзя).

          Т.е. дело не в iTerm как таковом, это же паллиатив. Кнопки должны правильно работать везде, и в слаке и в IDE.


          1. FreeNickname
            27.10.2022 01:16

            А что с Karabiner-Elements? Я последний раз пользовался месяца два назад – работал) 
            Я, вроде бы, переназначал так, но это не точно, возможно это старый конфиг.


            1. citius
              28.10.2022 01:21

              Его нельзя просто так поставить, нужно отключать SIP, либо еще как-то по хитрому изголяться с системой. Первое не позволяет корпоративная политика на рабочем ноуте, второе у меня не сработало.

              https://github.com/pqrs-org/Karabiner-Elements/issues/2438


          1. ris58h Автор
            27.10.2022 08:37

            Так а вы что уже попробовали? С помощью hidutil, как в статье, маппинг добавляли?

            Вот тут пишут про код клавиши для §/±: "The Usage ID you are looking for is 0x64."

            У тильды (Keyboard Grave Accent and Tilde) код 0x35, согласно таблице.

            Это согласуется с тем, что в конфиге для Karabiner-Elements у @FreeNickname в комменте выше.

            Короче, чтобы "поменять кнопку §/± (слева от 1), чтобы она генерила `/~" попробуйте:

            hidutil property --set '{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc":0x700000064,"HIDKeyboardModifierMappingDst":0x700000035}]}'


            1. citius
              28.10.2022 01:28
              +1

              Это только половина проблемы. Да, кнопка перекидывается.

              Но по прежнему вводится не то, вместо нормальной тильды ~ верхняя ˜.

              PS: я нашел долбаный корень зла, латинскую раскладку нужно выбирать просто U.S. а никак не U.S. International PC которая у меня стояла.


  1. OptimumOption
    27.10.2022 08:27

    "... Почему F13, а не тот же CapsLock или что-то ещё? Просто это неиспользуемая клавиша..." - конечно, где же её взять на простой Magic Keyboard? Да и не комильфо "консоль" вешать на какую то "Ф", если уж разговор пошел про Quake. Вешайте на тильду!


  1. debug45
    27.10.2022 10:00

    Позволяет ли этот инструмент назначить не просто другую клавишу, а сочетание других клавиш?


    1. ris58h Автор
      27.10.2022 12:42

      Похоже, что нет. В этом случае проще Karabiner-Elements использовать.


  1. denisstfu
    27.10.2022 10:48
    +2

    Самая удобная настройка в MacOS - возможность просто чекбоксом поменять функционал Caps Lock на смену раскладки. Если надо переключить регистр, то просту держим кнопку чуть дольше.