├── tmp
└── .keep
├── .gitignore
├── assets
└── demo.gif
├── NyaIME
├── Assets.xcassets
│ ├── Contents.json
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
├── Sources
│ ├── InputState.swift
│ ├── NyaIMEApp.swift
│ ├── EventType.swift
│ ├── Nya.swift
│ ├── ComposingText.swift
│ └── NyaIMEInputController.swift
├── NyaIME.entitlements
├── Info.plist
└── Resources
│ └── cat.svg
├── NyaIME.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── xcuserdata
│ └── koki.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── xcshareddata
│ └── xcschemes
│ │ └── NyaIME.xcscheme
└── project.pbxproj
├── Taskfile.yml
├── pkg.plist
├── distribution.xml
├── LICENSE
├── README.md
├── README.nya.md
├── .swift-format
└── .github
└── workflows
└── release.yml
/tmp/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /tmp/*
3 | !/tmp/.keep
4 |
--------------------------------------------------------------------------------
/assets/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/koki-develop/NyaIME/HEAD/assets/demo.gif
--------------------------------------------------------------------------------
/NyaIME/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/NyaIME/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/NyaIME.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NyaIME/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/NyaIME/Sources/InputState.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InputState.swift
3 | // NyaIME
4 | //
5 | // Created by koki sato on 2024/09/07.
6 | //
7 |
8 | enum InputState {
9 | case normal
10 | case composing
11 | case selecting
12 | }
13 |
--------------------------------------------------------------------------------
/NyaIME.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Taskfile.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | tasks:
4 | build:
5 | silent: true
6 | cmds:
7 | - xcodebuild -project ./NyaIME.xcodeproj -configuration Debug
8 | install:
9 | silent: true
10 | deps: [build]
11 | cmds:
12 | - cp -R ./build/Debug/NyaIME.app ~/Library/Input\ Methods
13 | - task: stop
14 | stop:
15 | silent: true
16 | cmds:
17 | - pkill NyaIME
18 |
--------------------------------------------------------------------------------
/NyaIME/NyaIME.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.temporary-exception.mach-register.global-name
8 | $(PRODUCT_BUNDLE_IDENTIFIER)_Connection
9 |
10 |
11 |
--------------------------------------------------------------------------------
/NyaIME.xcodeproj/xcuserdata/koki.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | NyaIME.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/pkg.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | BundleHasStrictIdentifier
7 |
8 | BundleIsRelocatable
9 |
10 | BundleIsVersionChecked
11 |
12 | BundleOverwriteAction
13 | upgrade
14 | RootRelativeBundlePath
15 | NyaIME.app
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/NyaIME/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | InputMethodConnectionName
6 | $(PRODUCT_BUNDLE_IDENTIFIER)_Connection
7 | InputMethodServerControllerClass
8 | $(PRODUCT_MODULE_NAME).NyaIMEInputController
9 | TISIntendedLanguage
10 | ja
11 | tsInputMethodIconFileKey
12 | cat.svg
13 |
14 |
15 |
--------------------------------------------------------------------------------
/distribution.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | tmp.pkg
15 |
--------------------------------------------------------------------------------
/NyaIME/Sources/NyaIMEApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NyaIMEApp.swift
3 | // NyaIME
4 | //
5 | // Created by koki sato on 2024/09/06.
6 | //
7 |
8 | import InputMethodKit
9 |
10 | class NSManualApplication: NSApplication {
11 | let appDelegate = AppDelegate()
12 |
13 | override init() {
14 | super.init()
15 | self.delegate = self.appDelegate
16 | }
17 |
18 | required init?(coder: NSCoder) {
19 | fatalError("init(coder:) has not been implemented")
20 | }
21 | }
22 |
23 | @main
24 | class AppDelegate: NSObject, NSApplicationDelegate {
25 | var server = IMKServer()
26 |
27 | func applicationDidFinishLaunching(_ notification: Notification) {
28 | self.server = IMKServer(
29 | name: Bundle.main.infoDictionary?["InputMethodConnectionName"] as? String,
30 | bundleIdentifier: Bundle.main.bundleIdentifier
31 | )
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Koki Sato
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/NyaIME/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "scale" : "1x",
6 | "size" : "16x16"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "scale" : "2x",
11 | "size" : "16x16"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "scale" : "1x",
16 | "size" : "32x32"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "scale" : "2x",
21 | "size" : "32x32"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "scale" : "1x",
26 | "size" : "128x128"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "scale" : "2x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "scale" : "1x",
36 | "size" : "256x256"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "scale" : "2x",
41 | "size" : "256x256"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "scale" : "1x",
46 | "size" : "512x512"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "scale" : "2x",
51 | "size" : "512x512"
52 | }
53 | ],
54 | "info" : {
55 | "author" : "xcode",
56 | "version" : 1
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/NyaIME/Sources/EventType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EventType.swift
3 | // NyaIME
4 | //
5 | // Created by koki sato on 2024/09/07.
6 | //
7 |
8 | import AppKit
9 |
10 | enum EventType {
11 | case esc
12 | case enter
13 | case backspace
14 | case space
15 | case down
16 | case up
17 | case input(_ text: String)
18 | }
19 |
20 | func getEventType(_ event: NSEvent) -> EventType? {
21 | switch event.keyCode {
22 | case 36:
23 | return .enter
24 | case 49:
25 | return .space
26 | case 51:
27 | return .backspace
28 | case 53:
29 | return .esc
30 | case 125:
31 | return .down
32 | case 126:
33 | return .up
34 | default:
35 | break
36 | }
37 |
38 | if let text = event.characters, isPrintable(text) {
39 | return .input(text)
40 | }
41 |
42 | return nil
43 | }
44 |
45 | func isPrintable(_ text: String) -> Bool {
46 | let printable = [
47 | CharacterSet.alphanumerics,
48 | CharacterSet.symbols,
49 | CharacterSet.punctuationCharacters,
50 | ].reduce(CharacterSet()) { $0.union($1) }
51 | return !text.unicodeScalars.contains(where: { !printable.contains($0) })
52 | }
53 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
🐈 NyaIME
2 |
3 |
4 | 猫の IME for Mac
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | 日本語 | ニャニャニャ
13 |
14 |
15 | # インストール
16 |
17 | ## Homebrew
18 |
19 | Homebrew を使用している場合は次のコマンドでインストールすることができます。
20 |
21 | ```console
22 | $ brew install koki-develop/tap/nyaime
23 | ```
24 |
25 | インストールが完了したら一度 Mac を再起動もしくはログアウトしてから、もう一度ログインしてください。
26 | その後、 `設定` > `キーボード` > `入力ソース` で `+` ボタンを押して `日本語` > `NyaIME` を追加してください。
27 |
28 | ## GitHub リリース
29 |
30 | [GitHub リリース](https://github.com/koki-develop/NyaIME/releases/latest) から `NyaIME.pkg` をダウンロードしてください。
31 | ダウンロードしたファイルを開くと NyaIME をインストールすることができます。
32 |
33 | > [!WARNING]
34 | >
35 | > 現在 `NyaIME.pkg` には署名を設定していないため、ダウンロードしたファイルをそのまま開こうとしてもセキュリティの警告が表示されて開くことができません。
36 | > 開くためには Finder から `NyaIME.pkg` を右クリックして `開く` を選択してください。
37 |
38 | インストールが完了したら一度 Mac を再起動もしくはログアウトしてから、もう一度ログインしてください。
39 | その後、 `設定` > `キーボード` > `入力ソース` で `+` ボタンを押して `日本語` > `NyaIME` を追加してください。
40 |
41 | # アンインストール
42 |
43 | ## Homebrew を使用してインストールした場合
44 |
45 | Homebrew を使用してインストールした場合は次のコマンドでアンインストールすることができます。
46 |
47 | ```console
48 | $ brew uninstall nyaime
49 | ```
50 |
51 | ## GitHub リリースからダウンロードした場合
52 |
53 | GitHub リリースからダウンロードした `NyaIME.pkg` を使用してインストールした場合は次の手順を実行してください。
54 |
55 | 1. `設定` > `キーボード` > `入力ソース` で `NyaIME` を選択した状態で `-` ボタンを押してください。
56 | 2. `~/Library/Input Methods/NyaIME.app` を削除してください。
57 |
58 | # ライセンス
59 |
60 | [MIT](./LICENSE)
61 |
--------------------------------------------------------------------------------
/NyaIME/Sources/Nya.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Nya.swift
3 | // NyaIME
4 | //
5 | // Created by koki sato on 2024/09/08.
6 | //
7 |
8 | struct Nya {
9 | let hiraganaZenkaku: String
10 | let katakanaZenkaku: String
11 | let katakanaHankaku: String
12 | }
13 |
14 | func toNya(_ text: String) -> Nya {
15 | let hiraganaZenkaku = text.enumerated().map { (i, char) in
16 | switch true {
17 | case "あお".contains(char):
18 | if i > 0 {
19 | return String(char)
20 | } else {
21 | return "にゃ"
22 | }
23 | case "うえかくけこがぐげごさすせそざずぜぞたつてとだづでどなぬねのはふへほばぶべぼぱぷぺぽまむめもやゆよらるれろわゎを".contains(char):
24 | return "にゃ"
25 | case "いきぎしじちぢにひびぴみり".contains(char):
26 | return "に"
27 | case "んぁぃぅぇぉっ".contains(char):
28 | return String(char)
29 | case "ゃゅょ".contains(char):
30 | if i > 0 {
31 | let prev = text[text.index(text.startIndex, offsetBy: i - 1)]
32 | if "きぎしじちぢにひびぴみり".contains(prev) {
33 | return "ゃ"
34 | }
35 | }
36 | return "にゃ"
37 | default:
38 | return String(char)
39 | }
40 | }.joined()
41 |
42 | let katakanaZenkaku = hiraganaZenkaku.applyingTransform(.hiraganaToKatakana, reverse: false)!
43 | let katakanaHankaku = katakanaZenkaku.applyingTransform(.fullwidthToHalfwidth, reverse: false)!
44 |
45 | return Nya(
46 | hiraganaZenkaku: hiraganaZenkaku,
47 | katakanaZenkaku: katakanaZenkaku,
48 | katakanaHankaku: katakanaHankaku
49 | )
50 | }
51 |
--------------------------------------------------------------------------------
/README.nya.md:
--------------------------------------------------------------------------------
1 | 🐈 NyaIME
2 |
3 |
4 | ニャニャニャ IME for Mac
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | 日本語 | ニャニャニャ
14 |
15 |
16 | # ニンニャニャーニャ
17 |
18 | ## Homebrew
19 |
20 | Homebrew ニャニニャニャニニャニニャニャアニニャニャニニャニャニャンニャニャニンニャニャーニャニャニャニャニャニャニャニニャニャ。
21 |
22 | ```console
23 | $ brew install koki-develop/tap/nyaime
24 | ```
25 |
26 | ニンニャニャーニャニャニャンニャニャニニャニャニニニャ Mac ニャニャニニニャニャニャニニャニャニャニャアニャニャニニャニャニャ、ニャニャニニニャニャニャニンニニャニャニャニャニ。
27 | ニャニャニャ、 `ニャッニャニ` > `ニーニャーニャ` > `ニャニャニャニャニャーニャ` ニャ `+` ニャニャンニャオニニャ `ニニャンニャ` > `NyaIME` ニャニャニニャニニャニャニャニャニ。
28 |
29 | ## GitHub ニニーニャ
30 |
31 | [GitHub ニニーニャ](https://github.com/koki-develop/NyaIME/releases/latest) ニャニャ `NyaIME.pkg` ニャニャニャンニャーニャニニャニャニャニャニ。
32 | ニャニャンニャーニャニニャニャァニニャニャニニャニャニャ NyaIME ニャニンニャニャーニャニャニャニャニャニャニャニニャニャ。
33 |
34 | > [!WARNING]
35 | >
36 | > ニャンニャニ `NyaIME.pkg` ニニャニャニャニニャニャッニャニニニャニニャニニャニャ、ニャニャンニャーニャニニャニャァニニャニャニャニャニャニャニニャニャニャニャニニャニャニャニャニニャィニャニャニニャニャニャニャニャニニャニャニャニニャニャニャニャニャニャニニャニャン。
37 | > ニニャニャニャニャニニャ Finder ニャニャ `NyaIME.pkg` ニャニニニャニッニャニニャ `ニニャニャ` ニャニャンニャニャニニャニャニャニャニ。
38 |
39 | ニンニャニャーニャニャニャンニャニャニニャニャニニニャ Mac ニャニャニニニャニャニャニニャニャニャニャアニャニャニニャニャニャ、ニャニャニニニャニャニャニンニニャニャニャニャニ。
40 | ニャニャニャ、 `ニャッニャニ` > `ニーニャーニャ` > `ニャニャニャニャニャーニャ` ニャ `+` ニャニャンニャオニニャ `ニニャンニャ` > `NyaIME` ニャニャンニャニャニニャニャニャニャニ。
41 |
42 | # ニャンニンニャニャーニャ
43 |
44 | ## Homebrew ニャニニャニャニニャニンニャニャーニャニニャニャアニ
45 |
46 | Homebrew ニャニニャニャニニャニンニャニャーニャニニャニャアニニャニャニニャニャニャンニャニャニャンニンニャニャーニャニャニャニャニャニャニャニニャニャ。
47 |
48 | ```console
49 | $ brew uninstall nyaime
50 | ```
51 |
52 | ## GitHub ニニーニャニャニャニャニャンニャーニャニニャニャアニ
53 |
54 | GitHub ニニーニャニャニャニャニャンニャーニャニニャ `NyaIME.pkg` ニャニニャニャニニャニンニャニャーニャニニャニャアニニャニャニニャニャニャンニャニッニャニャニニャニャニャニャニ。
55 |
56 | 1. `ニャッニャニ` > `ニーニャーニャ` > `ニャニャニャニャニャーニャ` ニャ `NyaIME` ニャニャンニャニャニニャニャニャニャニニャ `-` ニャニャンニャオニニャニャニャニャニ。
57 | 2. `~/Library/Input Methods/NyaIME.app` ニャニャニャニャニニャニャニャニャニ。
58 |
59 | # ニャニニャンニャ
60 |
61 | [MIT](./LICENSE)
62 |
--------------------------------------------------------------------------------
/NyaIME/Resources/cat.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
29 |
--------------------------------------------------------------------------------
/.swift-format:
--------------------------------------------------------------------------------
1 | {
2 | "fileScopedDeclarationPrivacy" : {
3 | "accessLevel" : "private"
4 | },
5 | "indentation" : {
6 | "spaces" : 4
7 | },
8 | "indentConditionalCompilationBlocks" : true,
9 | "indentSwitchCaseLabels" : false,
10 | "lineBreakAroundMultilineExpressionChainComponents" : false,
11 | "lineBreakBeforeControlFlowKeywords" : false,
12 | "lineBreakBeforeEachArgument" : false,
13 | "lineBreakBeforeEachGenericRequirement" : false,
14 | "lineLength" : 100,
15 | "maximumBlankLines" : 1,
16 | "multiElementCollectionTrailingCommas" : true,
17 | "noAssignmentInExpressions" : {
18 | "allowedFunctions" : [
19 | "XCTAssertNoThrow"
20 | ]
21 | },
22 | "prioritizeKeepingFunctionOutputTogether" : false,
23 | "respectsExistingLineBreaks" : true,
24 | "rules" : {
25 | "AllPublicDeclarationsHaveDocumentation" : false,
26 | "AlwaysUseLiteralForEmptyCollectionInit" : false,
27 | "AlwaysUseLowerCamelCase" : true,
28 | "AmbiguousTrailingClosureOverload" : true,
29 | "BeginDocumentationCommentWithOneLineSummary" : false,
30 | "DoNotUseSemicolons" : true,
31 | "DontRepeatTypeInStaticProperties" : true,
32 | "FileScopedDeclarationPrivacy" : true,
33 | "FullyIndirectEnum" : true,
34 | "GroupNumericLiterals" : true,
35 | "IdentifiersMustBeASCII" : true,
36 | "NeverForceUnwrap" : false,
37 | "NeverUseForceTry" : false,
38 | "NeverUseImplicitlyUnwrappedOptionals" : false,
39 | "NoAccessLevelOnExtensionDeclaration" : true,
40 | "NoAssignmentInExpressions" : true,
41 | "NoBlockComments" : true,
42 | "NoCasesWithOnlyFallthrough" : true,
43 | "NoEmptyTrailingClosureParentheses" : true,
44 | "NoLabelsInCasePatterns" : true,
45 | "NoLeadingUnderscores" : false,
46 | "NoParensAroundConditions" : true,
47 | "NoPlaygroundLiterals" : true,
48 | "NoVoidReturnOnFunctionSignature" : true,
49 | "OmitExplicitReturns" : false,
50 | "OneCasePerLine" : true,
51 | "OneVariableDeclarationPerLine" : true,
52 | "OnlyOneTrailingClosureArgument" : true,
53 | "OrderedImports" : true,
54 | "ReplaceForEachWithForLoop" : true,
55 | "ReturnVoidInsteadOfEmptyTuple" : true,
56 | "TypeNamesShouldBeCapitalized" : true,
57 | "UseEarlyExits" : false,
58 | "UseLetInEveryBoundCaseVariable" : true,
59 | "UseShorthandTypeNames" : true,
60 | "UseSingleLinePropertyGetter" : true,
61 | "UseSynthesizedInitializer" : true,
62 | "UseTripleSlashForDocumentationComments" : true,
63 | "UseWhereClausesInForLoops" : false,
64 | "ValidateDocumentationComments" : false
65 | },
66 | "spacesAroundRangeFormationOperators" : false,
67 | "tabWidth" : 8,
68 | "version" : 1
69 | }
70 |
--------------------------------------------------------------------------------
/NyaIME.xcodeproj/xcshareddata/xcschemes/NyaIME.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
42 |
44 |
50 |
51 |
52 |
53 |
59 |
61 |
67 |
68 |
69 |
70 |
72 |
73 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 | run-name: Release ${{ github.ref_name}}
3 |
4 | on:
5 | push:
6 | tags:
7 | - 'v*'
8 |
9 | jobs:
10 | release:
11 | runs-on: macos-latest
12 | permissions:
13 | contents: write
14 | steps:
15 | - uses: actions/checkout@v4
16 |
17 | - name: Build
18 | run: |
19 | xcodebuild \
20 | -project ./NyaIME.xcodeproj \
21 | -configuration Release \
22 | CODE_SIGNING_ALLOWED=NO
23 | mkdir ./tmp/app
24 | mv ./build/Release/NyaIME.app ./tmp/app/
25 |
26 | - name: Build Package
27 | run: |
28 | xcrun pkgbuild \
29 | --root ./tmp/app \
30 | --component-plist ./pkg.plist \
31 | --identifier me.koki.inputmethod.NyaIME \
32 | --install-location '/Library/Input Methods' \
33 | ./tmp/tmp.pkg
34 |
35 | - name: Build Installer
36 | run: |
37 | xcrun productbuild \
38 | --distribution distribution.xml \
39 | --package-path ./tmp \
40 | ./tmp/NyaIME.pkg
41 |
42 | - name: Create Release
43 | uses: softprops/action-gh-release@v2
44 | with:
45 | files: ./tmp/NyaIME.pkg
46 |
47 | - name: Checkout homebrew-tap
48 | uses: actions/checkout@v4
49 | with:
50 | repository: koki-develop/homebrew-tap
51 | path: homebrew-tap
52 | token: ${{ secrets.TAP_GITHUB_TOKEN }}
53 |
54 | - name: Tap metadata
55 | id: tap
56 | env:
57 | GITHUB_REF_NAME: ${{ github.ref_name }}
58 | GH_TOKEN: ${{ github.token }}
59 | run: |
60 | echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
61 | echo "sha256=$(shasum -a 256 ./tmp/NyaIME.pkg | awk '{print $1}')" >> $GITHUB_OUTPUT
62 | echo "homepage=https://github.com/koki-develop/NyaIME" >> $GITHUB_OUTPUT
63 | echo "desc=$(gh repo view koki-develop/NyaIME --json description --jq .description)" >> $GITHUB_OUTPUT
64 |
65 | - name: Update Tap
66 | working-directory: homebrew-tap
67 | env:
68 | NYAIME_VERSION: ${{ steps.tap.outputs.version }}
69 | NYAIME_SHA256: ${{ steps.tap.outputs.sha256 }}
70 | NYAIME_HOMEPAGE: ${{ steps.tap.outputs.homepage }}
71 | NYAIME_DESC: ${{ steps.tap.outputs.desc }}
72 | run: |
73 | mkdir -p Casks
74 | cat < Casks/nyaime.rb
75 | cask "nyaime" do
76 | version "${NYAIME_VERSION}"
77 | url "https://github.com/koki-develop/NyaIME/releases/download/v#{version}/NyaIME.pkg"
78 | sha256 "${NYAIME_SHA256}"
79 |
80 | name "NyaIME"
81 | desc "${NYAIME_DESC}"
82 | homepage "${NYAIME_HOMEPAGE}"
83 |
84 | pkg "NyaIME.pkg"
85 | uninstall pkgutil: "me.koki.inputmethod.NyaIME"
86 | end
87 | EOF
88 | cat Casks/nyaime.rb
89 |
90 | # https://github.com/actions/checkout#push-a-commit-using-the-built-in-token
91 | git config user.name "github-actions[bot]"
92 | git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
93 | git add ./Casks/nyaime.rb
94 | git commit -m "Brew cask update for nyaime version v${NYAIME_VERSION}"
95 | git push origin main
96 |
--------------------------------------------------------------------------------
/NyaIME/Sources/ComposingText.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ComposingText.swift
3 | // NyaIME
4 | //
5 | // Created by koki sato on 2024/09/07.
6 | //
7 |
8 | let composingTextmap: [String: String] = [
9 | // a
10 | "a": "あ", "i": "い", "u": "う", "e": "え", "o": "お",
11 | // b
12 | "bb": "っb",
13 | "ba": "ば", "bi": "び", "bu": "ぶ", "be": "べ", "bo": "ぼ",
14 | "bya": "びゃ", "byi": "びぃ", "byu": "びゅ", "bye": "びぇ", "byo": "びょ",
15 | // c
16 | "cc": "っc",
17 | "cha": "ちゃ", "chi": "ち", "chu": "ちゅ", "che": "ちぇ", "cho": "ちょ",
18 | "cya": "ちゃ", "cyi": "ちぃ", "cyu": "ちゅ", "cye": "ちぇ", "cyo": "ちょ",
19 | // d
20 | "dd": "っd",
21 | "da": "だ", "di": "ぢ", "du": "づ", "de": "で", "do": "ど",
22 | "dha": "でゃ", "dhi": "でぃ", "dhu": "でゅ", "dhe": "でぇ", "dho": "でょ",
23 | "dya": "ぢゃ", "dyi": "ぢぃ", "dyu": "ぢゅ", "dye": "ぢぇ", "dyo": "ぢょ",
24 | // f
25 | "ff": "っf",
26 | "fa": "ふぁ", "fi": "ふぃ", "fu": "ふ", "fe": "ふぇ", "fo": "ふぉ",
27 | "fya": "ふゃ", "fyi": "ふぃ", "fyu": "ふゅ", "fye": "ふぇ", "fyo": "ふょ",
28 | // g
29 | "gg": "っg",
30 | "ga": "が", "gi": "ぎ", "gu": "ぐ", "ge": "げ", "go": "ご",
31 | "gya": "ぎゃ", "gyi": "ぎぃ", "gyu": "ぎゅ", "gye": "ぎぇ", "gyo": "ぎょ",
32 | // h
33 | "hh": "っh",
34 | "ha": "は", "hi": "ひ", "hu": "ふ", "he": "へ", "ho": "ほ",
35 | "hya": "ひゃ", "hyi": "ひぃ", "hyu": "ひゅ", "hye": "ひぇ", "hyo": "ひょ",
36 | // j
37 | "jj": "っj",
38 | "ja": "じゃ", "ji": "じ", "ju": "じゅ", "je": "じぇ", "jo": "じょ",
39 | "jya": "じゃ", "jyi": "じぃ", "jyu": "じゅ", "jye": "じぇ", "jyo": "じょ",
40 | // k
41 | "kk": "っk",
42 | "ka": "か", "ki": "き", "ku": "く", "ke": "け", "ko": "こ",
43 | "kya": "きゃ", "kyi": "きぃ", "kyu": "きゅ", "kye": "きぇ", "kyo": "きょ",
44 | // l
45 | "ll": "っl",
46 | "la": "ぁ", "li": "ぃ", "lu": "ぅ", "le": "ぇ", "lo": "ぉ",
47 | "ltu": "っ",
48 | "lya": "ゃ", "lyu": "ゅ", "lyo": "ょ",
49 | "lwa": "ゎ",
50 | // m
51 | "mm": "っm",
52 | "ma": "ま", "mi": "み", "mu": "む", "me": "め", "mo": "も",
53 | "mya": "みゃ", "myi": "みぃ", "myu": "みゅ", "mye": "みぇ", "myo": "みょ",
54 | // n
55 | "nn": "ん",
56 | "na": "な", "ni": "に", "nu": "ぬ", "ne": "ね", "no": "の",
57 | "nya": "にゃ", "nyi": "にぃ", "nyu": "にゅ", "nye": "にぇ", "nyo": "にょ",
58 | "nb": "んb", "nc": "んc", "nd": "んd", "nf": "んf", "ng": "んg",
59 | "nh": "んh", "nj": "んj", "nk": "んk", "nl": "んl", "nm": "んm",
60 | "np": "んp", "nq": "んq", "nr": "んr", "ns": "んs", "nt": "んt",
61 | "nv": "んv", "nw": "んw", "nx": "んx", "nz": "んz",
62 | // p
63 | "pp": "っp",
64 | "pa": "ぱ", "pi": "ぴ", "pu": "ぷ", "pe": "ぺ", "po": "ぽ",
65 | "pya": "ぴゃ", "pyi": "ぴぃ", "pyu": "ぴゅ", "pye": "ぴぇ", "pyo": "ぴょ",
66 | // q
67 | "qq": "っq",
68 | "qa": "くぁ", "qi": "くぃ", "qu": "くぅ", "qe": "くぇ", "qo": "くぉ",
69 | "qya": "くゃ", "qyi": "くぃ", "qyu": "くゅ", "qye": "くぇ", "qyo": "くょ",
70 | // r
71 | "rr": "っr",
72 | "ra": "ら", "ri": "り", "ru": "る", "re": "れ", "ro": "ろ",
73 | "rya": "りゃ", "ryi": "りぃ", "ryu": "りゅ", "rye": "りぇ", "ryo": "りょ",
74 | // s
75 | "ss": "っs",
76 | "sa": "さ", "si": "し", "su": "す", "se": "せ", "so": "そ",
77 | "sha": "しゃ", "shi": "し", "shu": "しゅ", "she": "しぇ", "sho": "しょ",
78 | "sya": "しゃ", "syi": "しぃ", "syu": "しゅ", "sye": "しぇ", "syo": "しょ",
79 | // t
80 | "tt": "っt",
81 | "ta": "た", "ti": "ち", "tu": "つ", "te": "て", "to": "と",
82 | "tha": "てゃ", "thi": "てぃ", "thu": "てゅ", "the": "てぇ", "tho": "てょ",
83 | "tya": "ちゃ", "tyi": "ちぃ", "tyu": "ちゅ", "tye": "ちぇ", "tyo": "ちょ",
84 | // v
85 | "vv": "っv",
86 | "va": "ゔぁ", "vi": "ゔぃ", "vu": "ゔ", "ve": "ゔぇ", "vo": "ゔぉ",
87 | "vya": "ゔゃ", "vyu": "ゔゅ", "vyo": "ゔょ",
88 | // w
89 | "ww": "っw",
90 | "wa": "わ", "wi": "うぃ", "we": "うぇ", "wo": "を",
91 | "wha": "うぁ", "whi": "うぃ", "wu": "う", "whe": "うぇ", "who": "うぉ",
92 | // x
93 | "xx": "っx",
94 | "xa": "ぁ", "xi": "ぃ", "xu": "ぅ", "xe": "ぇ", "xo": "ぉ",
95 | "xtu": "っ",
96 | "xya": "ゃ", "xyu": "ゅ", "xyo": "ょ",
97 | "xwa": "ゎ",
98 | // y
99 | "yy": "っy",
100 | "ya": "や", "yu": "ゆ", "ye": "いぇ", "yo": "よ",
101 | // z
102 | "zz": "っz",
103 | "za": "ざ", "zi": "じ", "zu": "ず", "ze": "ぜ", "zo": "ぞ",
104 | "zya": "じゃ", "zyi": "じぃ", "zyu": "じゅ", "zye": "じぇ", "zyo": "じょ",
105 | // 矢印
106 | "zh": "←", "zj": "↓", "zk": "↑", "zl": "→",
107 | // 記号
108 | "!": "!", "\"": "”", "#": "#", "$": "$", "%": "%",
109 | "&": "&", "'": "’", "(": "(", ")": ")", "*": "*",
110 | "+": "+", ",": "、", "-": "ー", ".": "。", "/": "・",
111 | ":": ":", ";": ";", "<": "<", "=": "=", ">": ">",
112 | "?": "?", "@": "@", "[": "「", "¥": "¥", "]": "」",
113 | "^": "^", "_": "_", "`": "`", "{": "『", "|": "|",
114 | "}": "』", "~": "〜",
115 | // 数字
116 | "0": "0", "1": "1", "2": "2", "3": "3", "4": "4",
117 | "5": "5", "6": "6", "7": "7", "8": "8", "9": "9",
118 | ]
119 |
120 | // NOTE: 変換対象は末尾 3 文字まで
121 | func updateComposingText(_ text: String) -> String {
122 | if text.count == 0 {
123 | return ""
124 | }
125 |
126 | // 末尾 3 文字を変換
127 | let last3 = text.suffix(3)
128 | var prefix = text.prefix(text.count - last3.count)
129 | for (i, char) in last3.enumerated() {
130 | if let suffix = composingTextmap[String(last3.suffix(last3.count - i))] {
131 | return prefix + suffix
132 | }
133 | prefix.append(char)
134 | }
135 |
136 | // 変換できなかった場合はそのまま返す
137 | return text
138 | }
139 |
--------------------------------------------------------------------------------
/NyaIME/Sources/NyaIMEInputController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NyaIMEInputController.swift
3 | // NyaIME
4 | //
5 | // Created by koki sato on 2024/09/06.
6 | //
7 |
8 | import InputMethodKit
9 |
10 | @objc(NyaIMEInputController)
11 | class NyaIMEInputController: IMKInputController {
12 | let appMenu: NSMenu
13 | let candidates: IMKCandidates
14 | var inputState: InputState = .normal
15 | var composingText: String = ""
16 | var selectionText: String = ""
17 |
18 | override init!(server: IMKServer!, delegate: Any!, client inputClient: Any!) {
19 | self.appMenu = NSMenu(title: "NyaIME")
20 | self.appMenu.addItem(
21 | NSMenuItem(
22 | title: "View on GitHub", action: #selector(self.viewOnGitHub(_:)), keyEquivalent: ""
23 | ))
24 |
25 | self.candidates = IMKCandidates(
26 | server: server, panelType: kIMKSingleColumnScrollingCandidatePanel)
27 |
28 | super.init(server: server, delegate: delegate, client: inputClient)
29 | }
30 |
31 | override func menu() -> NSMenu! {
32 | return self.appMenu
33 | }
34 |
35 | override func handle(_ event: NSEvent!, client sender: Any!) -> Bool {
36 | guard let eventType = getEventType(event) else {
37 | return false
38 | }
39 |
40 | switch (eventType, self.inputState) {
41 | case (.input(let text), .selecting):
42 | self.insertText(self.selectionText)
43 | self.candidates.hide()
44 | self.composingText.removeAll()
45 | fallthrough
46 | case (.input(let text), .normal):
47 | self.inputState = .composing
48 | fallthrough
49 | case (.input(let text), .composing):
50 | self.composingText = updateComposingText(self.composingText + text)
51 | self.setMarkedText(self.composingText)
52 | return true
53 |
54 | case (.backspace, .composing):
55 | self.composingText.removeLast()
56 | self.setMarkedText(self.composingText)
57 | return true
58 | case (.backspace, .selecting):
59 | self.insertText(String(self.selectionText.dropLast()))
60 | self.setMarkedText("")
61 | self.candidates.hide()
62 | self.inputState = .normal
63 | self.composingText.removeAll()
64 | return true
65 |
66 | case (.space, .normal):
67 | self.insertText(" ")
68 | return true
69 | case (.space, .composing):
70 | if self.composingText.hasSuffix("n") {
71 | self.composingText.removeLast()
72 | self.composingText.append("ん")
73 | }
74 | self.inputState = .selecting
75 | self.candidates.update()
76 | self.candidates.show()
77 | return true
78 | case (.space, .selecting):
79 | self.candidates.moveDown(sender)
80 | return true
81 |
82 | case (.enter, .composing):
83 | self.insertText(self.composingText)
84 | self.setMarkedText("")
85 | self.composingText.removeAll()
86 | self.inputState = .normal
87 | return true
88 |
89 | case (.esc, .composing):
90 | self.setMarkedText("")
91 | self.composingText.removeAll()
92 | self.inputState = .normal
93 | return true
94 | case (.esc, .selecting):
95 | self.inputState = .composing
96 | self.setMarkedText(self.composingText)
97 | self.candidates.hide()
98 | return true
99 | case (.down, .selecting), (.up, .selecting), (.enter, .selecting):
100 | self.candidates.interpretKeyEvents([event])
101 | return true
102 |
103 | default:
104 | return false
105 | }
106 | }
107 |
108 | override func deactivateServer(_ sender: Any!) {
109 | self.candidates.hide()
110 | self.insertText(self.composingText)
111 | self.setMarkedText("")
112 | self.composingText.removeAll()
113 | self.inputState = .normal
114 | }
115 |
116 | override func candidates(_ sender: Any!) -> [Any]! {
117 | let nya = toNya(self.composingText)
118 | return [
119 | nya.katakanaZenkaku,
120 | nya.hiraganaZenkaku,
121 | nya.katakanaHankaku,
122 | ]
123 | }
124 |
125 | override func candidateSelected(_ candidateString: NSAttributedString!) {
126 | self.insertText(candidateString.string)
127 | self.setMarkedText("")
128 | self.candidates.hide()
129 | self.composingText.removeAll()
130 | self.inputState = .normal
131 | }
132 |
133 | override func candidateSelectionChanged(_ candidateString: NSAttributedString!) {
134 | self.setMarkedText(candidateString.string)
135 | self.selectionText = candidateString.string
136 | }
137 |
138 | func insertText(_ text: String) {
139 | guard let client = client() else {
140 | return
141 | }
142 | client.insertText(text, replacementRange: NSRange(location: NSNotFound, length: NSNotFound))
143 | }
144 |
145 | func setMarkedText(_ text: String) {
146 | guard let client = client() else {
147 | return
148 | }
149 | let cursorPosition = NSRange(location: NSNotFound, length: NSNotFound)
150 |
151 | let highlight =
152 | self.mark(forStyle: kTSMHiliteSelectedConvertedText, at: cursorPosition)
153 | as? [NSAttributedString.Key: Any]
154 | let underline =
155 | self.mark(
156 | forStyle: kTSMHiliteConvertedText,
157 | at: NSRange(location: NSNotFound, length: 0)
158 | ) as? [NSAttributedString.Key: Any]
159 |
160 | let str =
161 | switch self.inputState {
162 | case .selecting:
163 | NSMutableAttributedString(string: text, attributes: highlight)
164 | default:
165 | NSMutableAttributedString(string: text, attributes: underline)
166 | }
167 | client.setMarkedText(str, selectionRange: cursorPosition, replacementRange: cursorPosition)
168 | }
169 |
170 | @objc
171 | func viewOnGitHub(_ sender: Any) {
172 | guard let url = URL(string: "https://github.com/koki-develop/NyaIME") else {
173 | return
174 | }
175 | NSWorkspace.shared.open(url)
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/NyaIME.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 56;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | E762D41E2C8C444900B57AEE /* InputState.swift in Sources */ = {isa = PBXBuildFile; fileRef = E762D41D2C8C444900B57AEE /* InputState.swift */; };
11 | E7636DFB2C8C85C3000F8DCA /* ComposingText.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7636DFA2C8C85C3000F8DCA /* ComposingText.swift */; };
12 | E77E821D2C8DDCF0000AAB69 /* Nya.swift in Sources */ = {isa = PBXBuildFile; fileRef = E77E821C2C8DDCF0000AAB69 /* Nya.swift */; };
13 | E7C8AF7A2C8AEFF9006FE9AA /* NyaIMEApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7C8AF792C8AEFF9006FE9AA /* NyaIMEApp.swift */; };
14 | E7C8AF7E2C8AEFFB006FE9AA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E7C8AF7D2C8AEFFB006FE9AA /* Assets.xcassets */; };
15 | E7C8AF812C8AEFFB006FE9AA /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E7C8AF802C8AEFFB006FE9AA /* Preview Assets.xcassets */; };
16 | E7C8AF8A2C8B2546006FE9AA /* NyaIMEInputController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7C8AF892C8B2546006FE9AA /* NyaIMEInputController.swift */; };
17 | E7C8AF912C8B26FB006FE9AA /* cat.svg in Resources */ = {isa = PBXBuildFile; fileRef = E7C8AF902C8B26FB006FE9AA /* cat.svg */; };
18 | E7CB992E2C8C3BDA001AE329 /* EventType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7CB992D2C8C3BDA001AE329 /* EventType.swift */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXFileReference section */
22 | E762D41D2C8C444900B57AEE /* InputState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputState.swift; sourceTree = ""; };
23 | E7636DFA2C8C85C3000F8DCA /* ComposingText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposingText.swift; sourceTree = ""; };
24 | E77E821C2C8DDCF0000AAB69 /* Nya.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Nya.swift; sourceTree = ""; };
25 | E7C8AF762C8AEFF9006FE9AA /* NyaIME.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NyaIME.app; sourceTree = BUILT_PRODUCTS_DIR; };
26 | E7C8AF792C8AEFF9006FE9AA /* NyaIMEApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NyaIMEApp.swift; sourceTree = ""; };
27 | E7C8AF7D2C8AEFFB006FE9AA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
28 | E7C8AF802C8AEFFB006FE9AA /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
29 | E7C8AF822C8AEFFB006FE9AA /* NyaIME.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NyaIME.entitlements; sourceTree = ""; };
30 | E7C8AF892C8B2546006FE9AA /* NyaIMEInputController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NyaIMEInputController.swift; sourceTree = ""; };
31 | E7C8AF902C8B26FB006FE9AA /* cat.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = cat.svg; sourceTree = ""; };
32 | E7C8AF922C8B2794006FE9AA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
33 | E7CB992D2C8C3BDA001AE329 /* EventType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventType.swift; sourceTree = ""; };
34 | /* End PBXFileReference section */
35 |
36 | /* Begin PBXFrameworksBuildPhase section */
37 | E7C8AF732C8AEFF9006FE9AA /* Frameworks */ = {
38 | isa = PBXFrameworksBuildPhase;
39 | buildActionMask = 2147483647;
40 | files = (
41 | );
42 | runOnlyForDeploymentPostprocessing = 0;
43 | };
44 | /* End PBXFrameworksBuildPhase section */
45 |
46 | /* Begin PBXGroup section */
47 | E7C8AF6D2C8AEFF9006FE9AA = {
48 | isa = PBXGroup;
49 | children = (
50 | E7C8AF782C8AEFF9006FE9AA /* NyaIME */,
51 | E7C8AF772C8AEFF9006FE9AA /* Products */,
52 | );
53 | sourceTree = "";
54 | };
55 | E7C8AF772C8AEFF9006FE9AA /* Products */ = {
56 | isa = PBXGroup;
57 | children = (
58 | E7C8AF762C8AEFF9006FE9AA /* NyaIME.app */,
59 | );
60 | name = Products;
61 | sourceTree = "";
62 | };
63 | E7C8AF782C8AEFF9006FE9AA /* NyaIME */ = {
64 | isa = PBXGroup;
65 | children = (
66 | E7C8AF922C8B2794006FE9AA /* Info.plist */,
67 | E7C8AF8F2C8B26EA006FE9AA /* Resources */,
68 | E7C8AF882C8AF0E4006FE9AA /* Sources */,
69 | E7C8AF7D2C8AEFFB006FE9AA /* Assets.xcassets */,
70 | E7C8AF822C8AEFFB006FE9AA /* NyaIME.entitlements */,
71 | E7C8AF7F2C8AEFFB006FE9AA /* Preview Content */,
72 | );
73 | path = NyaIME;
74 | sourceTree = "";
75 | };
76 | E7C8AF7F2C8AEFFB006FE9AA /* Preview Content */ = {
77 | isa = PBXGroup;
78 | children = (
79 | E7C8AF802C8AEFFB006FE9AA /* Preview Assets.xcassets */,
80 | );
81 | path = "Preview Content";
82 | sourceTree = "";
83 | };
84 | E7C8AF882C8AF0E4006FE9AA /* Sources */ = {
85 | isa = PBXGroup;
86 | children = (
87 | E7C8AF792C8AEFF9006FE9AA /* NyaIMEApp.swift */,
88 | E7C8AF892C8B2546006FE9AA /* NyaIMEInputController.swift */,
89 | E7CB992D2C8C3BDA001AE329 /* EventType.swift */,
90 | E762D41D2C8C444900B57AEE /* InputState.swift */,
91 | E7636DFA2C8C85C3000F8DCA /* ComposingText.swift */,
92 | E77E821C2C8DDCF0000AAB69 /* Nya.swift */,
93 | );
94 | path = Sources;
95 | sourceTree = "";
96 | };
97 | E7C8AF8F2C8B26EA006FE9AA /* Resources */ = {
98 | isa = PBXGroup;
99 | children = (
100 | E7C8AF902C8B26FB006FE9AA /* cat.svg */,
101 | );
102 | path = Resources;
103 | sourceTree = "";
104 | };
105 | /* End PBXGroup section */
106 |
107 | /* Begin PBXNativeTarget section */
108 | E7C8AF752C8AEFF9006FE9AA /* NyaIME */ = {
109 | isa = PBXNativeTarget;
110 | buildConfigurationList = E7C8AF852C8AEFFB006FE9AA /* Build configuration list for PBXNativeTarget "NyaIME" */;
111 | buildPhases = (
112 | E7C8AF722C8AEFF9006FE9AA /* Sources */,
113 | E7C8AF732C8AEFF9006FE9AA /* Frameworks */,
114 | E7C8AF742C8AEFF9006FE9AA /* Resources */,
115 | );
116 | buildRules = (
117 | );
118 | dependencies = (
119 | );
120 | name = NyaIME;
121 | productName = NyaIME;
122 | productReference = E7C8AF762C8AEFF9006FE9AA /* NyaIME.app */;
123 | productType = "com.apple.product-type.application";
124 | };
125 | /* End PBXNativeTarget section */
126 |
127 | /* Begin PBXProject section */
128 | E7C8AF6E2C8AEFF9006FE9AA /* Project object */ = {
129 | isa = PBXProject;
130 | attributes = {
131 | BuildIndependentTargetsInParallel = 1;
132 | LastSwiftUpdateCheck = 1430;
133 | LastUpgradeCheck = 1540;
134 | TargetAttributes = {
135 | E7C8AF752C8AEFF9006FE9AA = {
136 | CreatedOnToolsVersion = 14.3;
137 | };
138 | };
139 | };
140 | buildConfigurationList = E7C8AF712C8AEFF9006FE9AA /* Build configuration list for PBXProject "NyaIME" */;
141 | compatibilityVersion = "Xcode 14.0";
142 | developmentRegion = en;
143 | hasScannedForEncodings = 0;
144 | knownRegions = (
145 | en,
146 | Base,
147 | );
148 | mainGroup = E7C8AF6D2C8AEFF9006FE9AA;
149 | productRefGroup = E7C8AF772C8AEFF9006FE9AA /* Products */;
150 | projectDirPath = "";
151 | projectRoot = "";
152 | targets = (
153 | E7C8AF752C8AEFF9006FE9AA /* NyaIME */,
154 | );
155 | };
156 | /* End PBXProject section */
157 |
158 | /* Begin PBXResourcesBuildPhase section */
159 | E7C8AF742C8AEFF9006FE9AA /* Resources */ = {
160 | isa = PBXResourcesBuildPhase;
161 | buildActionMask = 2147483647;
162 | files = (
163 | E7C8AF912C8B26FB006FE9AA /* cat.svg in Resources */,
164 | E7C8AF812C8AEFFB006FE9AA /* Preview Assets.xcassets in Resources */,
165 | E7C8AF7E2C8AEFFB006FE9AA /* Assets.xcassets in Resources */,
166 | );
167 | runOnlyForDeploymentPostprocessing = 0;
168 | };
169 | /* End PBXResourcesBuildPhase section */
170 |
171 | /* Begin PBXSourcesBuildPhase section */
172 | E7C8AF722C8AEFF9006FE9AA /* Sources */ = {
173 | isa = PBXSourcesBuildPhase;
174 | buildActionMask = 2147483647;
175 | files = (
176 | E7C8AF7A2C8AEFF9006FE9AA /* NyaIMEApp.swift in Sources */,
177 | E7636DFB2C8C85C3000F8DCA /* ComposingText.swift in Sources */,
178 | E762D41E2C8C444900B57AEE /* InputState.swift in Sources */,
179 | E7CB992E2C8C3BDA001AE329 /* EventType.swift in Sources */,
180 | E77E821D2C8DDCF0000AAB69 /* Nya.swift in Sources */,
181 | E7C8AF8A2C8B2546006FE9AA /* NyaIMEInputController.swift in Sources */,
182 | );
183 | runOnlyForDeploymentPostprocessing = 0;
184 | };
185 | /* End PBXSourcesBuildPhase section */
186 |
187 | /* Begin XCBuildConfiguration section */
188 | E7C8AF832C8AEFFB006FE9AA /* Debug */ = {
189 | isa = XCBuildConfiguration;
190 | buildSettings = {
191 | ALWAYS_SEARCH_USER_PATHS = NO;
192 | CLANG_ANALYZER_NONNULL = YES;
193 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
194 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
195 | CLANG_ENABLE_MODULES = YES;
196 | CLANG_ENABLE_OBJC_ARC = YES;
197 | CLANG_ENABLE_OBJC_WEAK = YES;
198 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
199 | CLANG_WARN_BOOL_CONVERSION = YES;
200 | CLANG_WARN_COMMA = YES;
201 | CLANG_WARN_CONSTANT_CONVERSION = YES;
202 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
203 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
204 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
205 | CLANG_WARN_EMPTY_BODY = YES;
206 | CLANG_WARN_ENUM_CONVERSION = YES;
207 | CLANG_WARN_INFINITE_RECURSION = YES;
208 | CLANG_WARN_INT_CONVERSION = YES;
209 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
210 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
211 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
212 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
213 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
214 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
215 | CLANG_WARN_STRICT_PROTOTYPES = YES;
216 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
217 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
218 | CLANG_WARN_UNREACHABLE_CODE = YES;
219 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
220 | COPY_PHASE_STRIP = NO;
221 | DEAD_CODE_STRIPPING = YES;
222 | DEBUG_INFORMATION_FORMAT = dwarf;
223 | ENABLE_STRICT_OBJC_MSGSEND = YES;
224 | ENABLE_TESTABILITY = YES;
225 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
226 | GCC_C_LANGUAGE_STANDARD = gnu11;
227 | GCC_DYNAMIC_NO_PIC = NO;
228 | GCC_NO_COMMON_BLOCKS = YES;
229 | GCC_OPTIMIZATION_LEVEL = 0;
230 | GCC_PREPROCESSOR_DEFINITIONS = (
231 | "DEBUG=1",
232 | "$(inherited)",
233 | );
234 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
235 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
236 | GCC_WARN_UNDECLARED_SELECTOR = YES;
237 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
238 | GCC_WARN_UNUSED_FUNCTION = YES;
239 | GCC_WARN_UNUSED_VARIABLE = YES;
240 | MACOSX_DEPLOYMENT_TARGET = 13.3;
241 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
242 | MTL_FAST_MATH = YES;
243 | ONLY_ACTIVE_ARCH = YES;
244 | SDKROOT = macosx;
245 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
246 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
247 | };
248 | name = Debug;
249 | };
250 | E7C8AF842C8AEFFB006FE9AA /* Release */ = {
251 | isa = XCBuildConfiguration;
252 | buildSettings = {
253 | ALWAYS_SEARCH_USER_PATHS = NO;
254 | CLANG_ANALYZER_NONNULL = YES;
255 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
256 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
257 | CLANG_ENABLE_MODULES = YES;
258 | CLANG_ENABLE_OBJC_ARC = YES;
259 | CLANG_ENABLE_OBJC_WEAK = YES;
260 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
261 | CLANG_WARN_BOOL_CONVERSION = YES;
262 | CLANG_WARN_COMMA = YES;
263 | CLANG_WARN_CONSTANT_CONVERSION = YES;
264 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
265 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
266 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
267 | CLANG_WARN_EMPTY_BODY = YES;
268 | CLANG_WARN_ENUM_CONVERSION = YES;
269 | CLANG_WARN_INFINITE_RECURSION = YES;
270 | CLANG_WARN_INT_CONVERSION = YES;
271 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
272 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
273 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
274 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
275 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
276 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
277 | CLANG_WARN_STRICT_PROTOTYPES = YES;
278 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
279 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
280 | CLANG_WARN_UNREACHABLE_CODE = YES;
281 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
282 | COPY_PHASE_STRIP = NO;
283 | DEAD_CODE_STRIPPING = YES;
284 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
285 | ENABLE_NS_ASSERTIONS = NO;
286 | ENABLE_STRICT_OBJC_MSGSEND = YES;
287 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
288 | GCC_C_LANGUAGE_STANDARD = gnu11;
289 | GCC_NO_COMMON_BLOCKS = YES;
290 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
291 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
292 | GCC_WARN_UNDECLARED_SELECTOR = YES;
293 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
294 | GCC_WARN_UNUSED_FUNCTION = YES;
295 | GCC_WARN_UNUSED_VARIABLE = YES;
296 | MACOSX_DEPLOYMENT_TARGET = 13.3;
297 | MTL_ENABLE_DEBUG_INFO = NO;
298 | MTL_FAST_MATH = YES;
299 | SDKROOT = macosx;
300 | SWIFT_COMPILATION_MODE = wholemodule;
301 | SWIFT_OPTIMIZATION_LEVEL = "-O";
302 | };
303 | name = Release;
304 | };
305 | E7C8AF862C8AEFFB006FE9AA /* Debug */ = {
306 | isa = XCBuildConfiguration;
307 | buildSettings = {
308 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
309 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
310 | CODE_SIGN_ENTITLEMENTS = NyaIME/NyaIME.entitlements;
311 | CODE_SIGN_STYLE = Automatic;
312 | COMBINE_HIDPI_IMAGES = YES;
313 | CURRENT_PROJECT_VERSION = 1;
314 | DEAD_CODE_STRIPPING = YES;
315 | DEVELOPMENT_ASSET_PATHS = "\"NyaIME/Preview Content\"";
316 | DEVELOPMENT_TEAM = 39PPNBH292;
317 | ENABLE_HARDENED_RUNTIME = YES;
318 | ENABLE_PREVIEWS = YES;
319 | GENERATE_INFOPLIST_FILE = YES;
320 | INFOPLIST_FILE = NyaIME/Info.plist;
321 | INFOPLIST_KEY_LSBackgroundOnly = YES;
322 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
323 | INFOPLIST_KEY_NSPrincipalClass = "$(PRODUCT_MODULE_NAME).NSManualApplication";
324 | LD_RUNPATH_SEARCH_PATHS = (
325 | "$(inherited)",
326 | "@executable_path/../Frameworks",
327 | );
328 | MARKETING_VERSION = 1.0;
329 | PRODUCT_BUNDLE_IDENTIFIER = me.koki.inputmethod.NyaIME;
330 | PRODUCT_NAME = "$(TARGET_NAME)";
331 | SWIFT_EMIT_LOC_STRINGS = YES;
332 | SWIFT_VERSION = 5.0;
333 | };
334 | name = Debug;
335 | };
336 | E7C8AF872C8AEFFB006FE9AA /* Release */ = {
337 | isa = XCBuildConfiguration;
338 | buildSettings = {
339 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
340 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
341 | CODE_SIGN_ENTITLEMENTS = NyaIME/NyaIME.entitlements;
342 | CODE_SIGN_STYLE = Automatic;
343 | COMBINE_HIDPI_IMAGES = YES;
344 | CURRENT_PROJECT_VERSION = 1;
345 | DEAD_CODE_STRIPPING = YES;
346 | DEVELOPMENT_ASSET_PATHS = "\"NyaIME/Preview Content\"";
347 | DEVELOPMENT_TEAM = 39PPNBH292;
348 | ENABLE_HARDENED_RUNTIME = YES;
349 | ENABLE_PREVIEWS = YES;
350 | GENERATE_INFOPLIST_FILE = YES;
351 | INFOPLIST_FILE = NyaIME/Info.plist;
352 | INFOPLIST_KEY_LSBackgroundOnly = YES;
353 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
354 | INFOPLIST_KEY_NSPrincipalClass = "$(PRODUCT_MODULE_NAME).NSManualApplication";
355 | LD_RUNPATH_SEARCH_PATHS = (
356 | "$(inherited)",
357 | "@executable_path/../Frameworks",
358 | );
359 | MARKETING_VERSION = 1.0;
360 | PRODUCT_BUNDLE_IDENTIFIER = me.koki.inputmethod.NyaIME;
361 | PRODUCT_NAME = "$(TARGET_NAME)";
362 | SWIFT_EMIT_LOC_STRINGS = YES;
363 | SWIFT_VERSION = 5.0;
364 | };
365 | name = Release;
366 | };
367 | /* End XCBuildConfiguration section */
368 |
369 | /* Begin XCConfigurationList section */
370 | E7C8AF712C8AEFF9006FE9AA /* Build configuration list for PBXProject "NyaIME" */ = {
371 | isa = XCConfigurationList;
372 | buildConfigurations = (
373 | E7C8AF832C8AEFFB006FE9AA /* Debug */,
374 | E7C8AF842C8AEFFB006FE9AA /* Release */,
375 | );
376 | defaultConfigurationIsVisible = 0;
377 | defaultConfigurationName = Release;
378 | };
379 | E7C8AF852C8AEFFB006FE9AA /* Build configuration list for PBXNativeTarget "NyaIME" */ = {
380 | isa = XCConfigurationList;
381 | buildConfigurations = (
382 | E7C8AF862C8AEFFB006FE9AA /* Debug */,
383 | E7C8AF872C8AEFFB006FE9AA /* Release */,
384 | );
385 | defaultConfigurationIsVisible = 0;
386 | defaultConfigurationName = Release;
387 | };
388 | /* End XCConfigurationList section */
389 | };
390 | rootObject = E7C8AF6E2C8AEFF9006FE9AA /* Project object */;
391 | }
392 |
--------------------------------------------------------------------------------