Behavior
The [behavior] section contains configuration for how different keyboard actions should behave:
Tri Layer
Tri-layer enables a third layer (often called adjust) automatically when two other layers (upper and lower) are both active.
You can enable Tri-Layer by specifying the upper, lower and adjust layers in the tri_layer sub-table:
In this example, when both layers 1 (upper) and 2 (lower) are active, layer 3 (adjust) will also be enabled.
Note that "#layer_name" could also be used in place of layer numbers.
One Shot
The one_shot sub-table configures one-shot modifiers or one-shot layers (OSM/OSL). Use timeout to specify how long the modifier/layer remains active. The value is a string suffixed with s or ms (default: 1s).
Combo
In the combo sub-table, you can configure the keyboard's combo key functionality. Combo allows you to define a group of keys that, when pressed simultaneously, will trigger a specific output action.
Combo configuration includes the following parameters:
timeout: Defines the maximum time window for pressing all combo keys. If the time exceeds this, the combo key will not be triggered. The format is a string, which can be milliseconds (e.g. "200ms") or seconds (e.g. "1s").combos: An array containing all defined combos. Each combo configuration is an object containing the following attributes:actions: An array of strings defining the keys that need to be pressed simultaneously to trigger the combo action.output: A string defining the output action to be triggered when all keys inactionsare pressed simultaneously.layer: An optional parameter, a number, specifying which layer the combo is valid on. If not specified, the combo is valid on all layers.
Here is an example of combo configuration:
Macro
In the macro sub-table, you can configure the keyboard's macro functionality. Macros are explained in more detail in the keyboard macros page.
Macro operations are defined with an operation and a keycode, duration or text field depending on the operation. Available operations are:
Morse (and TapDance)
In the morse sub-table, you can configure the keyboard's morse functionality. Morse is a superset of the well-known tap dance, enabling you to assign different actions to various combinations of taps and holds performed within a specific time window.
Morse keys are defined as a list under the [behavior.morse] section:
RMK provides three methods for defining a Morse key.
Define a morse key
1. Vial-style Tap Dance
This method is fully compatible with Vial's Tap Dance, it defines four specific actions:
tap: The action to be triggered on the first tap. This is the default action when the key is tapped once.hold: The action to be triggered when the key is held down (not tapped) beyond the tapping term.hold_after_tap: The action to be triggered when the key is held down after being tapped once.double_tap: The action to be triggered when the key is tapped twice within the tapping term.
Example:
2. Tap and Hold Arrays
This is an extended version of tap dance. It allows you to define sequences of actions for multiple taps and for holds that occur after a specific number of taps.
tap_actions: An array of actions triggered by sequential taps. Each tap within the tapping term increments the tap count and triggers the corresponding action from thetap_actionsarray. For example,tap_actions = ["F1", "F2", "F3"]means a single tap triggers "F1", double tap triggers "F2", triple tap triggers "F3", and so on. If the tap count exceeds the length of the array, the last action is used.hold_actions: An array of actions triggered when the key is held after a certain number of taps. When a key is held after multiple taps, the corresponding action from thehold_actionsarray is triggered. For example,hold_actions = ["MO(1)", "MO(2)", "MO(3)"]means holding after one tap triggers "MO(1)", holding after two taps triggers "MO(2)", and so on.
Example:
3. Full Morse Patterns
This is the most powerful method, allowing you to define actions based on Morse code-like patterns of taps and holds. This lets you assign a large number of actions to a single key
morse_actions: A list of pattern-to-action mappings. The pattern is a tap/hold sequence, a tap is represented by a.or0, a hold is represented by a_,-or1. For example, the morse pattern ofCcan be described like this:"-.-."or"_._."or"1010". The maximum length of the pattern is 15.
Example:
The three definition methods are mutually exclusive. For any single Morse key definition, you must choose only one of the following approaches:
- Full Morse:
morse_actions - Tap and Hold Arrays:
tap_actionsand/orhold_actions - Vial-style:
tap,hold,hold_after_tap,double_tap.
Mixing fields from different methods in the same definition is not allowed.
Profile
The profile of a morse key contains all tunable configurations of this morse key, such as behavior mode, timing configurations, etc.
A profile contains the following fields:
-
enable_flow_tap: Enables HRM (Home Row Mod) mode. When enabled, theprior_idle_timesetting becomes functional. Defaults tofalse. -
prior_idle_time: If the previous non-modifier key is released within this period before pressing the current tap-hold key, the tap action for the tap-hold behavior will be triggered. This parameter is effective only when enable_flow_tap is set totrue. Defaults to 120ms. -
unilateral_tap: (Experimental) Enables unilateral tap mode. When enabled, tap action will be triggered when a key from "same" hand is pressed. In current experimental version, the "same" hand is calculated using the<hand>, which can be given inmatrix_map. This option is recommended to set to true whenenable_flow_tapis set to true. -
The morse mode, which can be set by enabling one of these:
permissive_hold: Enables permissive hold mode. When enabled, hold action will be triggered when a key is pressed and released during tap-hold decision. This option is recommended to set to true whenenable_flow_tapis set to true.hold_on_other_press: Enables hold-on-other-key-press mode. When enabled, hold action will be triggered immediately when any other non-tap-hold key is pressed while a tap-hold key is being held. This provides faster modifier activation without waiting for the timeout. Defaults tofalse.normal_mode: this is the default mode, when nor thepermissive_holdnor thehold_on_other_pressis set.
-
hold_timeout: Defines the duration a tap-hold key must be pressed to determine hold behavior. If tap-hold key is released within this time, the key is recognized as a "tap". Holding it beyond this duration triggers the "hold" action. Defaults to 250ms. -
gap_timeout: Defines the duration a tap-hold key must be released to terminate a morse sequence. Defaults to 250ms. Note that only morse and tap-dance needs this setting, simple tap-hold does not.
Default profile for Morse/TapDance/TapHold
In the [behavior.morse] sub-table you can configure the default profile. If there's no explicit profile applied to a morse key, default profile will be used.
The following are some examples for default profile setting:
Per-key profiles for Morse, TapDance, Tap Hold fine tuning
In the morse.profiles sub-table you can define individual key profiles. Each profile has an associated name, which can be referred
- from the layout.matrix_map (the name is case sensitive), to override the defaults in certain key positions
- from the tap hold keys in the key map if the third optional parameter is filled:
TH(key-tap, key-hold, <profile_name>),MT(key, modifier, <profile_name>),LT(n, key, <profile_name>)
- the Morse keys may also have their per key profile overrides (which is stronger than the positional override) by setting the
profilefield.
The following examples are the typical default configurations:
Then you can reference the profile in layer config:
Global Configuration Limits
The following parameters in the [rmk] section control the resource allocation for the Morse feature:
morse_max_num: The maximum number of Morse key you can create. (Default: 8, Range: 0-256)max_patterns_per_key: The maximum number of individual patterns (like ".-") or actions that a single Morse key can contain. (Default: 8, Range: 4-65536)
Note that the Vial-style method (using tap, hold, hold_after_tap, double_tap) needs at least 4 patterns. If you create a key with a long tap_actions/hold_actions array or many morse_actions, you might need to increase max_patterns_per_key accordingly.
Please note that while the firmware can handle all Morse configurations, Vial can only recognize and edit the four basic Vial-style actions. These correspond to the patterns for single tap (.), hold (-), double tap (..), and hold-after-tap (.-). More complex patterns defined using morse_actions or extended tap_actions will not be visible or editable in Vial.
Comprehensive Example
Here is a comprehensive example of morse configuration:
Using Morse(Tap Dance) in Keymaps
You can use both Morse and TD to represent a morse key in your keymap, you can reference it by its index (starting from 0):
Fork
In the fork sub-table, you can configure the keyboard's state-based key fork functionality. Forks allow you to define a trigger key and condition-dependent possible replacement keys. When the trigger key is pressed, the condition is checked by the following rule: If any of the match_any states are active AND none of the match_none states are active, the trigger key will be replaced with positive_output; otherwise, it will be replaced with the negative_output. By default, the modifiers listed in match_any will be suppressed (even the one-shot modifiers) for the time the replacement key action is executed. However, with kept_modifiers some of them can be kept instead of automatic suppression.
Fork configuration includes the following parameters:
forks: An array containing all defined forks. Each fork configuration is an object containing the following attributes:trigger: Defines the triggering key.negative_output: A string defining the output action to be triggered when the conditions are not metpositive_output: A string defining the output action to be triggered when the conditions are metmatch_any: A string defining a combination of modifier keys, lock LEDs, mouse buttons (optional)match_none: A string defining a combination of modifier keys, lock LEDs, mouse buttons (optional)kept_modifiers: A string defining a combination of modifier keys, which should not be 'suppressed' from the keyboard state for the time the replacement action is executed (optional)bindable: Enables the evaluation of not yet triggered forks on the output of this fork to further manipulate the output. Advanced use cases can be solved using this option (optional)
For match_any, match_none the legal values are listed below (many values may be combined with "|"):
LShift,LCtrl,LAlt,LGui,RShift,RCtrl,RAlt,RGui(these include the effect of explicitly held and one-shot modifiers too)CapsLock,ScrollLock,NumLock,Compose,KanaMouseBtn1..MouseBtn8
Here is a sample of fork configuration with random examples:
Please note that the processing of forks happens after combos and before others, so the trigger key must be the one listed in your keymap (or combo output). For example if LT(2, Backspace) is in your keymap, then trigger = "Backspace" will NOT work, you should "replace" the full key and use trigger = "LT(2, Backspace)" instead, like in the example above. You may want to include F24 or similar dummy keys in your keymap, and use them as trigger for your pre-configured forks, such as Shift/CapsLock dependent macros to enter unicode characters of your language.
Vial does not support fork configuration yet.