# How to Set Up Unicode Input with U+ Codes in the RIME Wanxiang Schema

> Learn to set up Unicode input with U+ codes in RIME Wanxiang schema. This guide explains how the Lua translator handles code points, ensuring valid UTF-8 characters.

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

---

**The Wanxiang RIME schema enables Unicode input by matching hexadecimal code points prefixed with "U" through a Lua translator that converts valid codes into UTF-8 characters while filtering out illegal surrogate ranges and values exceeding the Unicode maximum.**

The rime_wanxiang project provides a streamlined method for entering arbitrary Unicode characters using standard U+ notation directly within the RIME input framework. By leveraging a dedicated Lua translator, the schema converts hexadecimal values into displayable glyphs without requiring external character maps or copy-paste operations. This guide explains the exact configuration, validation logic, and practical usage based on the current source implementation in the amzxyz/rime_wanxiang repository.

## How Unicode Input Works

The input flow relies on three coordinated components in the RIME processing pipeline:

1.  **Pattern Recognition**: The **recognizer** defined in [`wanxiang.schema.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/wanxiang.schema.yaml) matches input against the regular expression `^U[a-f0-9]+`, tagging valid segments with the `unicode` tag for translation.
2.  **Lua Translation**: The **[`unicode.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/unicode.lua)** script extracts the hex string following the prefix, converts it to an integer, and validates it against Unicode constraints.
3.  **Candidate Generation**: Valid code points yield candidates with `utf8.char(code)` as the display text and the original code (e.g., `U62FC`) as a comment; invalid entries return candidates with explanatory error messages instead of characters.

The translator dynamically detects the trigger prefix from the recognizer pattern via `env.unicode_keyword`, which automatically extracts the second character of the regex. This design allows you to change the prefix without modifying the Lua source code.

## Configuration and Setup

### Default Configuration

The default [`wanxiang.schema.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/wanxiang.schema.yaml) already contains the necessary entries to enable Unicode input. The recognizer pattern is defined at lines 30-34:

```yaml
recognizer:
  patterns:
    unicode: "^U[a-f0-9]+"

```

The translator registration appears at lines 80-83:

```yaml
translators:
  - lua_translator@unicode

```

Place the [`lua/unicode.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/lua/unicode.lua) file in your RIME user profile's `lua/` directory. RIME automatically loads Lua modules referenced in the schema configuration upon deployment or schema switch.

### Customizing the Trigger Prefix

To change the prefix from "U" to another character (such as "V" or "X"), modify only the recognizer pattern in [`wanxiang.schema.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/wanxiang.schema.yaml):

```yaml
recognizer:
  patterns:
    unicode: "^X[a-f0-9]+"

```

The Lua translator reads the `env.unicode_keyword` variable to dynamically extract the new prefix from the pattern's second character, requiring no changes to [`lua/unicode.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/lua/unicode.lua).

## Usage Examples

### Basic Unicode Entry

Type the prefix followed by the hexadecimal code point to generate the corresponding character:

```text
U62fc   →  拼   (comment: U62FC)
U4E00   →  一   (comment: U4E00)
U263A   →  ☺   (comment: U263A)

```

Input is case-insensitive for hex digits; both `U4e2d` and `U4E2D` correctly produce the character "中".

### Quick-Pick Candidates for BMP Characters

For Basic Multilingual Plane (BMP) code points below `0x10000`, the translator in [`lua/unicode.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/lua/unicode.lua) automatically generates additional candidates showing the next 16 sequential characters:

```text
U4E00  →  一   (U4E00)
          丁   (U4E01)
          丂   (U4E02)
          ...

```

The algorithm automatically skips surrogate pair values in the range `0xD800-0xDFFF` when generating these suggestions.

### Handling Invalid Code Points

The translator implements strict validation logic in [`lua/unicode.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/lua/unicode.lua) (around lines 17-25) to prevent insertion of illegal Unicode:

-   **Out of range**: Code points exceeding `0x10FFFF` return a candidate with the comment "数值超限！"
-   **Surrogate range**: Values between `0xD800` and `0xDFFF` return "代理区字符无效！"

```text
U110000   →  数值超限！
UDEAD     →  代理区字符无效！

```

## Source File Reference

The Unicode input system spans two primary files in the repository:

**[`wanxiang.schema.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/wanxiang.schema.yaml)**  
This schema file contains the recognizer pattern at lines 30-34 that defines the input trigger regex, and the translator registration at lines 80-83 that loads `lua_translator@unicode` into the processing pipeline.

**[`lua/unicode.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/lua/unicode.lua)**  
This script implements the core conversion logic. It parses the hex input, validates against the maximum Unicode value of `0x10FFFF`, excludes surrogate pairs in the range `0xD800-0xDFFF`, and generates candidates using the `utf8.char()` function.

## Summary

-   The Wanxiang schema implements Unicode input through a coordinated regex recognizer and Lua translator pattern that accepts U+ hex codes.
-   The default trigger is the uppercase letter "U" followed by hex digits, though the prefix is configurable via the recognizer pattern alone.
-   The system enforces Unicode standards by rejecting values above `0x10FFFF` and blocking surrogate range code points from `0xD800` to `0xDFFF`.
-   BMP code points automatically display 16 subsequent characters as "quick-pick" candidates, streamlining access to related symbols.
-   All configuration resides in [`wanxiang.schema.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/wanxiang.schema.yaml) while the conversion logic is handled by [`lua/unicode.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/lua/unicode.lua).

## Frequently Asked Questions

### What is the default prefix for Unicode input in Wanxiang?

The default prefix is the uppercase letter **U**. The recognizer pattern `^U[a-f0-9]+` in [`wanxiang.schema.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/wanxiang.schema.yaml) triggers the Lua translator whenever you type U followed by one or more hexadecimal characters (0-9, a-f).

### Can I use lowercase letters for the hex code?

Yes. The [`unicode.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/unicode.lua) translator accepts both uppercase and lowercase hexadecimal digits. Typing `U4e2d` or `U4E2D` will both correctly output the Chinese character "中" because the conversion function handles case insensitivity.

### Why does the candidate list show multiple characters when I enter a BMP code point?

For code points below `0x10000`, the translator automatically generates candidates for the requested code plus the next 16 sequential Unicode values, skipping any surrogate pair ranges. This provides quick access to related characters without requiring you to retype the prefix for each adjacent symbol.

### How do I disable the quick-pick feature for BMP characters?

To disable the automatic suggestion of subsequent code points, edit [`lua/unicode.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/lua/unicode.lua) and locate the candidate generation loop for BMP values (typically near the section handling code points less than `0x10000`). Remove or comment out the loop that appends the additional 16 candidates to the result list, keeping only the exact match candidate.