SkillAgentSearch skills...

Keymapper

A cross-platform context-aware key remapper.

Install / Use

/learn @houmain/Keymapper

README

keymapper

<p> <a href="https://github.com/houmain/keymapper/actions/workflows/build.yml"> <img alt="Build" src="https://github.com/houmain/keymapper/actions/workflows/build.yml/badge.svg"/></a> <a href="https://github.com/houmain/keymapper/issues"> <img alt="Issues" src="https://img.shields.io/github/issues-raw/houmain/keymapper.svg"/></a>

<a href="#configuration">Configuration</a> | <a href="#example-configuration">Example</a> | <a href="#functional-principle">Functional principle</a> | <a href="#keymapperctl">keymapperctl</a> | <a href="#installation">Installation</a> | <a href="#building">Building</a> | <a href="https://github.com/houmain/keymapper/releases">Changelog</a>

</p>

A cross-platform context-aware key remapper. It allows to:

  • Redefine your keyboard layout and shortcuts systemwide or per application.
  • Manage all your keyboard shortcuts in a single configuration file.
  • Change shortcuts for similar actions in different applications at once.
  • Share configuration files between multiple systems (GNU/Linux, Windows, MacOS, FreeBSD).
  • Specify input and output as characters instead of the keys required to type them.
  • Bind keyboard shortcuts to launch applications.
  • Control the state from external applications using keymapperctl.
  • Use mouse buttons and wheel in your mappings.

Configuration

Configuration files are easily written by hand and mostly consist of lines with input expressions and corresponding output expressions separated by >>:

# comments start with # and continue until the end of a line
CapsLock >> Backspace
Z >> Y
Y >> Z
Control{Q} >> Alt{F4}

Unless overridden using the command line argument -c, the configuration is read from keymapper.conf, which is looked for in the common places:

  • on all systems in $XDG_CONFIG_HOME and $HOME/.config,
  • on Linux, MacOS and FreeBSD also in /etc,
  • on Windows also in the user's profile, AppData\Local and AppData\Roaming folders,

each with an optional keymapper subdirectory and finally in the working directory.

The command line argument -u causes the configuration to be automatically reloaded whenever the configuration file changes.

:warning: In case of emergency: You can always press the special key combination <kbd>Shift</kbd>+<kbd>Escape</kbd>+<kbd>K</kbd> to terminate keymapperd.

Key names

The keys are named after their scan codes and are not affected by the present keyboard layout. The names have been chosen to match on what the web browsers have agreed upon, so this handy website can be used to get a key's name. For convenience the letter and digits keys are also named A to Z and 0 to 9. The logical keys Shift, Control, Alt and Meta are also defined (each matches the left and right modifier keys). There are also virtual keys for state switching and an Any key.

The mouse buttons are named ButtonLeft, ButtonRight, ButtonMiddle, ButtonBack and ButtonForward, the wheel is named WheelUp, WheelDown, WheelLeft and WheelRight.

It is also possible to directly provide the scan code instead of the key name in decimal or hex notation (e.g. 159, 0x9F).

:warning: Beware that the configuration file is case sensitive.

Input expressions

Input expressions consist of one or more key names separated by spaces or parenthesis, which give them different meaning:

  • A B means that keys have to be pressed successively (released in any order).
  • (A B) means that keys have to be pressed simultaneously in any order.
  • A{B} means that a key has to be held while another is pressed.
  • Groups and modifiers can also be nested like A{B{C}} or (A B){C}.
  • !A means that a key must not be pressed. When an expression ends with !A, it triggers when the key is released.
  • "..." string literals match when the enclosed characters are typed.
  • With an initial ? the mapping gets skipped as long as it only partially matches.

Output expressions

The output expression format is analogous to the input expression format:

  • A B means that keys are pressed successively.
  • (A B) means that both keys are pressed simultaneously.
  • A{B} means that a key is held while another is pressed.
  • !A means that the (potentially pressed) key should be released before the rest of the expression is applied.
  • ^ splits the output in two parts, one which is applied when the input key is pressed and one when the key is released.
  • "..." string literals allow to specify characters to type.
  • $() can be used for launching applications.
  • An empty expression can be used to suppress any output.

Order of mappings

Mappings are applied in consecutive order until a match is found, therefore their order is of importance. While the following outputs A as soon as Meta is pressed:

Meta    >> A
Meta{X} >> B

The other way round, nothing is output when Meta is pressed alone because depending on whether an X follows, either B or A is output:

Meta{X} >> B
Meta    >> A

:warning: You may want to add a @forward-modifiers directive to your configuration, which ensures that the common mouse-modifiers are never held back:

@forward-modifiers Shift Control Alt

For a detailed description of how the mapping is applied, see the Functional principle section.

Context awareness

Context blocks allow to enable mappings only in specific contexts. A context can be defined by system, the focused window title, window class, process path or the input device/device-id an event originates from.
A block continues until the next block (respectively the end of the file). The block which applies in all contexts can be reopened using default. e.g.:

[default]

[title = "Visual Studio"]

[system = "Linux", class != "qtcreator"] # '!=' inverses a condition

[device = "Some Device Name"] # consecutive blocks share mappings
[device = "Some Other Device"]

[system = "Windows" path = "notepad.exe"] # comma separator is optional

:warning: The device/device-id filters on Windows require the installation of a virtual device driver. The process path may not be available on Wayland and for processes with higher privileges. The window title is not available on MacOS.

The values of a context can be easily obtained using the Next Key Info function of the tray icon or keymapperctl.

Class and device filters match contexts with the exact same string, others match contexts containing the string. For finer control regular expressions can be used. These have to be delimited with slashes. Optionally i can be appended to make the comparison case insensitive:

[title = /Visual Studio Code|Code OSS/i]

Additionally a modifier filter allows to activate blocks depending on the state of one or more keys:

# active when Virtual1 is down and Virtual2 is not
[modifier = "Virtual1 !Virtual2"]

Finally blocks can be activated depending on whether two strings match. Macros may be used for generating the strings. e.g.:

# active when environment variable has some specific value
[getenv["HOSTNAME"] = "LaptopMum"]

Abstract commands

To simplify mapping of one input expression to different output expressions, it can be mapped to an abstract command first. The command name can be chosen arbitrarily but must not be a key name. The configuration is case sensitive and all key names start with a capital letter, so it is advisable to begin command names with a lowercase letter:

Control{B} >> build

Subsequently this command can be mapped to one output expression per context. The last active mapping overrides the previous ones:

build >> Control{B}

[title="Visual Studio"]
build >> (Shift Control){B}

Multiple stages

By inserting [stage] a configuration can be split into stages, which are evaluated separately. The output of a stage is the input of the following stage, where it can be mapped further:

# adjust keyboard layout
Z >> Y
Y >> Z

# map keys output by previous stage
[stage]
Control{Z} >> undo

Output on key release

When an output expression contains ^, it is only applied up to this point, when the input key is pressed. The part after the ^ is not applied until the input is released. Both parts can be empty:

# type "cmd" after the Windows run dialog appeared
Meta{C} >> Meta{R} ^ "cmd" Enter

# prevent key repeat
A >> B^

# output B when A is released
A >> ^B

Virtual keys

Virtual0 to Virtual255 are virtual keys, which can be used as state switches. They are toggled when used in output expressions:

# toggle Virtual1 whenever ScrollLock is pressed
ScrollLock >> Virtual1

# release Virtual1 when Escape is pressed
Escape >> !Virtual1

They can be used as modifiers in input expressions:

# map A to B when Virtual1 is down
Virtual1{A} >> B

# map E to F when Virtual1 is NOT down
!Virtual1 E >> F

# keep G held as long as Virtual1 is down
Virtual1 >> G

# output H when Virtual1 is released
!Virtual1 >> H

Toggling virtual keys can also have immediate effects. Using them as modifiers is toggling them twice:

# toggle Virtual1 before and after pressing B
# this effectively maps D to A B C
Virtual1 >> A ^ C
D >> Virtual1{B}

# {} may also be empty. This maps C to A B
Virtual2 >> B
Virtual1 >> A Virtual2{}
C >> Virtual1{}

ContextActive exists separately for each cont

View on GitHub
GitHub Stars1.1k
CategoryDevelopment
Updated7h ago
Forks38

Languages

C++

Security Score

100/100

Audited on Apr 5, 2026

No findings