# How to Configure the Key Binder for Custom Shortcuts in Rime Wanxiang

> Learn how to configure the key binder for custom shortcuts in Rime Wanxiang. Define match patterns, accept keys, and send sequences for personalized input.

- Repository: [amzxyz/rime_wanxiang](https://github.com/amzxyz/rime_wanxiang)
- Tags: how-to-guide
- Published: 2026-02-24

---

**To configure custom shortcuts in the wanxiang Rime input method, edit your custom YAML file to define bindings with match patterns, accept keys, and send sequences that the Lua processor evaluates for every keystroke.**

The **key_binder** in the `amzxyz/rime_wanxiang` repository provides a conditional key mapping system that allows you to trigger specific key sequences based on regular expression patterns. This extensible processor runs as a Lua module within the Rime engine, intercepting keystrokes to determine whether to redirect input according to user-defined rules.

## Understanding the Key Binder Architecture

### Processor Entry Point in lua/key_binder.lua

The core logic resides in [`lua/key_binder.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/lua/key_binder.lua), which registers a Lua processor invoked for every key event. According to the source code, the processor reads the current input buffer via `env.engine.context.input` and iterates over the `env.bindings` list to evaluate conditions:

```lua
for _, binding in ipairs(env.bindings) do
    if key_event:eq(binding.accept) and rime_api.regex_match(input, binding.match) then
        -- forward the send_sequence
    end
end

```

The processor specifically checks whether the engine is in an *abc* composition state before processing bindings, ensuring shortcuts only activate during appropriate input phases.

### Binding Structure and the parse() Function

Each binding consists of three critical fields parsed by the `parse()` function within [`lua/key_binder.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/lua/key_binder.lua):

- **match**: A Lua-style regular expression tested against the current input string
- **accept**: The physical key or combination that triggers the binding
- **send_sequence**: The key sequence sent to the engine when conditions are satisfied

### Configuration Sources and Schema Integration

The default configuration in [`default.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/default.yaml) contains an empty `key_binder:` section that serves as a placeholder for bindings. All official schemas, including [`wanxiang.schema.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/wanxiang.schema.yaml), declare the processor in their `engine/processors` list to ensure it is active:

```yaml
processors:
  - key_binder
  - lua_processor@*key_binder

```

Users typically override these settings in a custom file such as [`custom/wanxiang.custom.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/custom/wanxiang.custom.yaml), which Rime merges on schema load.

## How Conditional Shortcuts Work

When a key event arrives, the processor executes a four-step validation sequence:

1. Checks `env.redirecting` to prevent infinite loops from recursive binding triggers
2. Validates the engine is in *abc* composition state and retrieves the current input buffer
3. Tests both the key event against `binding.accept` and the input string against `binding.match` using `rime_api.regex_match`
4. If both conditions match, temporarily sets `env.redirecting = true`, processes each key in `send_sequence` via `env.engine:process_key(event)`, then returns `kAccepted` to consume the original keystroke

This architecture enables **context-aware shortcuts** that activate only when specific code patterns appear in the input buffer, while falling back to default behavior in other contexts.

## Key Binder Configuration Examples

### Global Shortcut Mapping

To map a key universally regardless of input context, use a catch-all regex in your custom YAML file:

```yaml
key_binder:
  bindings:
    - match: ".*"
      accept: "/"
      send_sequence: "Page_Down"

```

This configuration makes the forward-slash key behave like **Page_Down** across all input scenarios.

### Context-Aware Shortcuts with Regex

Restrict shortcuts to specific input patterns using anchored regex. This example triggers only when typing begins with "sj" (时间):

```yaml
key_binder:
  bindings:
    - match: "^sj.*"
      accept: "/"
      send_sequence: "Control+T"

```

Now the "/" key invokes the time tip **only** after typing "sj", preserving the original key behavior in other contexts.

### Multi-Key Sequence Mapping

The `send_sequence` field accepts comma-separated key combinations to simulate chorded input:

```yaml
key_binder:
  bindings:
    - match: ".*"
      accept: "Control+comma"
      send_sequence: "Control+K, Control+J"

```

The processor expands this single shortcut into sequential key events sent to the engine via `process_key()`.

### Modifying Default Tip Keys

The default tip key is defined via the `key_binder/tips_key` setting. To disable or reassign the default comma tip and free the key for custom bindings:

```yaml
key_binder/tips_key: "semicolon"

```

This change prevents conflicts with built-in tip functionality while allowing you to reassign the comma key through custom bindings.

## Summary

- The **key_binder** processor in [`lua/key_binder.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/lua/key_binder.lua) evaluates every keystroke against regex patterns and binding rules defined in your configuration
- Bindings require three fields: **match** (Lua regex), **accept** (trigger key), and **send_sequence** (output keys)
- Configuration files such as [`custom/wanxiang.custom.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/custom/wanxiang.custom.yaml) override defaults and define user-specific shortcuts that merge with the base schema
- The system supports both global shortcuts (`match: ".*"`) and context-aware triggers using pattern-specific regex like `^sj.*`
- Changes take effect after reloading the Rime schema or restarting the input method

## Frequently Asked Questions

### Where do I add my custom key bindings?

Define custom bindings in a personal scheme file such as [`custom/wanxiang.custom.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/custom/wanxiang.custom.yaml) under the `key_binder/bindings` section. Rime merges these settings with the base configuration found in [`default.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/default.yaml) when loading the schema.

### What regex syntax does the match field use?

The **match** field uses Lua-style regular expressions evaluated by `rime_api.regex_match` within the processor. You can use standard patterns like `.*` to match any input, `^prefix.*` to match strings starting with specific characters, or full patterns for complex conditional logic.

### Can I bind modifier key combinations like Ctrl+Shift+A?

Yes. The **accept** and **send_sequence** fields support modifier notation such as "Control+Shift+A", "Alt+comma", or "Shift+Return". Separate multiple keys in a sequence with commas for chained execution in `send_sequence`.

### Why isn't my key binding working after editing the file?

Rime requires a schema reload or input method restart to recognize changes to YAML configuration files. Additionally, verify that your regex pattern in the **match** field correctly captures the current input state, as the binding will not trigger if `rime_api.regex_match` returns false for the current buffer content.