> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monolex.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# IME and CJK Support

> Atomic-Term IME Integration and CJK Double-Width Guarantee from Monokinetics

# IME and CJK Support

Monolex provides first-class support for CJK (Chinese, Japanese, Korean) input through the atomic-term module and Monokinetics principles.

```
╔═══════════════════════════════════════════════════════════════════════════════╗
║  IME/CJK SUPPORT IN MONOLEX                                                   ║
╠═══════════════════════════════════════════════════════════════════════════════╣
║                                                                               ║
║   1. ATOMIC-TERM IME                                                          ║
║      Real-time input source detection via macOS Carbon API                    ║
║      Composition state handling for CJK input methods                         ║
║                                                                               ║
║   2. MONOKINETICS CJK GUARANTEE                                               ║
║      Every Asian character occupies exactly 2 cells                           ║
║      Enforced through VTE flags at the parser level                           ║
║                                                                               ║
╚═══════════════════════════════════════════════════════════════════════════════╝
```

***

## The CJK Problem in Terminals

```
┌───────────────────────────────────────────────────────────────────────────────┐
│  PROBLEM 1: INPUT (IME Composition)                                           │
├───────────────────────────────────────────────────────────────────────────────┤
│                                                                               │
│   User types: h -> a -> n (in Korean IME)                                     │
│                                                                               │
│   WITHOUT proper handling:                                                    │
│     Each keystroke sent immediately to PTY -> Garbage characters              │
│                                                                               │
│   WITH proper handling:                                                       │
│     Buffer until composition complete -> Only final text sent                 │
│                                                                               │
└───────────────────────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────────────────────┐
│  PROBLEM 2: DISPLAY (Character Width)                                         │
├───────────────────────────────────────────────────────────────────────────────┤
│                                                                               │
│   WITHOUT width guarantee:                                                    │
│     Different fonts = different widths -> ASCII art breaks                    │
│                                                                               │
│   WITH Monokinetics guarantee:                                                │
│     CJK = exactly 2 cells (always) -> Perfect alignment                       │
│                                                                               │
└───────────────────────────────────────────────────────────────────────────────┘
```

***

## Atomic-Term IME Architecture

```
╔═══════════════════════════════════════════════════════════════════════════════╗
║                       ATOMIC-TERM IME ARCHITECTURE                            ║
╠═══════════════════════════════════════════════════════════════════════════════╣
║                                                                               ║
║   macOS System                                                                ║
║   ┌───────────────────────────────────────────────────────────────────────┐   ║
║   │ Input Source: Dubeolsik (Korean)                                      │   ║
║   │ ID: com.apple.inputmethod.Korean.2SetKorean                           │   ║
║   └───────────────────────────────────────────────────────────────────────┘   ║
║                          │                                                    ║
║                          │ Carbon API (TIS)                                   ║
║                          v                                                    ║
║   ┌───────────────────────────────────────────────────────────────────────┐   ║
║   │                 Rust Backend (atomic_term_ime.rs)                     │   ║
║   │                                                                       │   ║
║   │   TISCopyCurrentKeyboardInputSource()                                 │   ║
║   │   TISGetInputSourceProperty(source, key)                              │   ║
║   │                                                                       │   ║
║   │   Result: InputSourceInfo {                                           │   ║
║   │     source_id, language, is_cjk, name, needs_composition              │   ║
║   │   }                                                                   │   ║
║   └───────────────────────────────────────────────────────────────────────┘   ║
║                          │                                                    ║
║                          │ Tauri IPC / Event                                  ║
║                          v                                                    ║
║   ┌───────────────────────────────────────────────────────────────────────┐   ║
║   │                 Frontend (ime-input-layer.ts)                         │   ║
║   │                                                                       │   ║
║   │   if (inputSource.is_cjk) handleCJKInput();                           │   ║
║   │   else writeToTerminal(event.key);                                    │   ║
║   └───────────────────────────────────────────────────────────────────────┘   ║
║                                                                               ║
╚═══════════════════════════════════════════════════════════════════════════════╝
```

***

## IME Composition States

```
╔═══════════════════════════════════════════════════════════════════════════════╗
║                         IME COMPOSITION STATES                                ║
╠═══════════════════════════════════════════════════════════════════════════════╣
║                                                                               ║
║   Korean Input Example:                                                       ║
║   ┌───────────────────────────────────────────────────────────────────────┐   ║
║   │   Keystroke   Composing Buffer   Committed   State                    │   ║
║   │   ─────────   ────────────────   ─────────   ─────────                │   ║
║   │   h (jamo)    (first jamo)       ""          composing                │   ║
║   │   a           (syllable)         ""          composing                │   ║
║   │   n           (syllable)         ""          composing                │   ║
║   │   Space       ""                 "han "      committed                │   ║
║   └───────────────────────────────────────────────────────────────────────┘   ║
║                                                                               ║
║   Japanese Input Example:                                                     ║
║   ┌───────────────────────────────────────────────────────────────────────┐   ║
║   │   n -> i -> h -> o -> n -> g -> o                                     │   ║
║   │   romaji -> hiragana -> conversion -> kanji -> commit                 │   ║
║   └───────────────────────────────────────────────────────────────────────┘   ║
║                                                                               ║
║   Frontend Handling:                                                          ║
║   ┌───────────────────────────────────────────────────────────────────────┐   ║
║   │   compositionstart  -> Start buffering                                │   ║
║   │   compositionupdate -> Update preview                                 │   ║
║   │   compositionend    -> Flush to PTY                                   │   ║
║   └───────────────────────────────────────────────────────────────────────┘   ║
║                                                                               ║
╚═══════════════════════════════════════════════════════════════════════════════╝
```

***

## Input Source Change Detection

```
╔═══════════════════════════════════════════════════════════════════════════════╗
║                    INPUT SOURCE CHANGE MONITORING                             ║
╠═══════════════════════════════════════════════════════════════════════════════╣
║                                                                               ║
║   Notification: "com.apple.Carbon.TISNotifySelectedKeyboardInputSourceChanged"║
║                                                                               ║
║   User Switching Methods:                                                     ║
║   ┌───────────────────────────────────────────────────────────────────────┐   ║
║   │ Cmd + Space   -> Switch to next input source                          │   ║
║   │ Caps Lock     -> English/Korean toggle (if configured)                │   ║
║   │ Globe Key     -> Input source selection popup                         │   ║
║   └───────────────────────────────────────────────────────────────────────┘   ║
║                                                                               ║
║   Flow: User switches -> macOS notifies -> Monolex callback -> Frontend       ║
║                                                                               ║
╚═══════════════════════════════════════════════════════════════════════════════╝
```

***

## CJK Detection Logic

```
┌───────────────────────────────────────────────────────────────────────────────┐
│                         CJK DETECTION LOGIC                                   │
├───────────────────────────────────────────────────────────────────────────────┤
│                                                                               │
│   By language code:                                                           │
│     "ko" │ "ja" │ "zh" │ "zh-Hans" │ "zh-Hant"                                │
│                                                                               │
│   Or by source ID keywords:                                                   │
│     "Korean" │ "Japanese" │ "Chinese" │ "Pinyin" │ "Hiragana" │ "Katakana"    │
│                                                                               │
└───────────────────────────────────────────────────────────────────────────────┘
```

***

## Monokinetics CJK Guarantee

```
╔═══════════════════════════════════════════════════════════════════════════════╗
║  MONOKINETICS TENET 1: CJK DOUBLE-WIDTH GUARANTEE                             ║
╠═══════════════════════════════════════════════════════════════════════════════╣
║                                                                               ║
║   "Every ASCII character is 1 cell wide.                                      ║
║    Every CJK character is exactly 2 cells wide.                               ║
║    Always. Predictably."                                                      ║
║                                                                               ║
║   ┌───┬───┬───┬───┬───┬───┬───────┬───────┐                                   ║
║   │ H │ e │ l │ l │ o │   │ CJK-1 │ CJK-2 │                                   ║
║   └───┴───┴───┴───┴───┴───┴───────┴───────┘                                   ║
║     1   1   1   1   1   1     2       2                                       ║
║                                                                               ║
╚═══════════════════════════════════════════════════════════════════════════════╝
```

***

## VTE Width Flags

```
┌───────────────────────────────────────────────────────────────────────────────┐
│  VTE WIDTH FLAGS                                                              │
├───────────────────────────────────────────────────────────────────────────────┤
│                                                                               │
│   Flag                         Meaning                    Width               │
│   ───────────────────────────  ─────────────────────────  ──────              │
│   WIDE_CHAR                    CJK/emoji (2 cols)         2                   │
│   WIDE_CHAR_SPACER             Trailing empty cell        0                   │
│   LEADING_WIDE_CHAR_SPACER     Leading empty cell         0                   │
│   (none)                       Normal ASCII/Latin         1                   │
│                                                                               │
│   Decision Tree:                                                              │
│   Cell -> WIDE_CHAR_SPACER? -> width=0 (skip)                                 │
│        -> WIDE_CHAR? -> width=2 (CJK)                                         │
│        -> else -> Unicode width lookup (usually 1)                            │
│                                                                               │
└───────────────────────────────────────────────────────────────────────────────┘
```

***

## Rendering Flow

```
┌───────────────────────────────────────────────────────────────────────────────┐
│  CJK RENDERING FLOW                                                           │
├───────────────────────────────────────────────────────────────────────────────┤
│                                                                               │
│   Input: CJK from IME -> VTE Parser -> Grid: [CJK│spacer│CJK│spacer]          │
│                                                                               │
│   xterm.js renders 4 columns (2 visible + 2 spacers)                          │
│                                                                               │
│   Screen: [CJK  ][CJK  ]  <── Each takes 2-cell space                         │
│                                                                               │
└───────────────────────────────────────────────────────────────────────────────┘
```

***

## Frontend Usage

```
┌───────────────────────────────────────────────────────────────────────────────┐
│  IME INTEGRATION PATTERNS                                                     │
├───────────────────────────────────────────────────────────────────────────────┤
│                                                                               │
│  PATTERN 1: Event-based (Recommended)                                         │
│  ─────────────────────────────────────                                        │
│  1. invoke('atomic_term_start_ime_watcher')                                   │
│                                                                               │
│  2. listen('atomic-term-ime-changed', callback)                               │
│          │                                                                    │
│          └──> On event:                                                       │
│                    info = event.payload                                       │
│                    info.is_cjk?                                               │
│                         │                                                     │
│                    YES ─┴──> enableCJKMode()                                  │
│                    NO  ────> disableCJKMode()                                 │
│                                                                               │
│  PATTERN 2: Polling                                                           │
│  ──────────────────────                                                       │
│  info = invoke('atomic_term_get_input_source')                                │
│  info.is_cjk? -> enableCJKMode() : disableCJKMode()                           │
│                                                                               │
└───────────────────────────────────────────────────────────────────────────────┘
```

***

## Available Commands

<CardGroup cols={2}>
  <Card title="atomic_term_get_input_source" icon="keyboard">
    Get current input source info
  </Card>

  <Card title="atomic_term_is_cjk_input" icon="globe">
    Quick CJK check (boolean)
  </Card>

  <Card title="atomic_term_start_ime_watcher" icon="eye">
    Start monitoring changes
  </Card>

  <Card title="atomic_term_stop_ime_watcher" icon="eye-slash">
    Stop monitoring
  </Card>
</CardGroup>

***

## Platform Support

| Platform | Support     | API                           |
| -------- | ----------- | ----------------------------- |
| macOS    | Full        | Carbon TIS API                |
| Windows  | Placeholder | GetKeyboardLayout() (planned) |
| Linux    | Placeholder | IBus/Fcitx D-Bus (planned)    |

***

## Summary

```
╔═══════════════════════════════════════════════════════════════════════════════╗
║  IME/CJK SUPPORT SUMMARY                                                      ║
╠═══════════════════════════════════════════════════════════════════════════════╣
║                                                                               ║
║   WHAT:   Complete CJK input and display support                              ║
║   HOW:    Carbon API + VTE flags + Composition events                         ║
║   WHY:    Perfect CJK experience for Korean/Japanese/Chinese users            ║
║                                                                               ║
║   Key Benefits:                                                               ║
║   * Real-time IME detection (no configuration needed)                         ║
║   * Proper composition handling (no garbage characters)                       ║
║   * Guaranteed double-width (no alignment issues)                             ║
║   * Works with all CJK input methods                                          ║
║                                                                               ║
╚═══════════════════════════════════════════════════════════════════════════════╝
```

<Tip>
  **Zero configuration required.** Monolex automatically detects your input method and handles CJK input correctly. Just switch to your preferred keyboard and start typing.
</Tip>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Monokinetics Philosophy" icon="atom" href="/philosophy/monokinetics">
    Learn about the design philosophy behind CJK guarantees.
  </Card>

  <Card title="Grid System" icon="table-cells" href="/terminal/grid-system">
    Understand how cells and widths are managed.
  </Card>
</CardGroup>
