|
| 1 | +# McBopomofo Copilot Instructions |
| 2 | + |
| 3 | +## What's the Project For |
| 4 | + |
| 5 | +McBopomofo (小麥注音輸入法) is a Traditional Chinese input method engine (IME) for macOS. It allows users to input Traditional Chinese characters using the Bopomofo phonetic system (注音符號), which is the standard phonetic notation system used in Taiwan. |
| 6 | + |
| 7 | +The project is part of the OpenVanilla framework and provides: |
| 8 | +- Smart phonetic-to-character conversion |
| 9 | +- User-customizable phrase dictionaries |
| 10 | +- Associated phrase suggestions |
| 11 | +- Multi-candidate selection |
| 12 | +- Support for custom user phrases and exclusions |
| 13 | + |
| 14 | +## System Requirements |
| 15 | + |
| 16 | +### Runtime Requirements |
| 17 | +- macOS 10.15 (Catalina) or later |
| 18 | + |
| 19 | +### Development Requirements |
| 20 | +- macOS 14.7 or later |
| 21 | +- Xcode 15.3 or later |
| 22 | +- Python 3.9 (available through Xcode or homebrew) |
| 23 | + |
| 24 | +## Build Process |
| 25 | + |
| 26 | +The project uses Xcode as its primary build system: |
| 27 | + |
| 28 | +1. **Open Project**: Open `McBopomofo.xcodeproj` in Xcode |
| 29 | +2. **Select Target**: Choose "McBopomofoInstaller" target |
| 30 | +3. **Build**: Build the project (⌘+B) |
| 31 | +4. **Install**: Run the installer directly to install McBopomofo |
| 32 | +5. **Reinstall**: For subsequent updates, repeat the process |
| 33 | + |
| 34 | +### Important Notes |
| 35 | +- macOS may limit the number of times an input method process can be killed in a single login session |
| 36 | +- If installation issues occur after multiple installs, log out and log back in |
| 37 | +- The installer automatically kills and restarts the input method process |
| 38 | + |
| 39 | +## Project Components |
| 40 | + |
| 41 | +### Architecture Overview |
| 42 | +``` |
| 43 | +McBopomofo/ |
| 44 | +├── Source/ # Main application source |
| 45 | +│ ├── Engine/ # C++ core engine |
| 46 | +│ │ ├── Mandarin/ # Bopomofo processing |
| 47 | +│ │ ├── gramambular2/ # Text segmentation library |
| 48 | +│ │ └── McBopomofoLM.* # Language model |
| 49 | +│ ├── InputState.swift # State machine implementation |
| 50 | +│ ├── InputMethodController.swift # Main controller |
| 51 | +│ └── Data/ # Language model data files |
| 52 | +├── McBopomofoTests/ # Test suite |
| 53 | +└── Packages/ # Swift Package dependencies |
| 54 | +``` |
| 55 | + |
| 56 | +### Technology Stack |
| 57 | +- **Swift**: UI layer, input method controller, state management |
| 58 | +- **Objective-C++**: Bridge between Swift and C++ components |
| 59 | +- **C++**: Core engine, language processing, data structures |
| 60 | +- **Xcode**: Build system and development environment |
| 61 | + |
| 62 | +### Framework Foundation |
| 63 | +McBopomofo is built on Apple's native input method frameworks: |
| 64 | + |
| 65 | +#### Cocoa Framework |
| 66 | +- **UI Components**: Native macOS user interface elements |
| 67 | +- **Event Handling**: Keyboard and mouse event processing |
| 68 | +- **Window Management**: Candidate window and preference panels |
| 69 | +- **Integration**: Seamless integration with macOS applications |
| 70 | + |
| 71 | +#### Input Method Kit (IMK) |
| 72 | +- **IMKInputController**: Base class for input method controllers |
| 73 | + - `McBopomofoInputMethodController` extends `IMKInputController` |
| 74 | + - Handles input events and text processing |
| 75 | + - Manages communication with client applications |
| 76 | +- **IMKServer**: Input method server infrastructure |
| 77 | + - Manages input method instances |
| 78 | + - Handles system-level input method operations |
| 79 | +- **IMKCandidateController**: Candidate selection interface |
| 80 | +- **Protocol Compliance**: Implements IMK protocols for proper system integration |
| 81 | + |
| 82 | +### Key Files |
| 83 | +- `InputMethodController.swift`: Main input method logic |
| 84 | +- `InputState.swift`: State machine implementation |
| 85 | +- `Source/Engine/McBopomofoLM.h/cpp`: Language model management |
| 86 | +- `Source/Engine/Mandarin/Mandarin.h/cpp`: Bopomofo processing |
| 87 | +- `Source/Engine/gramambular2/`: Text segmentation algorithms |
| 88 | + |
| 89 | +## Design of Input States |
| 90 | + |
| 91 | +McBopomofo implements a finite state machine with multiple distinct states to handle various input scenarios: |
| 92 | + |
| 93 | +### Core Input States |
| 94 | + |
| 95 | +1. **Deactivated**: User hasn't activated McBopomofo |
| 96 | +2. **Empty**: McBopomofo is active but no input yet, or user just committed text |
| 97 | +3. **Inputting**: User is typing Bopomofo keys; input buffer is visible |
| 98 | +4. **Committing**: Sending text to client applications |
| 99 | +5. **Marking**: User is selecting text in buffer to create custom phrase |
| 100 | +6. **ChoosingCandidate**: Candidate window is open for user selection |
| 101 | + |
| 102 | +### Extended States |
| 103 | + |
| 104 | +The system includes additional specialized states: |
| 105 | + |
| 106 | +- **SelectingFeature**: User accessing special features menu |
| 107 | +- **SelectingDateMacro**: Date/time macro selection |
| 108 | +- **ChineseNumber**: Chinese numeral conversion |
| 109 | +- **Big5**: Big5 encoding conversion |
| 110 | +- **EnclosedNumber**: Circled/parenthesized number conversion |
| 111 | +- **AssociatedPhrases**: Associated phrase suggestions |
| 112 | +- **SelectingDictionary**: Dictionary lookup mode |
| 113 | +- **ShowingCharInfo**: Character information display |
| 114 | +- **CustomMenu**: Custom menu operations |
| 115 | + |
| 116 | +### State Properties |
| 117 | +- **Immutable**: States are immutable objects; transitions create new state instances |
| 118 | +- **One-way data flow**: UI and text output follow single data source |
| 119 | +- **Context-specific data**: Each state contains only relevant data (e.g., candidate list only exists in Choosing Candidate state) |
| 120 | + |
| 121 | +### Implementation Details |
| 122 | +- Base class: `InputState` |
| 123 | +- State-specific subclasses: `Deactivated`, `Empty`, `Inputting`, `Committing`, `Marking`, `ChoosingCandidate` |
| 124 | +- Controller creates new state objects instead of modifying existing ones |
| 125 | + |
| 126 | +## Design of Mandarin Package |
| 127 | + |
| 128 | +The Mandarin package handles Bopomofo phonetic input processing and conversion. |
| 129 | + |
| 130 | +### Core Classes |
| 131 | + |
| 132 | +#### BopomofoSyllable (BPMF) |
| 133 | +- **Purpose**: Represents a complete Bopomofo syllable |
| 134 | +- **Storage**: 16-bit integer with bit masks for components |
| 135 | +- **Components**: Consonant, Middle Vowel, Vowel, Tone Marker |
| 136 | +- **Features**: |
| 137 | + - Conversion to/from Hanyu Pinyin |
| 138 | + - Composed string representation |
| 139 | + - Component validation and extraction |
| 140 | + - Overlap detection between syllables |
| 141 | + |
| 142 | +#### BopomofoKeyboardLayout |
| 143 | +- **Purpose**: Maps keyboard keys to Bopomofo components |
| 144 | +- **Key Functions**: |
| 145 | + - `syllableFromKeySequence()`: Converts key sequence to syllable |
| 146 | + - `keySequenceFromSyllable()`: Converts syllable back to keys |
| 147 | +- **Layout Support**: Different keyboard layouts for Bopomofo input |
| 148 | +- **Validation**: Ensures valid key combinations (e.g., J/Q/X require I or UE vowels) |
| 149 | + |
| 150 | +#### BopomofoReadingBuffer |
| 151 | +- **Purpose**: Manages user input during syllable composition |
| 152 | +- **Features**: |
| 153 | + - Key combination and validation |
| 154 | + - Pinyin mode support |
| 155 | + - Buffer clearing and state management |
| 156 | + - Integration with keyboard layouts |
| 157 | + |
| 158 | +### Key Algorithms |
| 159 | + |
| 160 | +#### Syllable Construction |
| 161 | +1. Process each key in input sequence |
| 162 | +2. Check for valid key combinations |
| 163 | +3. Handle special cases (J/Q/X with I/UE vowels) |
| 164 | +4. Apply tone markers correctly |
| 165 | +5. Validate final syllable composition |
| 166 | + |
| 167 | +#### Component Mapping |
| 168 | +- Bit-masked representation for efficient storage |
| 169 | +- Separate masks for consonants, vowels, and tones |
| 170 | +- Support for multiple components per key |
| 171 | + |
| 172 | +## Keyboard Layouts |
| 173 | + |
| 174 | +McBopomofo supports multiple Bopomofo keyboard layouts to accommodate different user preferences and typing habits: |
| 175 | + |
| 176 | +### Standard Layout |
| 177 | +- **Description**: Traditional Bopomofo layout used in Taiwan |
| 178 | +- **Characteristics**: Direct mapping of Bopomofo symbols to QWERTY keys |
| 179 | +- **Usage**: Most common layout for Bopomofo input |
| 180 | +- **Implementation**: `BopomofoKeyboardLayout::StandardLayout()` |
| 181 | + |
| 182 | +### ETen Layout |
| 183 | +- **Description**: ETen Traditional layout |
| 184 | +- **Characteristics**: Alternative key mapping optimized for certain typing patterns |
| 185 | +- **Usage**: Popular among users familiar with ETen input systems |
| 186 | +- **Implementation**: `BopomofoKeyboardLayout::ETenLayout()` |
| 187 | + |
| 188 | +### Hsu Layout (許氏鍵盤) |
| 189 | +- **Description**: Hsu keyboard layout designed by Hsu Lian-chin |
| 190 | +- **Characteristics**: |
| 191 | + - Optimized for faster typing with fewer keystrokes |
| 192 | + - Special heuristics for vowel combinations |
| 193 | + - Automatic correction rules (e.g., GI/GUE → JI/JUE) |
| 194 | +- **Usage**: Preferred by advanced users for speed typing |
| 195 | +- **Implementation**: `BopomofoKeyboardLayout::HsuLayout()` |
| 196 | + |
| 197 | +### ETen26 Layout |
| 198 | +- **Description**: ETen 26-key layout variant |
| 199 | +- **Characteristics**: Extended ETen layout with additional key combinations |
| 200 | +- **Usage**: Enhanced version of ETen layout |
| 201 | +- **Implementation**: `BopomofoKeyboardLayout::ETen26Layout()` |
| 202 | + |
| 203 | +### Layout Architecture |
| 204 | +- **Key-to-Component Mapping**: Each layout defines mappings from keyboard keys to Bopomofo components |
| 205 | +- **Syllable Construction**: Layouts handle complex rules for syllable formation |
| 206 | +- **Special Rules**: Each layout can implement specific typing optimizations and corrections |
| 207 | +- **Runtime Switching**: Users can switch between layouts in preferences |
| 208 | + |
| 209 | +## Design of Language Model (McBopomofoLM) |
| 210 | + |
| 211 | +The language model manages text conversion, user customization, and phrase suggestions. |
| 212 | + |
| 213 | +### Architecture |
| 214 | + |
| 215 | +#### McBopomofoLM Class |
| 216 | +- **Inheritance**: Extends `Formosa::Gramambular2::LanguageModel` |
| 217 | +- **Purpose**: Central hub for all language processing |
| 218 | +- **Integration**: Combines multiple data sources and processing layers |
| 219 | + |
| 220 | +### Data Processing Pipeline |
| 221 | + |
| 222 | +When processing unigrams (single-character/phrase entries): |
| 223 | + |
| 224 | +1. **Original Unigrams**: Retrieve from primary language model |
| 225 | +2. **Exclusion Filtering**: Remove user-excluded phrases |
| 226 | +3. **Phrase Replacement**: Apply user-defined replacements |
| 227 | +4. **External Conversion**: Transform via external converter (if enabled) |
| 228 | +5. **Deduplication**: Remove duplicate entries |
| 229 | +6. **Return Results**: Provide final candidate list |
| 230 | + |
| 231 | +### Key Components |
| 232 | + |
| 233 | +#### Primary Language Model |
| 234 | +- **ParselessLM**: Main language model for character/phrase data |
| 235 | +- **Unigram-based**: Uses single-token probability model |
| 236 | +- **File-based**: Loads from bundled data files |
| 237 | + |
| 238 | +#### User Customization |
| 239 | +- **UserPhrasesLM**: User-defined custom phrases |
| 240 | +- **Exclusion List**: User-blocked phrases |
| 241 | +- **Replacement Map**: User-defined phrase substitutions |
| 242 | +- **Associated Phrases**: Context-based phrase suggestions |
| 243 | + |
| 244 | +#### External Processing |
| 245 | +- **Macro Converter**: Handles text macros and shortcuts |
| 246 | +- **External Converter**: Traditional/Simplified Chinese character conversion (OpenCC-based) |
| 247 | +- **Runtime Configuration**: Enable/disable features dynamically |
| 248 | + |
| 249 | +### File Management |
| 250 | +- **User Data Folder**: Configurable location for user files |
| 251 | +- **Template System**: Automatic creation of empty user files |
| 252 | +- **Atomic Updates**: Safe file writing and reloading |
| 253 | + |
| 254 | +## Algorithm of Gramambular2 |
| 255 | + |
| 256 | +Gramambular2 is the core segmentation and input method library using statistical models. |
| 257 | + |
| 258 | +### Theoretical Foundation |
| 259 | + |
| 260 | +#### Hidden Markov Model (HMM) |
| 261 | +- **Observations**: Input characters or Bopomofo syllables |
| 262 | +- **Hidden States**: Possible character/phrase groupings |
| 263 | +- **Goal**: Find most likely segmentation given input sequence |
| 264 | + |
| 265 | +#### Naive Bayes Classification |
| 266 | +- **Approach**: Simplified probabilistic classification |
| 267 | +- **Assumptions**: Independence between features |
| 268 | +- **Efficiency**: Fast computation suitable for real-time input |
| 269 | + |
| 270 | +### Core Algorithm |
| 271 | + |
| 272 | +#### Segmentation Process |
| 273 | +1. **Input Sequence**: Receive series of observations (syllables/characters) |
| 274 | +2. **State Generation**: Generate possible hidden states (character combinations) |
| 275 | +3. **Probability Calculation**: Compute likelihood using unigram model |
| 276 | +4. **Path Selection**: Choose most probable segmentation path |
| 277 | +5. **Output Generation**: Return most likely character sequence |
| 278 | + |
| 279 | +#### Language Model Integration |
| 280 | +- **Unigram Model**: Simple single-token probability model |
| 281 | +- **Frequency-based**: Probabilities derived from corpus frequency |
| 282 | +- **Extensible**: Support for custom language models |
| 283 | + |
| 284 | +### Implementation Details |
| 285 | + |
| 286 | +#### Reading Grid |
| 287 | +- **Purpose**: Manages candidate generation and selection |
| 288 | +- **Structure**: Grid of possible readings and conversions |
| 289 | +- **Optimization**: Efficient storage and retrieval of candidates |
| 290 | + |
| 291 | +#### Language Model Interface |
| 292 | +- **Abstract Base**: `LanguageModel` interface for pluggable models |
| 293 | +- **Standard Methods**: `hasUnigrams()`, `getUnigrams()` for data access |
| 294 | +- **Extensibility**: Support for custom language model implementations |
| 295 | + |
| 296 | +### Performance Characteristics |
| 297 | +- **Real-time**: Optimized for interactive input method use |
| 298 | +- **Memory Efficient**: Minimal memory footprint |
| 299 | +- **Scalable**: Handles large dictionaries efficiently |
| 300 | +- **Fast Lookup**: Quick candidate generation and ranking |
| 301 | + |
| 302 | +### Use Cases |
| 303 | +1. **Input Method**: Convert Bopomofo sequences to Chinese characters |
| 304 | +2. **Text Segmentation**: Break Chinese text into meaningful units |
| 305 | +3. **Candidate Ranking**: Order possible conversions by probability |
| 306 | +4. **Context Awareness**: Consider surrounding text for better suggestions |
| 307 | + |
| 308 | +## Development Guidelines |
| 309 | + |
| 310 | +### Code Organization |
| 311 | +- **Swift**: Use for UI, state management, and application logic |
| 312 | +- **C++**: Use for performance-critical algorithms and data processing |
| 313 | +- **Objective-C++**: Use for bridging between Swift and C++ |
| 314 | + |
| 315 | +### Testing |
| 316 | +McBopomofo employs a comprehensive testing strategy with both C++ and Swift test suites: |
| 317 | + |
| 318 | +#### C++ Engine Tests |
| 319 | +Located in `Source/Engine/`, these tests validate core algorithms and data structures: |
| 320 | + |
| 321 | +- **Unit Tests**: Individual component testing using Google Test framework |
| 322 | +- **Test Files**: |
| 323 | + - `MandarinTest.cpp`: Bopomofo syllable and keyboard layout tests |
| 324 | + - `McBopomofoLMTest.cpp`: Language model functionality tests |
| 325 | + - `ParselessLMTest.cpp`: Language model parsing and data structure tests |
| 326 | + - `UTF8HelperTest.cpp`: UTF-8 string processing tests |
| 327 | + - `UserPhrasesLMTest.cpp`: User-defined phrase management tests |
| 328 | + - `PhraseReplacementMapTest.cpp`: Phrase replacement logic tests |
| 329 | + - `KeyValueBlobReaderTest.cpp`: Data file reading tests |
| 330 | + - `MemoryMappedFileTest.cpp`: Memory-mapped file operations tests |
| 331 | + - `AssociatedPhrasesV2Test.cpp`: Associated phrase suggestion tests |
| 332 | + - `UserOverrideModelTest.cpp`: User override functionality tests |
| 333 | +- **Coverage**: Core engine components, data structures, algorithms |
| 334 | +- **Build**: Integrated with CMake build system |
| 335 | + |
| 336 | +#### Swift Application Tests |
| 337 | +Located in `McBopomofoTests/`, these tests validate application logic and UI integration: |
| 338 | + |
| 339 | +- **Test Framework**: XCTest framework for Swift testing |
| 340 | +- **Test Files**: |
| 341 | + - `KeyHandlerBopomofoTests.swift`: Input processing and key handling tests |
| 342 | + - `KeyHandlerPlainBopomofoTests.swift`: Plain Bopomofo input tests |
| 343 | + - `PreferencesTests.swift`: User preferences and configuration tests |
| 344 | + - `DictionaryServiceTests.swift`: Dictionary lookup service tests |
| 345 | + - `ServiceProviderTests.swift`: Input method service provider tests |
| 346 | + - `AssociatedPhrasesTests.swift`: Associated phrase functionality tests |
| 347 | + - `InputMacroTests.swift`: Text macro processing tests |
| 348 | + - `VersionUpdateTests.swift`: Version management and update tests |
| 349 | +- **Integration**: Tests complete input workflows and state management |
| 350 | +- **UI Testing**: Validates user interface components and interactions |
| 351 | + |
| 352 | +#### Mixed Language Tests |
| 353 | +- **UTF8HelperTest.mm**: Objective-C++ test bridging Swift and C++ components |
| 354 | +- **Bridging Header**: `McBopomofoTests-Bridging-Header.h` enables Swift-C++ interop in tests |
| 355 | + |
| 356 | +#### Testing Approach |
| 357 | +- **Isolated Testing**: C++ tests focus on algorithmic correctness |
| 358 | +- **Integration Testing**: Swift tests validate complete user workflows |
| 359 | +- **Cross-Language Testing**: Objective-C++ tests ensure proper bridging |
| 360 | +- **Continuous Validation**: Both test suites run during development cycles |
| 361 | + |
| 362 | +### Debugging |
| 363 | +- **State Inspection**: Monitor InputState transitions |
| 364 | +- **Language Model**: Verify unigram processing pipeline |
| 365 | +- **Syllable Processing**: Check Bopomofo key handling |
| 366 | + |
| 367 | +### Performance Considerations |
| 368 | +- **Memory Management**: Careful handling of large language model data |
| 369 | +- **Real-time Constraints**: Input method must be responsive |
| 370 | +- **Battery Usage**: Optimize for minimal system impact |
0 commit comments