Platform Rust License Version


Viet+

Vietnamese Input Method for Linux
Zero underline • Native X11 • Backspace-Replay sync • Built in Rust

## About Viet+ Viet+ is a modern Vietnamese input method for Linux that eliminates the **underline hell** common in other Vietnamese IMEs. Unlike traditional solutions that use pre-edit buffers with ugly underlines and duplicate text, Viet+ implements a **Direct Input** approach: - **No pre-edit buffer** — keystrokes are instantly converted to Unicode - **No underline** — clean, distraction-free typing - **No text duplication** — just pure Vietnamese - **Backspace-Replay sync** — engine state never desyncs from what's on screen --- ## Features | Feature | Description | |---------|-------------| | **Direct Input Engine** | No pre-edit buffer, no underline, no text duplication | | **Backspace-Replay** | Replays entire keystroke history through a fresh engine on every keypress — eliminates state desync | | **Telex & VNI** | Both input methods fully supported | | **Flexible Diacritic Placement** | Type modifiers/tone marks at end of syllable (e.g., `tranaf` -> `trần`) | | **Auto-Restore English** | Hit space/ESC to undo accidental Vietnamese conversion | | **ESC Undo** | Strip all tones from the current word instantly | | **Smart App Memory** | Remembers Vietnamese/English per application | | **Macro Expansion** | Custom shortcuts (e.g., `ko` -> `không`) | | **Focus Reset** | Automatically clears engine state on focus change between apps | | **Casing Preservation** | Syllable substitutions preserve your exact casing (e.g. `Saa` -> `Sả`, `SAA` -> `SẢ`) | | **CPU Priority** | Pins daemon to P-cores + nice(-10) for low-latency input | | **Zero Telemetry** | No keylogging, no network calls, fully FOSS | --- ## Why Viet+? Most Vietnamese input methods on Linux suffer from **underline hell** — pre-edit buffers that duplicate text, show ugly underlines, and break your flow. Viet+ takes a different approach: > **Direct Input** — keystrokes are instantly converted to Unicode. No pre-edit buffer. No underline. No text duplication. Just pure Vietnamese. The **Backspace-Replay** pattern keeps the engine perfectly in sync: instead of tracking state incrementally (which can desync), Viet+ replays the entire keystroke history through a fresh engine on every keypress. The screen output is always recomputed from scratch. --- ## Quick Start ```bash # Clone and build git clone https://git.khoavo.myds.me/vndangkhoa/vietc.git cd vietc make build-all # Test the engine interactively cargo run --bin vietc-cli # Run the daemon cargo run --bin vietc # Or download a package from the releases page # AppImage: ./Viet+-0.1.0-x86_64.AppImage # Debian: sudo dpkg -i vietc_0.1.0-1_amd64.deb ``` --- ## Input Methods ### Telex | Key | Result | Example | |-----|--------|---------| | `aa` | â | `tan` -> `tân` | | `aw` | ă | `tan` -> `tăn` | | `ee` | ê | `men` -> `mên` | | `oo` | ô | `to` -> `tô` | | `ow` | ơ | `to` -> `tơ` | | `uw` | ư | `tu` -> `tư` | | `s` | á (sắc) | `as` -> `á` | | `f` | à (huyền) | `af` -> `à` | | `r` | ả (hỏi) | `ar` -> `ả` | | `x` | ã (ngã) | `ax` -> `ã` | | `j` | ạ (nặng) | `aj` -> `ạ` | | `dd` | đ | `dd` -> `đ` | ### VNI | Key | Result | |-----|--------| | `a1` | á | | `a2` | à | | `a3` | ả | | `a4` | ã | | `a5` | ạ | | `a6` | â | | `a8` | ă | | `e6` | ê | | `o6` | ô | | `o7` | ơ | | `u7` | ư | --- ## Configuration Config file: `~/.config/vietc/config.toml` or `./vietc.toml` ```toml input_method = "vni" toggle_key = "space" start_enabled = false grab = true [auto_restore] enabled = true trigger_keys = ["space", "escape"] [app_state] enabled = true english_apps = ["code", "vim", "kitty", "foot"] vietnamese_apps = ["telegram", "discord", "firefox"] [macros] ko = "không" dc = "được" vs = "với" lm = "làm" ``` --- ## Architecture ``` ┌──────────────────┐ ┌──────────────────┐ ┌────────────────┐ │ X11 Keyboard │────▶│ Viet+ Daemon │────▶│ X11/XTEST │ │ Grab (XGrabKb) │ │ │ │ Injection │ │ │ │ Backspace-Replay│ │ │ │ FocusIn/Out │ │ Engine │ │ Direct │ │ Detection │ │ (Telex/VNI) │ │ Clipboard │ └──────────────────┘ └──────────────────┘ └────────────────┘ │ ┌─────┴─────┐ │ App State │ │ Manager │ └───────────┘ ``` ### How Backspace-Replay Works 1. All keystrokes in the current word are stored in `keystroke_history` 2. On each keypress, a **fresh engine** is created and the entire history is replayed through it 3. The engine's buffer IS what should be on screen 4. Viet+ calculates the diff: backspaces to erase old text + new text to type 5. On flush (space/period/etc.), history is cleared for the next word This eliminates the state desync bugs that plague incremental engines. --- ## Installation ### Debian/Ubuntu Package ```bash sudo dpkg -i vietc_0.1.0-1_amd64.deb ``` Recommends: `libxtst6`, `xclip` (for clipboard injection) ### AppImage ```bash ./Viet+-0.1.0-x86_64.AppImage ``` No special permissions needed on X11 — uses XGrabKeyboard + XTest injection. ### Manual Install ```bash make build-all sudo make install ``` --- ## Building ```bash # Build all backends (X11 + Wayland) make build-all # Run tests (255+ tests) make test # Run interactive test harness cargo run --bin vietc-cli # Build packages make deb # .deb package make appimage # AppImage ``` --- ## Project Structure ``` vietc/ ├── engine/ # Core IME engine (Telex + VNI) │ ├── src/ │ │ ├── engine.rs # Main engine + replay_keystrokes() │ │ ├── telex.rs # Telex state machine │ │ ├── vni.rs # VNI engine │ │ ├── english.rs # English auto-restore dictionary │ │ └── tests/ # 255+ unit tests │ └── Cargo.toml ├── protocol/ # Injection backends │ ├── src/ │ │ ├── inject.rs # KeyInjector trait │ │ ├── x11_capture.rs # X11 keyboard capture (XGrabKeyboard) │ │ ├── x11_inject.rs # Direct X11 clipboard + XTest injection │ │ └── wayland_im.rs # Wayland IM protocol │ └── Cargo.toml ├── daemon/ # Background daemon │ ├── src/ │ │ ├── main.rs # Event loop, Backspace-Replay integration │ │ ├── config.rs # TOML config loader │ │ ├── app_state.rs # Per-app state manager │ │ └── display.rs # Display server detection │ └── Cargo.toml ├── cli/ # Interactive test harness ├── ui/ # Tray icon application ├── packaging/ # Distribution packages │ ├── appimage/ # AppImage build scripts │ └── deb/ # .deb package build scripts ├── vietc.toml # Default configuration ├── vietc.service # Systemd user service ├── Makefile # Build targets └── README.md ``` --- ## Changelog See [CHANGELOG.md](CHANGELOG.md) for release history. --- ## License MIT License - see [LICENSE](LICENSE) for details. ---

Made with love for the Vietnamese Linux community