2021-04-25 17:28:02 +00:00
|
|
|
# Macros
|
|
|
|
|
2021-10-01 22:55:10 +00:00
|
|
|
key-mapper comes with an optional custom macro language with support for cross-device
|
|
|
|
variables, conditions and named parameters.
|
|
|
|
|
|
|
|
Syntax errors are shown in the UI on save. Each `k` function adds a short delay of 10ms
|
|
|
|
between key-down, key-up and at the end. See [usage.md](usage.md#configuration-files)
|
|
|
|
for more info.
|
2021-04-25 17:28:48 +00:00
|
|
|
|
|
|
|
Bear in mind that anti-cheat software might detect macros in games.
|
|
|
|
|
2021-10-01 22:55:10 +00:00
|
|
|
### key
|
|
|
|
|
|
|
|
> Acts like a pressed key. All names that are available in regular mappings can be used
|
|
|
|
> here.
|
|
|
|
>
|
|
|
|
> You don't have to use quotes around the symbol constants.
|
|
|
|
>
|
|
|
|
> Shorthand: `k`
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> key(symbol: str)
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
> Examples:
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> key(symbol=KEY_A)
|
|
|
|
> key(b).key(space)
|
|
|
|
> ```
|
|
|
|
|
|
|
|
### wait
|
|
|
|
|
|
|
|
> Waits in milliseconds before continuing the macro
|
|
|
|
>
|
|
|
|
> Shorthand: `w`
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> wait(time: int)
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
> Examples:
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> wait(time=100)
|
|
|
|
> wait(500)
|
|
|
|
> ```
|
|
|
|
|
|
|
|
### repeat
|
|
|
|
|
|
|
|
> Repeats the execution of the second parameter a few times
|
|
|
|
>
|
|
|
|
> Shorthand: `r`
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> repeat(repeats: int, macro: Macro)
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
> Examples:
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> repeat(1, key(KEY_A))
|
|
|
|
> repeat(repeats=2, key(space))
|
|
|
|
> ```
|
|
|
|
|
|
|
|
### modify
|
|
|
|
|
|
|
|
> Holds a modifier while executing the second parameter
|
|
|
|
>
|
|
|
|
> Shorthand: `m`
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> modify(modifier: str, macro: Macro)
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
> Examples:
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> modify(Control_L, k(a).k(x))
|
|
|
|
> ```
|
|
|
|
|
|
|
|
### hold
|
|
|
|
|
|
|
|
> Executes the child macro repeatedly as long as the key is pressed down.
|
|
|
|
>
|
|
|
|
> If a symbol string like KEY_A is provided, it will hold down that symbol as
|
|
|
|
> long as the key is pressed down.
|
|
|
|
>
|
|
|
|
> Shorthand: `h`
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> hold(macro: Macro | str)
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
> Examples:
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> hold(KEY_A)
|
|
|
|
> hold(key(space))
|
|
|
|
> ```
|
|
|
|
|
|
|
|
### mouse
|
|
|
|
|
|
|
|
> Moves the mouse cursor
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> mouse(direction: str, speed: int)
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
> Examples:
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> mouse(up, 1)
|
|
|
|
> mouse(left, 2)
|
|
|
|
> ```
|
2021-04-25 17:28:02 +00:00
|
|
|
|
2021-10-01 22:55:10 +00:00
|
|
|
### wheel
|
|
|
|
|
|
|
|
> Injects scroll wheel events
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> wheel(direction: str, speed: int)
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
> Examples:
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> mouse(up, 1)
|
|
|
|
> mouse(left, 2)
|
|
|
|
> ```
|
|
|
|
|
|
|
|
### event
|
|
|
|
|
|
|
|
> Writes an event. type, code and value of existing keys be found via the `sudo evtest`
|
|
|
|
> command
|
|
|
|
>
|
|
|
|
> Shorthand: `e`
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> event(type: str | int, code: str | int, value: int)
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
> Examples:
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> event(EV_KEY, KEY_A, 1)
|
|
|
|
> event(2, 8, 1)
|
|
|
|
> ```
|
|
|
|
|
|
|
|
### set
|
|
|
|
|
|
|
|
> Set a variable to a value. This variable and its value is available in all injection
|
|
|
|
> processes.
|
|
|
|
>
|
|
|
|
> Variables can be used in function arguments by adding a `$` in front of their name:
|
|
|
|
> `repeat($foo, key(KEY_A))`
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> set(variable: str, value: str | int)
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
> Examples:
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> set(foo, 1)
|
|
|
|
> set(foo, "qux")
|
|
|
|
> ```
|
|
|
|
|
|
|
|
### if_eq
|
|
|
|
|
|
|
|
> Compare two values and run different macros depending on the outcome
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> if_eq(value_1: str | int, value_2: str | int, then: Macro | None, else: Macro | None)
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
> Examples:
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> set(a, 1).if_eq($a, 1, key(KEY_A), key(KEY_B))
|
|
|
|
> set(a, 1).set(b, 1).if_eq($a, $b, else=key(KEY_B).key(KEY_C))
|
|
|
|
> set(a, "foo").if_eq("foo", $a, key(KEY_A))
|
|
|
|
> ```
|
|
|
|
|
|
|
|
### if_tap
|
|
|
|
|
|
|
|
> If the key is tapped quickly, run the `then` macro, otherwise the
|
|
|
|
> second. The third param is the optional time in milliseconds and defaults to
|
|
|
|
> 300ms
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> if_tap(then: Macro | None, else: Macro | None, timeout: int)
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
> Examples:
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> if_tap(key(KEY_A), key(KEY_B), timeout=500)
|
|
|
|
> if_tap(then=key(KEY_A), else=key(KEY_B))
|
|
|
|
> ```
|
|
|
|
|
|
|
|
### if_single
|
|
|
|
|
|
|
|
> If the key that is mapped to the macro is pressed and released, run the `then` macro.
|
|
|
|
>
|
|
|
|
> If another key is pressed while the triggering key is held down, run the `else` macro.
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> if_single(then: Macro | None, else: Macro | None)
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
> Examples:
|
|
|
|
>
|
|
|
|
> ```c#
|
|
|
|
> if_single(key(KEY_A), key(KEY_B))
|
|
|
|
> if_single(then=key(KEY_A), else=key(KEY_B))
|
|
|
|
> ```
|
|
|
|
|
|
|
|
## Syntax
|
2021-04-25 17:28:02 +00:00
|
|
|
|
|
|
|
Multiple functions are chained using `.`.
|
|
|
|
|
|
|
|
Unlike other programming languages, `qux(bar())` would not run `bar` and then
|
2021-10-01 22:55:10 +00:00
|
|
|
`qux`. Instead, `cux` can decide to run `bar` during runtime depending on various
|
|
|
|
other factors. Like `repeat` is running its parameter multiple times.
|
2021-04-25 17:28:02 +00:00
|
|
|
|
2021-10-01 22:55:10 +00:00
|
|
|
Whitespaces, newlines and tabs don't have any meaning and are removed when the macro
|
|
|
|
gets compiled.
|
2021-04-25 17:28:02 +00:00
|
|
|
|
2021-10-01 22:55:10 +00:00
|
|
|
Similar to python, arguments can be either positional or keyword arguments.
|
|
|
|
`key(symbol=KEY_A)` is the same as `key(KEY_A)`.
|
2021-04-25 17:28:02 +00:00
|
|
|
|
2021-10-01 22:55:10 +00:00
|
|
|
Using `$` resolves a variable during runtime. For example `set(a, $1)` and
|
|
|
|
`if_eq($a, 1, key(KEY_A), key(KEY_B))`.
|
2021-04-25 17:28:02 +00:00
|
|
|
|
|
|
|
## Combinations spanning multiple devices
|
|
|
|
|
2021-04-25 17:28:48 +00:00
|
|
|
For regular combinations on only single devices it is not required to
|
2021-07-25 08:36:00 +00:00
|
|
|
configure macros. See [readme/usage.md](usage.md#combinations).
|
2021-04-25 17:28:02 +00:00
|
|
|
|
2021-10-01 22:55:10 +00:00
|
|
|
**Keyboard** `space` `set(foo, 1).h(space).set(foo, 0)`
|
2021-04-25 17:28:02 +00:00
|
|
|
|
2021-10-01 22:55:10 +00:00
|
|
|
**Mouse** `middle` `if_eq($foo, 1, h(a), h(BTN_MIDDLE))`
|
2021-04-25 17:28:02 +00:00
|
|
|
|
2021-04-25 17:28:48 +00:00
|
|
|
Apply both presets. If you press space on your keyboard, it will write a
|
|
|
|
space exactly like it used to. If you hold down space and press the middle
|
|
|
|
button of your mouse, it will write "a" instead. If you just press the
|
|
|
|
middle button of your mouse it behaves like a regular middle mouse button.
|
2021-04-25 17:28:02 +00:00
|
|
|
|
2021-04-25 17:28:48 +00:00
|
|
|
**Explanation**
|
2021-04-25 17:28:02 +00:00
|
|
|
|
2021-04-25 17:28:48 +00:00
|
|
|
`h(space)` makes your key work exactly like if it was mapped to "space".
|
|
|
|
It will inject a key-down event if you press it, does nothing as long you
|
|
|
|
hold your key down, and injects a key-up event after releasing.
|
2021-04-25 17:28:02 +00:00
|
|
|
`set(foo, 1).set(foo, 0)` sets "foo" to 1 and then sets "foo" to 0.
|
2021-10-01 22:55:10 +00:00
|
|
|
`set` and `if_eq` work on shared memory, so all injections will see your
|
2021-04-25 17:28:48 +00:00
|
|
|
variables. Combine both to get a key that works like a normal key, but that also
|
2021-10-01 22:55:10 +00:00
|
|
|
works as a modifier for other keys of other devices. `ifeq($foo, 1, ..., ...)`
|
|
|
|
runs the first param if foo is 1, or the second one if foo is not 1.
|