A simple example of private.xml

<?xml version="1.0"?>
<root>
  <item>
    <name>Swap Space and Tab</name>
    <identifier>private.swap_space_and_tab</identifier>
    <autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::TAB</autogen>
    <autogen>__KeyToKey__ KeyCode::TAB, KeyCode::SPACE</autogen>
  </item>

  <item>
    <name>Change Right Command Key to Escape</name>
    <identifier>private.right_command_to_escape</identifier>
    <autogen>__KeyToKey__ KeyCode::COMMAND_R, KeyCode::ESCAPE</autogen>
  </item>
</root>

2 settings are added by this private.xml.

Examples of <autogen>

There are a lot of examples of <autogen> in "Samples for Karabiner Binding Developers" at the bottom of Karabiner Prefs.
You can see the raw XML from samples.xml.

In addition, prepared settings are described in checkbox.xml. These are also good examples of <autogen>.

The XML is also installed into your machine.
See /Applications/Karabiner.app/Contents/Resources/.

You can add a new setting by <item>.

<?xml version="1.0"?>
<root>

  <item>
    <name>Name of Setting</name>
    <appendix>Optional Description of Setting</appendix>
    <identifier>Unique Identifier of Setting</identifier>
    <autogen>Behavior Definition</autogen>
    <autogen>Behavior Definition</autogen>
  </item>

  <item>...</item>

  <item>...</item>

</root>

Please write <name>, <identifier>, <autogen> under <item>.

<name>
<appendix>
These values are used in Preference Pane.
<identifier> This value is used to identify setting.
You need to specify a unique value. We recommend you to add a "private." prefix to your identifier. It prevents conflicts with identifiers of prepared settings.
<autogen> Definition of this setting behavior.
For example, __KeyToKey__, __PointingButtonToKey__.

List of KeyCode, ConsumerKeyCode, PointingButton

__KeyToKey__ syntax

Plain

This <autogen> changes space key to tab key.

<autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::TAB</autogen>

Modifier+Key to Key

This <autogen> changes "left control+space key" to tab key.

<autogen>
  __KeyToKey__
  KeyCode::SPACE, ModifierFlag::CONTROL_L,
  KeyCode::TAB
</autogen>

Modifier+Key to Modifier+Key

This <autogen> changes "left control+space key" to "left control+tab key".

<autogen>
  __KeyToKey__
  KeyCode::SPACE, ModifierFlag::CONTROL_L,
  KeyCode::TAB,   ModifierFlag::CONTROL_L
</autogen>

Multiple modifiers

You can use "|" to specify multiple modifiers.

This <autogen> changes "left control+fn+space key" to tab key.

<autogen>
  __KeyToKey__
  KeyCode::SPACE, ModifierFlag::CONTROL_L | ModifierFlag::FN,
  KeyCode::TAB
</autogen>

ModifierFlag::NONE

If you want to change key behavior only when specific modifiers are pressed, use ModifierFlag::NONE.

This <autogen> changes "fn+space key" to tab key and retain other modifier combinations+space key behavior.

Physical key Changed key State
space space Not changed
control+space control+space Not changed
fn+space tab Changed
fn+control+space fn+control+space Not changed
<autogen>
  __KeyToKey__
  KeyCode::SPACE, ModifierFlag::FN | ModifierFlag::NONE,
  KeyCode::TAB
</autogen>

Change to multiple keys

This <autogen> changes space key to tab,return key.

<autogen>
  __KeyToKey__
  KeyCode::SPACE,
  KeyCode::TAB, KeyCode::RETURN
</autogen>

Order of <autogen>

Basic case

Karabiner applies only the first matched <autogen>.

The following autogens change space key to tab key (not return key).

<autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::TAB</autogen>
<autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::RETURN</autogen>

More complex case

If you want to change "shift+space to tab" and "space to return", you need to order <autogen> as follows.

Physical key Changed key
shift+space tab
space return
<!-- shift+space to tab -->
<autogen>__KeyToKey__ KeyCode::SPACE, ModifierFlag::SHIFT_L, KeyCode::TAB</autogen>

<!-- space to return -->
<autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::RETURN</autogen>

Wrong case If you've put them in reverse order, Karabiner changes "shift+space" to "shift+return".

<!-- Karabiner always changes space key to return key even if you're pressing shift modifier. -->
<autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::RETURN</autogen>

<!-- *** This autogen is never applied. *** -->
<autogen>__KeyToKey__ KeyCode::SPACE, ModifierFlag::SHIFT_L, KeyCode::TAB</autogen>

Type of identifier prefix

You can add a special behavior by using some prefix on <identifier>.

Prefix Behavior
notsave. "notsave." prefix is designed for creating "mode".
  • This setting is not saved even if it was enabled.
  • This setting priority is higher than normal settings.
  • User cannot enable this setting by Preference. (Use KeyCode::VK_CONFIG_*.)

You can define settings which are effective in specific conditions.
For example:

  • Change keys in some apps.
  • Change keys in some devices.
  • Change keys in some input sources.
  • Change keys if specified configuration is enabled.

You can see all filters and examples in filters.xml. (You can try them by searching "developer filters" in Preferences.)

Basic usage

Put filters into <item>. If multiple filters are specified, <autogen> will be effective if all conditions are true.

<?xml version="1.0"?>
<root>
  <item>
    <name>Swap space key and tab key</name>
    <identifier>private.filters_example</identifier>

    <!--
      Swap keys in Safari, Firefox or Google Chrome if you are using Apple keyboards.
    -->

    <only>SAFARI, FIREFOX, GOOGLE_CHROME</only>

    <device_only>DeviceVendor::APPLE_COMPUTER, DeviceProduct::ANY</device_only>

    <autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::TAB</autogen>
    <autogen>__KeyToKey__ KeyCode::TAB, KeyCode::SPACE</autogen>
  </item>
</root>

Narrow filters

Filters are applied to all <autogen> that are same level nodes or children nodes.
If you want to narrow filters, please use <block>.

<?xml version="1.0"?>
<root>
  <item>
    <name>Change numeric keys to keypad.</name>
    <appendix>+ Change space key to left click in Safari.</appendix>
    <identifier>private.filter_block_example</identifier>

    <autogen>__KeyToKey__ KeyCode::KEY_0, KeyCode::KEYPAD_0</autogen>
    <autogen>__KeyToKey__ KeyCode::KEY_1, KeyCode::KEYPAD_1</autogen>
    <autogen>__KeyToKey__ KeyCode::KEY_2, KeyCode::KEYPAD_2</autogen>
    <autogen>__KeyToKey__ KeyCode::KEY_3, KeyCode::KEYPAD_3</autogen>
    <autogen>__KeyToKey__ KeyCode::KEY_4, KeyCode::KEYPAD_4</autogen>
    <autogen>__KeyToKey__ KeyCode::KEY_5, KeyCode::KEYPAD_5</autogen>
    <autogen>__KeyToKey__ KeyCode::KEY_6, KeyCode::KEYPAD_6</autogen>
    <autogen>__KeyToKey__ KeyCode::KEY_7, KeyCode::KEYPAD_7</autogen>
    <autogen>__KeyToKey__ KeyCode::KEY_8, KeyCode::KEYPAD_8</autogen>
    <autogen>__KeyToKey__ KeyCode::KEY_9, KeyCode::KEYPAD_9</autogen>

    <block>
      <!-- This filter will not be applied to parent autogens. -->
      <only>SAFARI</only>
      <autogen>__KeyToKey__ KeyCode::SPACE, PointingButton::LEFT</autogen>
    </block>
  </item>
</root>

An example

You can define settings which are effective in specific applications only.
Add <only> or <not> to your <item>.

This private.xml exchanges space key and tab key in Safari and Google Chrome.

<?xml version="1.0"?>
<root>
  <item>
    <name>Swap Space and Tab</name>
    <identifier>private.app_safari_swap_space_and_tab</identifier>

    <only>SAFARI, GOOGLE_CHROME</only>

    <autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::TAB</autogen>
    <autogen>__KeyToKey__ KeyCode::TAB, KeyCode::SPACE</autogen>
  </item>
</root>

Steps to define an application specific setting

Examine a bundle identifier of target application

  1. Launch EventViewer from a menu.
  2. See "App" tab of EventViewer.
    This list is updated when you changed the current application.

    Change the current application to target application. Then press "copy to pasteboard" button.
    You can paste this information to text area.

Add an application definition to your private.xml.

  1. Add <appdef> to your private.xml.
    <appname> is a name of application which you use in <only> filter.
    Write the bundle identifier into <equal>.
    <?xml version="1.0"?>
    <root>
      <appdef>
        <appname>APPSTORE</appname>
        <equal>com.apple.appstore</equal>
      </appdef>
    </root>
  2. Then, you can use <only>APPSTORE</only> in private.xml.
    <?xml version="1.0"?>
    <root>
      <appdef>
        <appname>APPSTORE</appname>
        <equal>com.apple.appstore</equal>
      </appdef>
    
      <item>
        <name>Space to Tab in App Store.app</name>
        <identifier>private.appdef</identifier>
        <only>APPSTORE</only>
        <autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::TAB</autogen>
      </item>
    </root>

Multiple apps

You can specify multiple apps by a comma separated list.
For example, <only>GOOGLE_CHROME, FIREFOX, SAFARI</only> means "Google Chrome or Firefox or Safari".

appdef syntax

You have to put one <appname> into <appdef>.
And you can put multiple <equal>, <prefix> and <suffix>.

<appname> This value is used in <only> and <not> filters.
<equal> Specify an entire bundle identifier.
<prefix>
<suffix>
Specify a prefix/suffix of bundle identifier.
For example, <prefix>org.pqrs.</prefix> matches any bundle identifiers that start with "org.pqrs.". (eg. org.pqrs.Karabiner, org.pqrs.Seil)

Multiple <equal>, <prefix> and <suffix> are joined by 'OR'.
For example, the following appdef will be matched "org.pqrs.aaa" or "org.pqrs.bbb" or "org.pqrs.ccc.*" or "*.local".

<appdef>
  <appname>PQRS</appname>
  <equal>org.pqrs.aaa</equal>
  <equal>org.pqrs.bbb</equal>
  <prefix>org.pqrs.ccc.</prefix>
  <suffix>.local</suffix>
</appdef>

Prepared application definitions

Karabiner provides various application definitions.
You can use them without <appdef> in private.xml.

You can also overwrite existent application definitions by private.xml.
If you overwrite TERMINAL definition as follows, <only>TERMINAL</only> is effective in Apple's Terminal.app only (not iTerm2 and other terminal apps).

<?xml version="1.0"?>
<root>
  <appdef>
    <appname>TERMINAL</appname>
    <equal>com.apple.Terminal</equal>
  </appdef>
</root>

An example

You can define settings which are effective in specific window name only.
Add <windowname_only> or <windowname_not> to your <item>.

This private.xml disables command-w in Gmail on Google Chrome.

<?xml version="1.0"?>
<root>
  <item>
    <name>Disable command-w in Gmail on Google Chrome.</name>
    <identifier>private.windowname_google_chrome_gmail_disable_close</identifier>
    <only>GOOGLE_CHROME</only>

    <windowname_only>Gmail</windowname_only>

    <autogen>
      __KeyToKey__
      KeyCode::W, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_COMMAND | ModifierFlag::NONE,
      KeyCode::VK_NONE,
    </autogen>
  </item>
</root>

Steps to define an window name specific setting

Examine window name

  1. Launch EventViewer from a menu.
  2. See "App" tab of EventViewer.
    This list is updated when a window name is changed.

    Note: The window name detection does not work properly in some apps. (eg. Safari.)

    Focus target window. Then press "copy to pasteboard" button.
    You can paste this information to text area.

Add an window name definition to your private.xml.

  1. Add <windownamedef> to your private.xml.
    <name> is a name of definition which you use in <windowname_only> filter.
    Write regular expressions pattern into <regex>. (regex patterns follow the ECMAScript syntax.)
    <?xml version="1.0"?>
    <root>
      <windownamedef>
        <name>Google_Search</name>
        <regex> - Google Search$</regex>
      </windownamedef>
    </root>
  2. Then, you can use <windowname_only>Google_Search</windowname_only> in private.xml.
    <?xml version="1.0"?>
    <root>
      <windownamedef>
        <name>Google_Search</name>
        <regex> - Google Search$</regex>
      </windownamedef>
    
      <item>
        <name>Disable command-w in Google Search on Google Chrome.</name>
        <identifier>private.windownamedef</identifier>
        <windowname_only>Google_Search</windowname_only>
        <autogen>
          __KeyToKey__
          KeyCode::W, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_COMMAND | ModifierFlag::NONE,
          KeyCode::VK_NONE,
        </autogen>
      </item>
    </root>

Prepared window name definitions

Karabiner provides various window name definitions.
You can use them without <windownamedef> in private.xml.

You can also overwrite existent window name definitions by private.xml.

An example

You can define settings which are effective in specific ui element role only.
It's useful when you want to make settings which are effective only if the focused element is text area (text field).

Add <uielementrole_only> or <uielementrole_not> to your <item>.

This private.xml changes hjkl keys to arrow keys in Finder.
And hjkl keys will not be modified if you are editing a file name.

<?xml version="1.0"?>
<root>
  <item>
    <name>Change hjkl keys to arrow keys in Finder</name>
    <identifier>private.hjkl_keys_to_arrow_keys_in_finder</identifier>

    <uielementrole_not>AXTextArea, AXTextField</uielementrole_not>

    <only>FINDER</only>
    <modifier_only>
      ModifierFlag::NONE,
      ModifierFlag::SHIFT_L | ModifierFlag::NONE,
      ModifierFlag::SHIFT_R | ModifierFlag::NONE,
    </modifier_only>
    <autogen>__KeyToKey__ KeyCode::H, KeyCode::CURSOR_LEFT</autogen>
    <autogen>__KeyToKey__ KeyCode::J, KeyCode::CURSOR_DOWN</autogen>
    <autogen>__KeyToKey__ KeyCode::K, KeyCode::CURSOR_UP</autogen>
    <autogen>__KeyToKey__ KeyCode::L, KeyCode::CURSOR_RIGHT</autogen>
  </item>
</root>

Confirm ui element role

You can confirm a focused ui element's role by EventViewer.

Prepared ui element role definitions

Karabiner provides various ui element role definitions.

You can also add your own ui element role by <uielementroledef> tag.

You can define settings which are effective on specific device only.
Add <device_only> or <device_not> to your <item>.

This private.xml turns scroll wheel off on Magic Mouse.

<?xml version="1.0"?>
<root>
  <item>
    <name>Disable ScrollWheel on Magic Mouse</name>
    <identifier>private.dropscrollwheel_0x05ac_0x030d</identifier>

    <device_only>DeviceVendor::APPLE_COMPUTER,DeviceProduct::MAGIC_MOUSE</device_only>

    <autogen>__DropScrollWheel__</autogen>
  </item>
</root>

Steps to define a device specific setting

Examine Vendor ID and Product ID of a target device

  1. Launch EventViewer from a menu.
  2. See "Devices" tab of EventViewer.

    Then press "copy to pasteboard" button.
    You can paste this information to text area.

Add an device definition to your private.xml

  1. Add <devicevendordef> and <deviceproductdef> to your private.xml.
    <?xml version="1.0"?>
    <root>
      <devicevendordef>
        <vendorname>HEWLETT_PACKARD</vendorname>
        <vendorid>0x03f0</vendorid>
      </devicevendordef>
    
      <deviceproductdef>
        <productname>MY_HP_KEYBOARD</productname>
        <productid>0x0224</productid>
      </deviceproductdef>
    </root>
  2. Then, you can use <device_only> in private.xml.
    <?xml version="1.0"?>
    <root>
      <devicevendordef>
        <vendorname>HEWLETT_PACKARD</vendorname>
        <vendorid>0x03f0</vendorid>
      </devicevendordef>
    
      <deviceproductdef>
        <productname>MY_HP_KEYBOARD</productname>
        <productid>0x0224</productid>
      </deviceproductdef>
    
      <item>
        <name>Space to Tab in MY_HP_KEYBOARD</name>
        <identifier>private.deviceproductdef</identifier>
        <device_only>DeviceVendor::HEWLETT_PACKARD, DeviceProduct::MY_HP_KEYBOARD</device_only>
        <autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::TAB</autogen>
      </item>
    
    </root>

Multiple devices

You can specify multiple devices by a comma separated list.
For example, the following <device_only> means "Magic Mouse or Logitech Unifying".

  <device_only>
    DeviceVendor::APPLE_COMPUTER, DeviceProduct::MAGIC_MOUSE,
    DeviceVendor::LOGITECH, DeviceProduct::LOGITECH_UNIFYING_0xc52b,
  </device_only>

Prepared device definitions

Karabiner provides various Vendor ID and Product ID definitions.
You can use them without <devicevendordef> and <deviceproductdef> in private.xml.

You can also overwrite existent device definitions by private.xml.

How to distinguish multiple devices which have same Vendor ID and Product ID

You can use "Location ID" in order to distinguish multiple devices which have same Vendor ID and Product ID.

Learn about "Location ID"

  • "Location ID" is an unique identifier even if devices have same Vendor ID and Product ID.
  • The behavior of "Location ID" is different for each type of device.
Device Type What's Location ID? Is immutable?
USB Device Location ID is determined by USB port. This value will be changed when you pull out USB device and plug it into other USB port.
Bluetooth Device Location ID is determined by Bluetooth Address. This value is immutable.

Examine Location ID

You can examin Location ID by EventViewer.

Location ID in XML

You can specify Location ID like this.

<?xml version="1.0"?>
<root>
  <devicevendordef>
    <vendorname>HEWLETT_PACKARD</vendorname>
    <vendorid>0x03f0</vendorid>
  </devicevendordef>

  <deviceproductdef>
    <productname>MY_HP_KEYBOARD</productname>
    <productid>0x0224</productid>
  </deviceproductdef>

  <devicelocationdef>
    <locationname>MY_HP_KEYBOARD_PRIMARY</locationname>
    <locationid>0xfa120000</locationid>
  </devicelocationdef>

  <item>
    <name>Space to Tab in MY_HP_KEYBOARD</name>
    <identifier>private.deviceproductdef</identifier>
    <device_only>
      DeviceVendor::HEWLETT_PACKARD,
      DeviceProduct::MY_HP_KEYBOARD,
      DeviceLocation::MY_HP_KEYBOARD_PRIMARY,
    </device_only>
    <autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::TAB</autogen>
  </item>

</root>

An example

You can define settings which are effective in specific input source only.
Add <inputsource_only> or <inputsource_not> to your <item>.

This private.xml exchanges space key and tab key on Dvorak.

<?xml version="1.0"?>
<root>
  <inputsourcedef>
    <name>MY_DVORAK</name>
    <inputsourceid_prefix>com.apple.keylayout.Dvorak</inputsourceid_prefix>
  </inputsourcedef>

  <item>
    <name>Swap Space and Tab</name>
    <identifier>private.my_dvorak_swap_space_and_tab</identifier>

    <inputsource_only>MY_DVORAK</inputsource_only>

    <autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::TAB</autogen>
    <autogen>__KeyToKey__ KeyCode::TAB, KeyCode::SPACE</autogen>
  </item>
</root>

Steps

  1. Examine Input Source ID of target input source.
    How to examine input source id.

  2. Add <inputsourcedef> your private.xml.

    <?xml version="1.0"?>
    <root>
      <inputsourcedef>
        <name>MY_DVORAK</name>
        <inputsourceid_prefix>com.apple.keylayout.Dvorak</inputsourceid_prefix>
      </inputsourcedef>
    </root>
  3. Then, you can use <inputsource_only> and <inputsource_not> in private.xml.

    <?xml version="1.0"?>
    <root>
      <inputsourcedef>
        <name>MY_DVORAK</name>
        <inputsourceid_prefix>com.apple.keylayout.Dvorak</inputsourceid_prefix>
      </inputsourcedef>
    
      <item>
        <name>Swap Space and Tab</name>
        <identifier>private.my_dvorak_swap_space_and_tab</identifier>
        <inputsource_only>MY_DVORAK</inputsource_only>
        <autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::TAB</autogen>
        <autogen>__KeyToKey__ KeyCode::TAB, KeyCode::SPACE</autogen>
      </item>
    </root>

Prepared input source definitions

Karabiner provides various input source definitions.
You can use them without <inputsourcedef> in private.xml.

How to examine input source id

You can examine input source id by Event Viewer.

  1. Launch Event Viewer.
  2. Switch input source into target input source.
  3. Switch input source into other input source.
  4. Again, switch input source into target input source.
  5. See Input Source ID in Event Viewer.

An example

This private.xml opens web site, launches calculator and executes a shell command "/bin/date | /usr/bin/pbcopy".

<?xml version="1.0"?>
<root>
  <!-- generic URL -->
  <vkopenurldef>
    <name>KeyCode::VK_OPEN_URL_WEB_karabiner</name>
    <url>https://pqrs.org/osx/karabiner/</url>
  </vkopenurldef>

  <!-- file path -->
  <vkopenurldef>
    <name>KeyCode::VK_OPEN_URL_APP_Calculator</name>
    <url type="file">/Applications/Calculator.app</url>
  </vkopenurldef>

  <!-- shell commands -->
  <vkopenurldef>
    <name>KeyCode::VK_OPEN_URL_SHELL_date_pbcopy</name>
    <url type="shell">
      <![CDATA[    /bin/date | /usr/bin/pbcopy    ]]>
    </url>
  </vkopenurldef>

  <item>
    <name>Change right-command + w to open https://pqrs.org/osx/karabiner/</name>
    <identifier>private.right_command_w</identifier>
    <autogen>
      __KeyToKey__
      KeyCode::W, ModifierFlag::COMMAND_R,
      KeyCode::VK_OPEN_URL_WEB_karabiner,
    </autogen>
  </item>

  <item>
    <name>Change right-command + c to launch calculator</name>
    <identifier>private.right_command_c</identifier>
    <autogen>
      __KeyToKey__
      KeyCode::C, ModifierFlag::COMMAND_R,
      KeyCode::VK_OPEN_URL_APP_Calculator,
    </autogen>
  </item>

  <item>
    <name>Change right-command + d to execute /bin/date | /usr/bin/pbcopy</name>
    <identifier>private.right_command_d</identifier>
    <autogen>
      __KeyToKey__
      KeyCode::D, ModifierFlag::COMMAND_R,
      KeyCode::VK_OPEN_URL_SHELL_date_pbcopy,
    </autogen>
  </item>
</root>

Virtual key code definition

You can define new virtual key code by <vkopenurldef>.

  • <name> is a name of virtual key code. This name must be started with KeyCode::VK_OPEN_URL_.
    For example, <name>KeyCode::VK_OPEN_URL_Yourapp</name>.

  • <url> is a url of virtual key code.
    <url> has a "type" attribute which determines how treat the value.

    Type attribute Description
    (empty) If you does not specify a type attribute, it will be treated as a generic URL.
    type="file" The value will be treated as file path.
    type="shell" The value will be treated as shell commands.
  • <background /> (optional)
    If <background /> exists, URL will be opened in background.

Prepared virtual key code definitions

Karabiner provides various virtual key code definitions.
You can use them without <vkopenurldef> in private.xml.

An example

This private.xml changes input source to Dvorak by Right Shift Key + D.

<?xml version="1.0"?>
<root>
  <vkchangeinputsourcedef>
    <name>KeyCode::VK_CHANGE_INPUTSOURCE_MY_DVORAK</name>
    <inputsourceid_equal>com.apple.keylayout.Dvorak</inputsourceid_equal>
  </vkchangeinputsourcedef>

  <item>
    <name>Change input source to Dvorak by right shift key + D</name>
    <identifier>private.change_input_source_to_dvorak</identifier>
    <autogen>
      __KeyToKey__
      KeyCode::D, ModifierFlag::SHIFT_R,
      KeyCode::VK_CHANGE_INPUTSOURCE_MY_DVORAK
    </autogen>
  </item>
</root>

Virtual key code definition

You can define new virtual key code by <vkchangeinputsourcedef>.

  • <name> is a name of virtual key code. This name must be started with KeyCode::VK_CHANGE_INPUTSOURCE_.
    For example, <name>KeyCode::VK_CHANGE_INPUTSOURCE_YOUR_LANGUAGE</name>.

  • <inputsourceid_equal> is a input source id of target input source.
    How to examine input source id.

Prepared virtual key code definitions

Karabiner provides various virtual key code definitions.
You can use them without <vkchangeinputsourcedef> in private.xml.

An example

You can include external xml files by <include>.

private.xml
<?xml version="1.0"?>
<root>
  <include path="core.xml" />
</root>
core.xml
<?xml version="1.0"?>
<root>
  <item>
    <name>Swap Space and Tab</name>
    <identifier>private.swap_space_and_tab</identifier>
    <autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::TAB</autogen>
    <autogen>__KeyToKey__ KeyCode::TAB, KeyCode::SPACE</autogen>
  </item>
</root>

<include> with Dropbox

You can synchronize your private.xml by Dropbox or other file syncing service.

private.xml
<?xml version="1.0"?>
<root>
  <include path="{{ ENV_HOME }}/Dropbox/private/Karabiner/core.xml" />
</root>
Dropbox/private/Karabiner/core.xml
<?xml version="1.0"?>
<root>
  <item>
    <name>Dropbox Test!</name>
  </item>
</root>

<include> with <replacementdef>

<replacementdef> in <include> has a local scope. These <replacementdef> are effective only in included file.

private.xml
<?xml version="1.0"?>
<root>
  <!-- Swap Space and Escape -->
  <include path="core.xml">
    <replacementdef>
      <replacementname>KEY1</replacementname>
      <replacementvalue>KeyCode::SPACE</replacementvalue>
    </replacementdef>
    <replacementdef>
      <replacementname>KEY2</replacementname>
      <replacementvalue>KeyCode::ESCAPE</replacementvalue>
    </replacementdef>
  </include>

  <!-- Swap Tab and Return -->
  <include path="core.xml">
    <replacementdef>
      <replacementname>KEY1</replacementname>
      <replacementvalue>KeyCode::TAB</replacementvalue>
    </replacementdef>
    <replacementdef>
      <replacementname>KEY2</replacementname>
      <replacementvalue>KeyCode::RETURN</replacementvalue>
    </replacementdef>
  </include>
</root>
core.xml
<?xml version="1.0"?>
<root>
  <item>
    <name>Swap {{ KEY1 }} and {{ KEY2 }}</name>
    <identifier>private.swap_{{ KEY1 }}_{{ KEY2 }}</identifier>
    <autogen>__KeyToKey__ {{ KEY1 }}, {{ KEY2 }}</autogen>
    <autogen>__KeyToKey__ {{ KEY2 }}, {{ KEY1 }}</autogen>
  </item>
</root>

An example

You can define replacement by <replacementdef>.

<?xml version="1.0"?>
<root>
  <replacementdef>
    <replacementname>MY_IGNORE_APPS</replacementname>
    <replacementvalue>SAFARI, FIREFOX, FINDER</replacementvalue>
  </replacementdef>

  <item>
    <name>Change space to tab except in my ignore apps.</name>
    <identifier>private.space_to_tab_except_my_ignore_apps</identifier>
    <not>{{ MY_IGNORE_APPS }}</not>
    <autogen>__KeyToKey__ KeyCode::SPACE, KeyCode::TAB</autogen>
  </item>
</root>

{{ <replacementname> }} is replaced by <replacementvalue>.

<not>{{ MY_IGNORE_APPS }}</not>

<!-- ↑ is replaced to ↓ -->

<not>SAFARI, FIREFOX, FINDER</not>

Global scope replacement

<replacementdef> written in private.xml has a global scope. It is effective for the entire XML.

When you wrote multiple <replacementdef> for one <replacementname>, only the first one is effective.

<?xml version="1.0"?>
<root>
  <replacementdef>
    <replacementname>MY_KEYCODE</replacementname>
    <replacementvalue>KeyCode::SPACE</replacementvalue>
  </replacementdef>

  <!-- This replacementdef of MY_KEYCODE is ignored -->
  <replacementdef>
    <replacementname>MY_KEYCODE</replacementname>
    <replacementvalue>KeyCode::TAB</replacementvalue>
  </replacementdef>

  <item>
    <name>{{ MY_KEYCODE }} is KeyCode::SPACE</name>
  </item>
</root>

Local scope replacement

You can define a local scope replacement by using <replacementdef> under <include>.
See <include> with <replacementdef> section.

Prepared replacement definitions

Karabiner provides various replacement definitions.
You can use them without <replacementdef> in private.xml.

You can also overwrite existing replacement definitions by private.xml.
An example of overwriting VI_H:

<?xml version="1.0"?>
<root>
  <replacementdef>
    <replacementname>VI_H</replacementname>
    <replacementvalue>KeyCode::J</replacementvalue>
  </replacementdef>
</root>

An example

You can define new KeyCode by <symbol_map>.

<?xml version="1.0"?>
<root>
  <symbol_map type="KeyCode" name="MY_LANGUAGE_KEY" value="0x32" />

  <item>
    <name>Change KeyCode::MY_LANGUAGE_KEY to tab.</name>
    <identifier>private.my_language_key_to_tab</identifier>
    <autogen>__KeyToKey__ KeyCode::MY_LANGUAGE_KEY, KeyCode::TAB</autogen>
  </item>
</root>

Specify a raw value

You can specify a raw value by using KeyCode::RawValue.

<?xml version="1.0"?>
<root>
  <item>
    <name>Change right option key to tab key</name>
    <identifier>private.right_option_key_to_tab_key</identifier>
    <!-- change right option key (0x3d) to tab key (0x30) -->
    <autogen>__KeyToKey__ KeyCode::RawValue::0x3d, KeyCode::RawValue::0x30</autogen>
  </item>
</root>

An example

You can define new virtual modifier by <modifierdef>.

Note: Added virtual modifiers are not shown in EventViewer.
<?xml version="1.0"?>
<root>
  <modifierdef>MY_HYPER</modifierdef>
  <modifierdef>MY_SUPER</modifierdef>

  <item>
    <name>My hyper and super key</name>
    <appendix>* Change the right shift key to my hyper key.</appendix>
    <appendix>* Change the right option key to my super key.</appendix>
    <appendix></appendix>
    <appendix>* Change hyper+a,s to 1,2.</appendix>
    <appendix>* Change super+a,s to brightness controls.</appendix>
    <identifier>private.hyper_super</identifier>

    <!-- Change the right shift key to my hyper key. -->
    <autogen>__KeyToKey__ KeyCode::SHIFT_R, KeyCode::VK_MODIFIER_MY_HYPER</autogen>
    <!-- Change the right option key to my super key. -->
    <autogen>__KeyToKey__ KeyCode::OPTION_R, KeyCode::VK_MODIFIER_MY_SUPER</autogen>

    <!-- hyper key settings -->
    <autogen>
      __KeyToKey__
      KeyCode::A, ModifierFlag::MY_HYPER,
      KeyCode::KEY_1,
    </autogen>
    <autogen>
      __KeyToKey__
      KeyCode::S, ModifierFlag::MY_HYPER,
      KeyCode::KEY_2,
    </autogen>

    <!-- super key settings -->
    <autogen>
      __KeyToKey__
      KeyCode::A, ModifierFlag::MY_SUPER,
      ConsumerKeyCode::BRIGHTNESS_DOWN,
    </autogen>
    <autogen>
      __KeyToKey__
      KeyCode::S, ModifierFlag::MY_SUPER,
      ConsumerKeyCode::BRIGHTNESS_UP,
    </autogen>

  </item>
</root>

Added KeyCode and ModifierFlag by <modifierdef>

<modifierdef> adds some KeyCode and ModifierFlag.
For generic usage, ModifierFlag::MY_HYPER and KeyCode::VK_MODIFIER_MY_HYPER are important.
(Replace MY_HYPER with your own modifier's name.)

These are full KeyCode and ModifierFlag that added by <modifierdef>MY_HYPER</modifierdef>:

KeyCode or ModifierFlag Description
ModifierFlag::MY_HYPER ModifierFlag for new modifier.
KeyCode::VK_MODIFIER_MY_HYPER KeyCode for new modifier.
KeyCode::VK_LOCK_MY_HYPER KeyCode to toggle new modifier lock.
KeyCode::VK_LOCK_MY_HYPER_FORCE_ON KeyCode to turn new modifier lock on.
KeyCode::VK_LOCK_MY_HYPER_FORCE_OFF KeyCode to turn new modifier lock off.
KeyCode::VK_NEGATIVE_LOCK_MY_HYPER KeyCode to toggle new modifier negative lock.
KeyCode::VK_NEGATIVE_LOCK_MY_HYPER_FORCE_ON KeyCode to turn new modifier negative lock on.
KeyCode::VK_NEGATIVE_LOCK_MY_HYPER_FORCE_OFF KeyCode to turn new modifier negative lock off.
KeyCode::VK_STICKY_MY_HYPER KeyCode to toggle new modifier sticky state.
KeyCode::VK_STICKY_MY_HYPER_FORCE_ON KeyCode to turn new modifier sticky state on.
KeyCode::VK_STICKY_MY_HYPER_FORCE_OFF KeyCode to turn new modifier sticky state off.

Attributes

Add notify="false" attribute to modifierdef if you want to hide an indicator of modifier locks and sticky for new modifier.

  <modifierdef notify="false">MY_HYPER2</modifierdef>

Without notify="false", Karabiner shows an indicator when your own modifier is locked.
lock indicator

Prepared virtual modifier definitions

Karabiner provides some prepared virtual modifier.
You can use them without <modifierdef> in private.xml.

Some prepared settings provides a point to expand their capabilities..
For example, Emacs Mode allows you to specify ignored apps.

You can expand them by using replacementdef.

Examples

Set Emacs Mode ignored apps to EMACS,TERMINAL,VI

<?xml version="1.0"?>
<root>
  <replacementdef>
    <replacementname>EMACS_MODE_IGNORE_APPS</replacementname>
    <replacementvalue>
      EMACS,
      TERMINAL,
      VI,
    </replacementvalue>
  </replacementdef>
</root>

The replacements are defined in replacementdef.xml.

  1. Get source code from repository.
  2. Prepared settings are defined in these files: Modify them.
  3. Install XML files. Execute these commands in Terminal.
     $ cd src/core/server/Resources
     $ make install
    
    (This commands ask your password in order to modify XML files in /Applications/Karabiner.app.)
  4. Then, reload XML files by "Reload XML" button on Preference.
Please send a pull request on GitHub when improvement is complete.