Skip to content

Commit 77b152b

Browse files
authored
Merge pull request openvanilla#680 from zonble/master
Adds GitHub Copilot and Gemini instructions
2 parents 8735a4c + c10b3b4 commit 77b152b

6 files changed

Lines changed: 99 additions & 1 deletion

File tree

.gemini/config.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
have_fun: false
2+
code_review:
3+
disable: false
4+
comment_severity_threshold: MEDIUM
5+
max_review_comments: -1
6+
pull_request_opened:
7+
help: false
8+
summary: true
9+
code_review: true
10+
include_drafts: true
11+
ignore_patterns: []

.github/copilot-instructions.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# McBopomofo Copilot Instructions
2+
3+
## Project Context
4+
- Input method for macOS built with AppKit/IMKit in Swift and bridged Objective-C++, backed by the C++ language model in `Source/Engine`.
5+
- Build and run with Xcode target `McBopomofo Installer`; Swift front end pulls helper frameworks from the local `Packages/` directory.
6+
- Dictionary assets and generation scripts live in `Source/Data`; compiled blobs are stored in `Source/Data/bin`.
7+
- Tests cover both layers: Swift XCTest-style suites in `McBopomofoTests` and GoogleTest cases in `Source/Engine/*Test.cpp` via CMake.
8+
- Preserve the existing MIT license banner on any new source file.
9+
10+
## Swift & AppKit Guidelines
11+
- Keep AppKit and IMKit work in Swift classes (`InputMethodController`, `PreferencesWindowController`, etc.) and limit scope with `private`/`fileprivate` helpers.
12+
- Use the `Preferences` static properties and property wrappers in `Source/Preferences.swift` instead of accessing `UserDefaults` directly; add new keys beside the existing constants.
13+
- Localize UI strings through `NSLocalizedString("…", comment: "")` and update the `.strings` files under `Base.lproj`, `en.lproj`, and `zh-Hant.lproj` when text changes.
14+
- Follow the established flow: `InputMethodController` drives menu actions, `KeyHandler` mediates IM events, and `InputState` models state transitions.
15+
- Perform UI work on the main thread; reuse existing helper methods or notifications rather than introducing ad-hoc dispatch queues.
16+
- Interact with the engine through `KeyHandler`/`LanguageModelManager` bridges instead of duplicating C++ logic in Swift.
17+
18+
## State Machine Design
19+
- Treat `InputState` subclasses as immutable snapshots; always create a new state object when the IM transitions instead of mutating existing instances.
20+
- Funnel key handling through `KeyHandler` so state transitions originate from one place and UI updates flow from the current state.
21+
- Keep UI and engine in sync by deriving candidate lists, composing buffers, and menu options from the state object rather than scattered flags.
22+
- Extend the state machine by adding new `InputState` subclasses plus explicit transitions; avoid adding booleans that bypass the existing states.
23+
24+
## Objective-C++ Bridge Guidelines
25+
- Manage engine lifetimes in `.mm` files by allocating in `init`, cleaning up in `dealloc`, and wrapping pointers in `std::shared_ptr` when passing to C++ APIs.
26+
- Surface new engine capabilities by extending bridge classes (`KeyHandler`, `LanguageModelManager`) and declaring them in `McBopomofo-Bridging-Header.h`.
27+
- Convert between `NSString` and `std::string` with `UTF8Helper`/`NSStringUtils`; avoid hand-written UTF conversions or raw buffers.
28+
- Keep bridge methods small: forward inputs to the engine and return plain values or Foundation types that Swift can consume.
29+
30+
## C++ Engine Guidelines
31+
- Stick to the existing C++17 style that uses `std::vector`, `std::unordered_map`, `std::optional`, and `std::string_view` as in `McBopomofoLM.cpp`.
32+
- Place new engine code inside the current namespaces (`McBopomofo`, `Formosa::Gramambular2`, `Formosa::Mandarin`) and reuse helper classes from `gramambular2`.
33+
- Reuse the blob readers (`KeyValueBlobReader`, `ParselessPhraseDB`, `PhraseReplacementMap`) when touching serialized resources; prefer augmenting them over inventing new formats.
34+
- Keep algorithms deterministic and side-effect free; logging and macOS-specific behavior should stay in the Objective-C++ layer.
35+
36+
## Tests and Tooling
37+
- Add Swift tests under `McBopomofoTests` using the `Testing` module with `@Suite`, `@Test`, and `#expect` macros; snapshot and restore `UserDefaults` like `PreferencesTests`.
38+
- Register new engine tests in `Source/Engine/CMakeLists.txt`, include them in the `McBopomofoLMLibTest` target, and use GoogleTest assertions.
39+
- When dictionary data changes, regenerate artifacts via the make targets in `Source/Data` and check updated binaries into `Source/Data/bin`.
40+
- Keep shell scripts such as `Source/add-phrase-hook.sh` POSIX-compliant and aligned with the existing shebang and style.
41+
42+
## Things to Avoid
43+
- Avoid replacing AppKit windows with SwiftUI or Combine; the runtime depends on NSWindow/XIB assets.
44+
- Do not bypass the bridge to talk to the engine directly from Swift; IMKit lifecycle assumptions require the Objective-C++ layer.
45+
- Refrain from hardcoding paths to user data; use the preference APIs and helper lookups.
46+
- Keep large dictionary blobs or generated files untouched unless the change specifically targets them.
47+
48+
## Reference Files
49+
- `Source/InputMethodController.swift`: IMK entry point coordinating candidate menus and preferences.
50+
- `Source/KeyHandler.mm`: Objective-C++ bridge between Swift events and the engine.
51+
- `Source/Engine/McBopomofoLM.cpp`: Core language model logic and unigram handling.
52+
- `McBopomofoTests/PreferencesTests.swift`: Example of the Swift `Testing` suite setup and patterns.
53+
- `Source/Engine/CMakeLists.txt`: Engine build configuration and test registration.
54+
55+
56+
57+
Note: https://docs.github.com/en/copilot/how-tos/configure-custom-instructions/add-repository-instructions#creating-path-specific-custom-instructions-1
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
applyTo: "Source/Data/*"
3+
---
4+
5+
These files define the mapping of phrases and words to their Bopomofo representations.
6+
7+
In most cases, developers will add new Chinese characters or phrases rather than delete existing ones. When adding new characters or phrases, please perform the following checks:
8+
9+
## Adding Phrases
10+
11+
When adding a new phrase containing multiple characters to `BPMFMappings.txt`, ensure that `phrase.occ` is also updated with the same phrase and its frequency. The frequency should be a positive integer. 0 is also acceptable, but negative values are not.
12+
13+
## Sorting
14+
15+
Both `BPMFMappings.txt` and `phrase.occ` must stay sorted using the C locale. After making changes, run `LC_ALL=C sort -o BPMFMappings.txt BPMFMappings.txt` and `LC_ALL=C sort -o phrase.occ phrase.occ` before committing.
16+
17+
## Heterophony Characters
18+
19+
When adding a new entry—such as a character with a Bopomofo reading—into `BPMFMappings.txt`, check if there is already an entry for the same character with a different Bopomofo reading. If so, this indicates a heterophony character, and you should review the frequency of each reading.
20+
21+
Often, the new reading will be much less common than the existing one. In such cases, add a comment to indicate that this is a heterophony character and note the frequency of each reading.
22+
23+
To reflect the lower frequency of the new reading, place the default reading in `heterophony1.list` and the new reading in `heterophony2.list`, and so on.
24+
25+
## Emojis and Symbols
26+
27+
We allow users to input emojis and symbols using Bopomofo. For example, when inputting ㄒㄧㄣ, we have 心 and ❤️‍🔥 in the candidate list. However, emojis and symbols should not be the default candidate of a given Bopomofo reading.

Source/Data/heterophony1.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,3 +521,4 @@
521521
龜 ㄍㄨㄟ
522522
化 ㄏㄨㄚˋ
523523
把 ㄅㄚˇ
524+
寫 ㄒㄧㄝˇ

Source/Data/heterophony3.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
著 ㄓㄨˋ
1313
著 ㄓㄨㄛˊ
1414
麼 ㄇㄚˊ
15+
寫 ㄒㄧㄝˋ

Source/zh-Hant.lproj/preferences.xib

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,8 @@
292292
</buttonCell>
293293
<cells>
294294
<column>
295-
<buttonCell type="radio" title="直接輸入大寫字母" imagePosition="left" alignment="left" state="on" inset="2" id="Udo-22-eqG">
295+
<buttonCell type="radio" title="直接輸入大
296+
字母" imagePosition="left" alignment="left" state="on" inset="2" id="Udo-22-eqG">
296297
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
297298
<font key="font" metaFont="system"/>
298299
</buttonCell>

0 commit comments

Comments
 (0)