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

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, 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:

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:

  • 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 contains an empty key_binder: section that serves as a placeholder for bindings. All official schemas, including wanxiang.schema.yaml, declare the processor in their engine/processors list to ensure it is active:

processors:
  - key_binder
  - lua_processor@*key_binder

Users typically override these settings in a custom file such as 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:

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" (时间):

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:

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:

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 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 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 under the key_binder/bindings section. Rime merges these settings with the base configuration found in 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →