You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
input-remapper/readme/macros.md

264 lines
5.6 KiB
Markdown

# Macros
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.
3 years ago
Bear in mind that anti-cheat software might detect macros in games.
### 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)
> ```
### wheel
> Injects scroll wheel events
>
> ```c#
> wheel(direction: str, speed: int)
> ```
>
> Examples:
>
> ```c#
> mouse(up, 1)
> mouse(left, 2)
> ```
### event
3 years ago
> Writes an event. Examples for `type`, `code` and `value` can 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))`
>
3 years ago
> Their values are available for other injections/devices as well, so you can make them
> interact with each other. In other words, using `set` on a keyboard and `if_eq` with
> the previously used variable name on a mouse will work.
>
> ```c#
> set(variable: str, value: str | int)
> ```
>
> Examples:
>
> ```c#
> set(foo, 1)
> set(foo, "qux")
> ```
### if_eq
3 years ago
> 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
Multiple functions are chained using `.`.
Unlike other programming languages, `qux(bar())` would not run `bar` and then
`qux`. Instead, `cux` can decide to run `bar` during runtime depending on various
other factors. Like `repeat` is running its parameter multiple times.
Whitespaces, newlines and tabs don't have any meaning and are removed when the macro
gets compiled.
Similar to python, arguments can be either positional or keyword arguments.
`key(symbol=KEY_A)` is the same as `key(KEY_A)`.
Using `$` resolves a variable during runtime. For example `set(a, $1)` and
`if_eq($a, 1, key(KEY_A), key(KEY_B))`.
## Combinations spanning multiple devices
3 years ago
For regular combinations on only single devices it is not required to
3 years ago
configure macros. See [readme/usage.md](usage.md#combinations).
**Keyboard** `space` `set(foo, 1).h(space).set(foo, 0)`
**Mouse** `middle` `if_eq($foo, 1, h(a), h(BTN_MIDDLE))`
3 years ago
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.
3 years ago
**Explanation**
3 years ago
`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.
`set(foo, 1).set(foo, 0)` sets "foo" to 1 and then sets "foo" to 0.
`set` and `if_eq` work on shared memory, so all injections will see your
3 years ago
variables. Combine both to get a key that works like a normal key, but that also
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.