Move CharacterInfo to swift package

This commit is contained in:
1024jp 2024-06-13 21:19:29 +09:00
parent 0a31a59e89
commit f006bce09d
32 changed files with 480 additions and 416 deletions

View File

@ -37,7 +37,6 @@ opt_in_rules:
- legacy_multiple
- let_var_whitespace
- lower_acl_than_parent
- missing_docs
- multiline_function_chains
- multiline_parameters
- multiline_parameters_brackets

View File

@ -43,7 +43,7 @@ Currently, the CotEditor project only accepts new localizations whose provider c
You have two options to add a new localization to CotEditor.app. Choose one of them depending on your knowledge and preference:
- Option 1: Add a new localization in Xcode by yourself and make a pull-request (for those who get used to git and Xcode projects):
- Open CotEditor.xcodeproj in Xcode, go to Project > CotEditor > Info > Localizations, and then add your language to the table. In the Resources group in the project, you can find all strings files (.xcstrings) both in the Localizations and Storyboards subgroups. The new language you added will automatically be appeared in the catalog list. Select your language and fill each cell of your language column in the table. Note that you don't need to localize the UnicodeBlock.strings file. It will be done by @1024jp based on the localization data by Apple.
- Open CotEditor.xcodeproj in Xcode, go to Project > CotEditor > Info > Localizations, and then add your language to the table. In the Resources group in the project, you can find all strings files (.xcstrings) both in the Localizations and Storyboards subgroups. The new language you added will automatically be appeared in the catalog list. Select your language and fill each cell of your language column in the table. Note that you don't need to localize the UnicodeBlock.strings file in Packages/Libraries/Sources/CharacterInfo/. It will be done by @1024jp based on the localization data by Apple.
- CotEditor currently uses the String Catalog format (.xcstrings) first introduced in Xcode 15 released in 2023. cf. [Localizing and varying text with a string catalog](https://developer.apple.com/documentation/xcode/localizing-and-varying-text-with-a-string-catalog)
- Option 2: Communicate with the maintainer personally and work with provided localization template (.xcloc file):
- Send a message to the maintainer (@1024jp) either by creating a new issue on GitHub or by e-mail to ask to get the localization template (.xcloc file) for your language. When you receiving the .xcloc file, open it in Xcode and fill each cell of your language column in the tables. When finished, send back the template file to the maintainer.

View File

@ -64,8 +64,6 @@
2A1125C723F6EFB2006A1DB2 /* URLDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1125C523F6EFB2006A1DB2 /* URLDetector.swift */; };
2A11F2131E669BFA005E1675 /* PointerBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A11F2121E669BFA005E1675 /* PointerBridge.swift */; };
2A11F2141E669BFA005E1675 /* PointerBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A11F2121E669BFA005E1675 /* PointerBridge.swift */; };
2A1235462121B106002E9C53 /* Unicode.UTF32.CodeUnit+BlockName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1235452121B106002E9C53 /* Unicode.UTF32.CodeUnit+BlockName.swift */; };
2A1235472121B106002E9C53 /* Unicode.UTF32.CodeUnit+BlockName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1235452121B106002E9C53 /* Unicode.UTF32.CodeUnit+BlockName.swift */; };
2A1311D62127DCE1001D52C5 /* NSTextView+CurrentLineHighlighting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1311D52127DCE1001D52C5 /* NSTextView+CurrentLineHighlighting.swift */; };
2A1311D72127DCE1001D52C5 /* NSTextView+CurrentLineHighlighting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1311D52127DCE1001D52C5 /* NSTextView+CurrentLineHighlighting.swift */; };
2A158C1C2945A6B1000A4EC1 /* HeadingMenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A158C1B2945A6B1000A4EC1 /* HeadingMenuItem.swift */; };
@ -413,10 +411,6 @@
2A72DA11209B778B005242B9 /* NSTextView+MultiCursor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A72DA0F209B778B005242B9 /* NSTextView+MultiCursor.swift */; };
2A733E8920BBB4AC0090D7CB /* String+Case.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A733E8820BBB4AC0090D7CB /* String+Case.swift */; };
2A733E8A20BBB4AC0090D7CB /* String+Case.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A733E8820BBB4AC0090D7CB /* String+Case.swift */; };
2A73B5B61D4675350025337F /* Unicode.Scalar+ControlCharacter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A73B5B31D4675350025337F /* Unicode.Scalar+ControlCharacter.swift */; };
2A73B5B71D4675350025337F /* Unicode.Scalar+ControlCharacter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A73B5B31D4675350025337F /* Unicode.Scalar+ControlCharacter.swift */; };
2A73B5BC1D468DD30025337F /* Unicode.Scalar+Information.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A73B5BB1D468DD30025337F /* Unicode.Scalar+Information.swift */; };
2A73B5BD1D468DD30025337F /* Unicode.Scalar+Information.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A73B5BB1D468DD30025337F /* Unicode.Scalar+Information.swift */; };
2A73B9332A8F6620002F3A16 /* RegexTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A73B9322A8F6620002F3A16 /* RegexTextField.swift */; };
2A73B9342A8F6620002F3A16 /* RegexTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A73B9322A8F6620002F3A16 /* RegexTextField.swift */; };
2A7470692B12FA5700669A7B /* NSTextStorage+TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A7470682B12FA5700669A7B /* NSTextStorage+TextView.swift */; };
@ -436,14 +430,14 @@
2A7B279924E435FE00F02304 /* OutlineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A7B279824E435FE00F02304 /* OutlineTests.swift */; };
2A7C92FC29FD64A8008343C8 /* DefaultKey+FontType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A7C92FB29FD64A8008343C8 /* DefaultKey+FontType.swift */; };
2A7C92FD29FD64A8008343C8 /* DefaultKey+FontType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A7C92FB29FD64A8008343C8 /* DefaultKey+FontType.swift */; };
2A7E06E82C1A745400E5396D /* CharacterInfo in Frameworks */ = {isa = PBXBuildFile; productRef = 2A7E06E72C1A745400E5396D /* CharacterInfo */; };
2A7E06EA2C1A745E00E5396D /* CharacterInfo in Frameworks */ = {isa = PBXBuildFile; productRef = 2A7E06E92C1A745E00E5396D /* CharacterInfo */; };
2A7F4DFF2871F46D0029CE66 /* PrintPanelAccessory.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A7F4E022871F46D0029CE66 /* PrintPanelAccessory.storyboard */; };
2A7F4E002871F46D0029CE66 /* PrintPanelAccessory.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A7F4E022871F46D0029CE66 /* PrintPanelAccessory.storyboard */; };
2A7FCC46280A367C0070EAB3 /* ValueRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A7FCC45280A367C0070EAB3 /* ValueRange.swift */; };
2A7FCC47280A367C0070EAB3 /* ValueRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A7FCC45280A367C0070EAB3 /* ValueRange.swift */; };
2A7FEF0B2B90B05C0042BEFF /* FilterField.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 2A7FEF0A2B90B05C0042BEFF /* FilterField.xcstrings */; };
2A7FEF0C2B90B05C0042BEFF /* FilterField.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 2A7FEF0A2B90B05C0042BEFF /* FilterField.xcstrings */; };
2A7FEF332B90E1C20042BEFF /* Character.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 2A7FEF322B90E1C20042BEFF /* Character.xcstrings */; };
2A7FEF342B90E1C20042BEFF /* Character.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 2A7FEF322B90E1C20042BEFF /* Character.xcstrings */; };
2A80BE8D27FFA61700D2F7FF /* LineEndingScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A80BE8C27FFA61700D2F7FF /* LineEndingScanner.swift */; };
2A80BE8E27FFA61700D2F7FF /* LineEndingScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A80BE8C27FFA61700D2F7FF /* LineEndingScanner.swift */; };
2A80BE9227FFFA8900D2F7FF /* LineEndingScannerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A80BE8F27FFFA8900D2F7FF /* LineEndingScannerTests.swift */; };
@ -542,9 +536,6 @@
2AA175FB2AC5634500F6462C /* PopoverHolderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA175F92AC5634500F6462C /* PopoverHolderView.swift */; };
2AA2C6FC24399A920017D1EC /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = 2AA2C6FB24399A920017D1EC /* Yams */; };
2AA2C6FE24399AA20017D1EC /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = 2AA2C6FD24399AA20017D1EC /* Yams */; };
2AA2E0101BFDE0190087BDD6 /* CharacterInfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA2E00F1BFDE0190087BDD6 /* CharacterInfoTests.swift */; };
2AA2E0131BFE12620087BDD6 /* UnicodeBlock.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2AA2E0111BFE12620087BDD6 /* UnicodeBlock.strings */; };
2AA2E0141BFE12620087BDD6 /* UnicodeBlock.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2AA2E0111BFE12620087BDD6 /* UnicodeBlock.strings */; };
2AA2E0261C0454730087BDD6 /* StringIndentationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA2E0251C0454730087BDD6 /* StringIndentationTests.swift */; };
2AA375441D403F100080C27C /* String+Encoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A4D69261D3FF61C00FBBD0B /* String+Encoding.swift */; };
2AA375451D403F110080C27C /* String+Encoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A4D69261D3FF61C00FBBD0B /* String+Encoding.swift */; };
@ -630,8 +621,6 @@
2AB1BD20287D747200C6FEAF /* SizeGetter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB1BD1E287D747200C6FEAF /* SizeGetter.swift */; };
2AB1BD24287DA73D00C6FEAF /* CharacterCountOptionsSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB1BD23287DA73D00C6FEAF /* CharacterCountOptionsSheetView.swift */; };
2AB1BD25287DA73D00C6FEAF /* CharacterCountOptionsSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB1BD23287DA73D00C6FEAF /* CharacterCountOptionsSheetView.swift */; };
2AB2913E245AAD74004CC203 /* Unicode.GeneralCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB2913D245AAD74004CC203 /* Unicode.GeneralCategory.swift */; };
2AB2913F245AAD74004CC203 /* Unicode.GeneralCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB2913D245AAD74004CC203 /* Unicode.GeneralCategory.swift */; };
2AB541DA20A5B6A400367DD5 /* NSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB541D920A5B6A400367DD5 /* NSView.swift */; };
2AB541DB20A5B6A400367DD5 /* NSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB541D920A5B6A400367DD5 /* NSView.swift */; };
2AB857E82B922D7D0079CFA2 /* ModeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB857E72B922D7D0079CFA2 /* ModeManager.swift */; };
@ -811,8 +800,6 @@
2AEE84B31E8158D700BA7982 /* WriteToConsoleCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AEE84B11E8158D700BA7982 /* WriteToConsoleCommand.swift */; };
2AF073E31D33C3AB00770BA6 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF073E21D33C3AB00770BA6 /* Theme.swift */; };
2AF073E41D33C3AB00770BA6 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF073E21D33C3AB00770BA6 /* Theme.swift */; };
2AF073FB1D34587500770BA6 /* CharacterInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF073FA1D34587500770BA6 /* CharacterInfo.swift */; };
2AF073FC1D34587500770BA6 /* CharacterInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF073FA1D34587500770BA6 /* CharacterInfo.swift */; };
2AF0C1251D3DA44900B6FCB6 /* FourCharCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF0C1241D3DA44900B6FCB6 /* FourCharCode.swift */; };
2AF0C1261D3DA44900B6FCB6 /* FourCharCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF0C1241D3DA44900B6FCB6 /* FourCharCode.swift */; };
2AF0C1281D3DA6F800B6FCB6 /* FourCharCodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF0C1271D3DA6F800B6FCB6 /* FourCharCodeTests.swift */; };
@ -896,8 +883,6 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
08C28FB2279CBE530016693E /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/UnicodeBlock.strings; sourceTree = "<group>"; };
0D51D5922274EF5300A5D747 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/UnicodeBlock.strings; sourceTree = "<group>"; };
2A04E9BA27FD6911008C82D8 /* SnippetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnippetTests.swift; sourceTree = "<group>"; };
2A05081223D6B9E900602F5E /* NSViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSViewController.swift; sourceTree = "<group>"; };
2A0778602072040500876277 /* RegularExpressionSyntaxType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegularExpressionSyntaxType.swift; sourceTree = "<group>"; };
@ -921,7 +906,6 @@
2A1125C223F1A86B006A1DB2 /* LineRangeCacheable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineRangeCacheable.swift; sourceTree = "<group>"; };
2A1125C523F6EFB2006A1DB2 /* URLDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLDetector.swift; sourceTree = "<group>"; };
2A11F2121E669BFA005E1675 /* PointerBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PointerBridge.swift; sourceTree = "<group>"; };
2A1235452121B106002E9C53 /* Unicode.UTF32.CodeUnit+BlockName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Unicode.UTF32.CodeUnit+BlockName.swift"; sourceTree = "<group>"; };
2A1311D52127DCE1001D52C5 /* NSTextView+CurrentLineHighlighting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextView+CurrentLineHighlighting.swift"; sourceTree = "<group>"; };
2A158C1B2945A6B1000A4EC1 /* HeadingMenuItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadingMenuItem.swift; sourceTree = "<group>"; };
2A158C1E2945E423000A4EC1 /* SavePanelAccessory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavePanelAccessory.swift; sourceTree = "<group>"; };
@ -1016,7 +1000,6 @@
2A3F18F7203270BE002F1CA7 /* UI Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "UI Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
2A3F18F9203270BE002F1CA7 /* UITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITests.swift; sourceTree = "<group>"; };
2A3F8F672429E04000CBBA89 /* DebouncerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebouncerTests.swift; sourceTree = "<group>"; };
2A401FE81D9AF7CA00ACE036 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/UnicodeBlock.strings; sourceTree = "<group>"; };
2A40D2892AA8AEF000402373 /* FindPanelOptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FindPanelOptionView.swift; sourceTree = "<group>"; };
2A41EC191DC4AD4A00F0C236 /* EditorTextView+TouchBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "EditorTextView+TouchBar.swift"; sourceTree = "<group>"; };
2A4257A61D22E0660086DAAD /* EncodingManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EncodingManager.swift; sourceTree = "<group>"; };
@ -1040,7 +1023,6 @@
2A4E637F20ADC45F0033CE63 /* NSBezierPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSBezierPath.swift; sourceTree = "<group>"; };
2A505C042988D44E002080AA /* ShortcutFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutFormatter.swift; sourceTree = "<group>"; };
2A50AA61204D513500D10A10 /* DocumentFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentFile.swift; sourceTree = "<group>"; };
2A51CF402BB45940001896F1 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/UnicodeBlock.strings; sourceTree = "<group>"; };
2A53F56627585A0E00ED16DF /* RegularExpressionReferenceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegularExpressionReferenceView.swift; sourceTree = "<group>"; };
2A54BE2B1D40EB24000816B0 /* LineEndingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineEndingTests.swift; sourceTree = "<group>"; };
2A55D5D72B7A728A0092DE48 /* AdvancedCharacterCount.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = AdvancedCharacterCount.xcstrings; sourceTree = "<group>"; };
@ -1116,8 +1098,6 @@
2A71BC7D1DDC70A80085AE1C /* NSImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSImage.swift; sourceTree = "<group>"; };
2A72DA0F209B778B005242B9 /* NSTextView+MultiCursor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextView+MultiCursor.swift"; sourceTree = "<group>"; };
2A733E8820BBB4AC0090D7CB /* String+Case.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Case.swift"; sourceTree = "<group>"; };
2A73B5B31D4675350025337F /* Unicode.Scalar+ControlCharacter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Unicode.Scalar+ControlCharacter.swift"; sourceTree = "<group>"; };
2A73B5BB1D468DD30025337F /* Unicode.Scalar+Information.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Unicode.Scalar+Information.swift"; sourceTree = "<group>"; };
2A73B9322A8F6620002F3A16 /* RegexTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegexTextField.swift; sourceTree = "<group>"; };
2A7470682B12FA5700669A7B /* NSTextStorage+TextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextStorage+TextView.swift"; sourceTree = "<group>"; };
2A75ACCA19E86DDB00444894 /* CotEditor.sdef */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = CotEditor.sdef; sourceTree = "<group>"; };
@ -1130,10 +1110,10 @@
2A78BFBB1D1B376000A583D2 /* ServicesProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServicesProvider.swift; sourceTree = "<group>"; };
2A7B279824E435FE00F02304 /* OutlineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutlineTests.swift; sourceTree = "<group>"; };
2A7C92FB29FD64A8008343C8 /* DefaultKey+FontType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DefaultKey+FontType.swift"; sourceTree = "<group>"; };
2A7E06E52C1A711B00E5396D /* Libraries */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Libraries; sourceTree = "<group>"; };
2A7F4E012871F46D0029CE66 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/PrintPanelAccessory.storyboard; sourceTree = "<group>"; };
2A7FCC45280A367C0070EAB3 /* ValueRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValueRange.swift; sourceTree = "<group>"; };
2A7FEF0A2B90B05C0042BEFF /* FilterField.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = FilterField.xcstrings; sourceTree = "<group>"; };
2A7FEF322B90E1C20042BEFF /* Character.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Character.xcstrings; sourceTree = "<group>"; };
2A80BE8C27FFA61700D2F7FF /* LineEndingScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineEndingScanner.swift; sourceTree = "<group>"; };
2A80BE8F27FFFA8900D2F7FF /* LineEndingScannerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineEndingScannerTests.swift; sourceTree = "<group>"; };
2A8321732980C41600F87D35 /* Image+Status.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Image+Status.swift"; sourceTree = "<group>"; };
@ -1187,10 +1167,6 @@
2AA14CFE1FA498E900EAF586 /* UnixScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnixScript.swift; sourceTree = "<group>"; };
2AA14D011FA4999200EAF586 /* PersistentOSAScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistentOSAScript.swift; sourceTree = "<group>"; };
2AA175F92AC5634500F6462C /* PopoverHolderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopoverHolderView.swift; sourceTree = "<group>"; };
2AA2E00F1BFDE0190087BDD6 /* CharacterInfoTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CharacterInfoTests.swift; sourceTree = "<group>"; };
2AA2E0121BFE12620087BDD6 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/UnicodeBlock.strings; sourceTree = "<group>"; };
2AA2E0151BFE14310087BDD6 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/UnicodeBlock.strings"; sourceTree = "<group>"; };
2AA2E0161BFE14320087BDD6 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/UnicodeBlock.strings; sourceTree = "<group>"; };
2AA2E0251C0454730087BDD6 /* StringIndentationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringIndentationTests.swift; sourceTree = "<group>"; };
2AA375461D40BDCB0080C27C /* LineEnding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineEnding.swift; sourceTree = "<group>"; };
2AA45A4A1D2E871900A1A401 /* EditorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditorViewController.swift; sourceTree = "<group>"; };
@ -1236,7 +1212,6 @@
2AB1BD1B287D60DF00C6FEAF /* CharacterCountOptionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCountOptionsView.swift; sourceTree = "<group>"; };
2AB1BD1E287D747200C6FEAF /* SizeGetter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SizeGetter.swift; sourceTree = "<group>"; };
2AB1BD23287DA73D00C6FEAF /* CharacterCountOptionsSheetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCountOptionsSheetView.swift; sourceTree = "<group>"; };
2AB2913D245AAD74004CC203 /* Unicode.GeneralCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Unicode.GeneralCategory.swift; sourceTree = "<group>"; };
2AB541D920A5B6A400367DD5 /* NSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSView.swift; sourceTree = "<group>"; };
2AB857E72B922D7D0079CFA2 /* ModeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModeManager.swift; sourceTree = "<group>"; };
2AB857EA2B93050E0079CFA2 /* ModeOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModeOptions.swift; sourceTree = "<group>"; };
@ -1253,9 +1228,7 @@
2AC186DC1E2F4264002F4D27 /* Debug.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Debug.swift; sourceTree = "<group>"; };
2AC2462D1D1BC70C00E46CFA /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
2AC39F721E8AC80E009F97D5 /* CollectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionTests.swift; sourceTree = "<group>"; };
2AC4E5D127A6C0300052A4DD /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/UnicodeBlock.strings"; sourceTree = "<group>"; };
2AC52BDA1D48CC0E007D6371 /* DispatchQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DispatchQueue.swift; sourceTree = "<group>"; };
2AC605AE2B64CDE300E93E5B /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/UnicodeBlock.strings; sourceTree = "<group>"; };
2AC6069A20416ADE00F9C839 /* OpenPanelAccessory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenPanelAccessory.swift; sourceTree = "<group>"; };
2AC6BFD021D00ABD00FF325C /* NSTextView+RegexParse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextView+RegexParse.swift"; sourceTree = "<group>"; };
2AC7044724EBB76B00454706 /* NSToolbarItem+Validatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSToolbarItem+Validatable.swift"; sourceTree = "<group>"; };
@ -1330,7 +1303,6 @@
2AED70ED1D2E36EF006FFBCE /* DocumentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DocumentViewController.swift; sourceTree = "<group>"; };
2AEE84B11E8158D700BA7982 /* WriteToConsoleCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WriteToConsoleCommand.swift; sourceTree = "<group>"; };
2AF073E21D33C3AB00770BA6 /* Theme.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
2AF073FA1D34587500770BA6 /* CharacterInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CharacterInfo.swift; sourceTree = "<group>"; };
2AF0C1241D3DA44900B6FCB6 /* FourCharCode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FourCharCode.swift; sourceTree = "<group>"; };
2AF0C1271D3DA6F800B6FCB6 /* FourCharCodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FourCharCodeTests.swift; sourceTree = "<group>"; };
2AF0C12C1D3DABD000B6FCB6 /* Document+ScriptingSupport.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Document+ScriptingSupport.swift"; sourceTree = "<group>"; };
@ -1365,11 +1337,8 @@
5454B92D243C8257009275BC /* CotEditor-Sparkle.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "CotEditor-Sparkle.xcconfig"; sourceTree = "<group>"; };
5454B92E243C8257009275BC /* CotEditor.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = CotEditor.xcconfig; sourceTree = "<group>"; };
5454B933243C8271009275BC /* CotEditor-AdHoc.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "CotEditor-AdHoc.entitlements"; sourceTree = "<group>"; };
57ED31741FFD892900F16CAD /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/UnicodeBlock.strings; sourceTree = "<group>"; };
5B91B7D4282A6851005CBD5C /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/UnicodeBlock.strings"; sourceTree = "<group>"; };
8D15AC360486D014006FF6A4 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8D15AC370486D014006FF6A4 /* CotEditor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CotEditor.app; sourceTree = BUILT_PRODUCTS_DIR; };
99A8630F2A753A8400EEEE75 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/UnicodeBlock.strings; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -1379,6 +1348,7 @@
files = (
2ACD02BF22A87F0400893051 /* ColorCode in Frameworks */,
2AA2C6FC24399A920017D1EC /* Yams in Frameworks */,
2A7E06E82C1A745400E5396D /* CharacterInfo in Frameworks */,
2ACAAC1C2B85E74C0041B095 /* SyntaxMap in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1387,6 +1357,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2A7E06EA2C1A745E00E5396D /* CharacterInfo in Frameworks */,
2AAAE6E526DB82F800C5F0AC /* Sparkle in Frameworks */,
2ACD02BD22A87EFD00893051 /* ColorCode in Frameworks */,
2ACAAC1E2B85E7530041B095 /* SyntaxMap in Frameworks */,
@ -1804,7 +1775,6 @@
2A1EB5C319AD469500C1E37E /* Assets.xcassets */,
2A149DC91902BC3900A9D6EF /* Storyboards */,
2AC94B262B6E2E110086F9F2 /* Localizables */,
2AA2E0111BFE12620087BDD6 /* UnicodeBlock.strings */,
2A8EAE3D2BA3B15D00448875 /* Credits.json */,
2A2179F51A07093B002C4AB1 /* SyntaxMap.json */,
2A3A758D19E77C84001DAB88 /* Syntaxes */,
@ -1937,7 +1907,6 @@
2A476CAF1D09CA640088E37A /* Models */ = {
isa = PBXGroup;
children = (
2AA2E00D1BFDD3AE0087BDD6 /* Character */,
2A89847C1C3CE1CE006290FF /* Syntax */,
2AA14CFA1FA47E9000EAF586 /* Script */,
2A505C07298952E5002080AA /* Shortcut */,
@ -2052,6 +2021,7 @@
2A7E06EB2C1A79B600E5396D /* Packages */ = {
isa = PBXGroup;
children = (
2A7E06E52C1A711B00E5396D /* Libraries */,
2A8544E6267872E0006EF01A /* SyntaxMap */,
);
path = Packages;
@ -2144,22 +2114,9 @@
name = Script;
sourceTree = "<group>";
};
2AA2E00D1BFDD3AE0087BDD6 /* Character */ = {
isa = PBXGroup;
children = (
2AF073FA1D34587500770BA6 /* CharacterInfo.swift */,
2A73B5BB1D468DD30025337F /* Unicode.Scalar+Information.swift */,
2A73B5B31D4675350025337F /* Unicode.Scalar+ControlCharacter.swift */,
2AB2913D245AAD74004CC203 /* Unicode.GeneralCategory.swift */,
2A1235452121B106002E9C53 /* Unicode.UTF32.CodeUnit+BlockName.swift */,
);
name = Character;
sourceTree = "<group>";
};
2AA6725B2B8F74D900B8F7E6 /* Models */ = {
isa = PBXGroup;
children = (
2A7FEF322B90E1C20042BEFF /* Character.xcstrings */,
2AAF93552A73DEE600CCC4A7 /* LineEnding.xcstrings */,
2A5E6FC02A72342700E33EA7 /* UnicodeNormalization.xcstrings */,
2A07A8FC2BABC1C3007CABFD /* Syntax.xcstrings */,
@ -2306,7 +2263,6 @@
2ACC65301C9802D4000574DC /* Models */ = {
isa = PBXGroup;
children = (
2AA2E00F1BFDE0190087BDD6 /* CharacterInfoTests.swift */,
2A63CEC31D0B06D800ED8186 /* SyntaxTests.swift */,
2ACC65311C98033D000574DC /* ThemeTests.swift */,
2A9C07551CF9F982006D672D /* IncompatibleCharacterTests.swift */,
@ -2488,6 +2444,7 @@
2ACD02BE22A87F0400893051 /* ColorCode */,
2AA2C6FB24399A920017D1EC /* Yams */,
2ACAAC1B2B85E74C0041B095 /* SyntaxMap */,
2A7E06E72C1A745400E5396D /* CharacterInfo */,
);
productInstallPath = "$(HOME)/Applications";
productName = CotEditor;
@ -2533,6 +2490,7 @@
2AA2C6FD24399AA20017D1EC /* Yams */,
2AAAE6E426DB82F800C5F0AC /* Sparkle */,
2ACAAC1D2B85E7530041B095 /* SyntaxMap */,
2A7E06E92C1A745E00E5396D /* CharacterInfo */,
);
productInstallPath = "$(HOME)/Applications";
productName = CotEditor;
@ -2652,7 +2610,6 @@
2A39ACFC2B8CEE2F00E216C9 /* AddRemoveButton.xcstrings in Resources */,
2A55D5D82B7A728A0092DE48 /* AdvancedCharacterCount.xcstrings in Resources */,
2ACDA2A52B81EE0E00B2EBA8 /* AppearanceSettings.xcstrings in Resources */,
2A7FEF332B90E1C20042BEFF /* Character.xcstrings in Resources */,
2A1E7E3B2B8D7D48004F0C07 /* CharacterInspector.xcstrings in Resources */,
2ACDA2892B81E2AC00B2EBA8 /* ColorCode.xcstrings in Resources */,
2A07A9032BABC1FA007CABFD /* CommandBar.xcstrings in Resources */,
@ -2698,7 +2655,6 @@
2A5E6FC12A72342700E33EA7 /* UnicodeNormalization.xcstrings in Resources */,
2A24F9162BEDFD9400CB6CCF /* WhatsNew.xcstrings in Resources */,
2ACDA2972B81E8BB00B2EBA8 /* WindowSettings.xcstrings in Resources */,
2AA2E0141BFE12620087BDD6 /* UnicodeBlock.strings in Resources */,
2A836F811D572A5D0044E8EC /* Main.storyboard in Resources */,
2ACDE29A2406B9C000FC31EC /* FindPanelFieldView.storyboard in Resources */,
2ACDE29C2406B9C000FC31EC /* SyntaxListView.storyboard in Resources */,
@ -2742,7 +2698,6 @@
2A39ACFD2B8CEE2F00E216C9 /* AddRemoveButton.xcstrings in Resources */,
2A55D5D92B7A728A0092DE48 /* AdvancedCharacterCount.xcstrings in Resources */,
2ACDA2A62B81EE0E00B2EBA8 /* AppearanceSettings.xcstrings in Resources */,
2A7FEF342B90E1C20042BEFF /* Character.xcstrings in Resources */,
2A1E7E3C2B8D7D48004F0C07 /* CharacterInspector.xcstrings in Resources */,
2ACDA28A2B81E2B100B2EBA8 /* ColorCode.xcstrings in Resources */,
2A07A9042BABC1FA007CABFD /* CommandBar.xcstrings in Resources */,
@ -2789,7 +2744,6 @@
2A24F9172BEDFD9400CB6CCF /* WhatsNew.xcstrings in Resources */,
2ACDA2982B81E8BB00B2EBA8 /* WindowSettings.xcstrings in Resources */,
2A36E36F2AF9ED0B00A73534 /* Sparkle.xcstrings in Resources */,
2AA2E0131BFE12620087BDD6 /* UnicodeBlock.strings in Resources */,
2A836F801D572A5D0044E8EC /* Main.storyboard in Resources */,
2A5D13421D1FE34F00D38E6A /* FindPanelFieldView.storyboard in Resources */,
2A10D1381E715E5B0027192A /* SyntaxListView.storyboard in Resources */,
@ -2925,7 +2879,6 @@
2AB1BD24287DA73D00C6FEAF /* CharacterCountOptionsSheetView.swift in Sources */,
2AB1BD1C287D60DF00C6FEAF /* CharacterCountOptionsView.swift in Sources */,
2A5DCE501D185F1B00D5D74C /* CharacterField.swift in Sources */,
2AF073FC1D34587500770BA6 /* CharacterInfo.swift in Sources */,
2A42823A2638DAEB00D03C5C /* CharacterInspectorView.swift in Sources */,
2A5ADE851D2168FC00F6CE26 /* Collection.swift in Sources */,
2A5C00342814698000700CAE /* Collection+BinarySearch.swift in Sources */,
@ -3194,10 +3147,6 @@
2A63FBE41D1D90E70081C84E /* ThemeView.swift in Sources */,
2A0DD6371E655FE6001CAAA3 /* Tokenizer.swift in Sources */,
2A0DD6341E655C4A001CAAA3 /* TokenTextEditor.swift in Sources */,
2AB2913E245AAD74004CC203 /* Unicode.GeneralCategory.swift in Sources */,
2A73B5B71D4675350025337F /* Unicode.Scalar+ControlCharacter.swift in Sources */,
2A73B5BD1D468DD30025337F /* Unicode.Scalar+Information.swift in Sources */,
2A1235472121B106002E9C53 /* Unicode.UTF32.CodeUnit+BlockName.swift in Sources */,
2A4257B71D23153B0086DAAD /* UnicodeInputView.swift in Sources */,
2AA14D001FA498E900EAF586 /* UnixScript.swift in Sources */,
2A8DA9481D28ED93003D0C4B /* URL.swift in Sources */,
@ -3227,7 +3176,6 @@
files = (
2AF5D0E5286D9AB3000BE826 /* ArithmeticsTests.swift in Sources */,
2A9C370E1D672A1F00774BA4 /* BracePairTests.swift in Sources */,
2AA2E0101BFDE0190087BDD6 /* CharacterInfoTests.swift in Sources */,
2AC39F731E8AC80E009F97D5 /* CollectionTests.swift in Sources */,
2A2E56D72C018ADB00416F9E /* ComparableTests.swift in Sources */,
2A3F8F682429E04000CBBA89 /* DebouncerTests.swift in Sources */,
@ -3295,7 +3243,6 @@
2A24F9142BEDF6D000CB6CCF /* CapsuleButtonStyle.swift in Sources */,
2AB1BD1D287D60DF00C6FEAF /* CharacterCountOptionsView.swift in Sources */,
2A5DCE4F1D185F1B00D5D74C /* CharacterField.swift in Sources */,
2AF073FB1D34587500770BA6 /* CharacterInfo.swift in Sources */,
2A42823B2638DAEB00D03C5C /* CharacterInspectorView.swift in Sources */,
2A5ADE841D2168FC00F6CE26 /* Collection.swift in Sources */,
2A5C00352814698000700CAE /* Collection+BinarySearch.swift in Sources */,
@ -3564,10 +3511,6 @@
2A63FBE31D1D90E70081C84E /* ThemeView.swift in Sources */,
2A0DD6361E655FE6001CAAA3 /* Tokenizer.swift in Sources */,
2A0DD6331E655C4A001CAAA3 /* TokenTextEditor.swift in Sources */,
2AB2913F245AAD74004CC203 /* Unicode.GeneralCategory.swift in Sources */,
2A73B5B61D4675350025337F /* Unicode.Scalar+ControlCharacter.swift in Sources */,
2A73B5BC1D468DD30025337F /* Unicode.Scalar+Information.swift in Sources */,
2A1235462121B106002E9C53 /* Unicode.UTF32.CodeUnit+BlockName.swift in Sources */,
2A4257B61D23153B0086DAAD /* UnicodeInputView.swift in Sources */,
2AA14CFF1FA498E900EAF586 /* UnixScript.swift in Sources */,
2A78BFB31D1B240900A583D2 /* UpdaterManager.swift in Sources */,
@ -3679,25 +3622,6 @@
name = Main.storyboard;
sourceTree = "<group>";
};
2AA2E0111BFE12620087BDD6 /* UnicodeBlock.strings */ = {
isa = PBXVariantGroup;
children = (
2AC4E5D127A6C0300052A4DD /* en-GB */,
2AA2E0151BFE14310087BDD6 /* zh-Hans */,
5B91B7D4282A6851005CBD5C /* zh-Hant */,
2AC605AE2B64CDE300E93E5B /* cs */,
2A51CF402BB45940001896F1 /* nl */,
0D51D5922274EF5300A5D747 /* fr */,
2AA2E0161BFE14320087BDD6 /* de */,
2A401FE81D9AF7CA00ACE036 /* it */,
2AA2E0121BFE12620087BDD6 /* ja */,
57ED31741FFD892900F16CAD /* pt */,
99A8630F2A753A8400EEEE75 /* es */,
08C28FB2279CBE530016693E /* tr */,
);
name = UnicodeBlock.strings;
sourceTree = "<group>";
};
2AAFA7BA2B7A2DAF00A2B228 /* MultipleReplaceListView.storyboard */ = {
isa = PBXVariantGroup;
children = (
@ -4062,6 +3986,14 @@
isa = XCSwiftPackageProductDependency;
productName = SyntaxMapBuilder;
};
2A7E06E72C1A745400E5396D /* CharacterInfo */ = {
isa = XCSwiftPackageProductDependency;
productName = CharacterInfo;
};
2A7E06E92C1A745E00E5396D /* CharacterInfo */ = {
isa = XCSwiftPackageProductDependency;
productName = CharacterInfo;
};
2AA2C6FB24399A920017D1EC /* Yams */ = {
isa = XCSwiftPackageProductDependency;
package = 2AA2C6FA24399A920017D1EC /* XCRemoteSwiftPackageReference "Yams" */;

View File

@ -1,5 +1,5 @@
{
"originHash" : "bf8320807957aff72d6269b713c804a2fb76b9f1e9ac955e1a55b19bebbf2471",
"originHash" : "c6c138f4baf7e1a58918fd7e903f1660829eab2520d79043ffc426b21a8dbb55",
"pins" : [
{
"identity" : "sparkle",

View File

@ -1,6 +1,83 @@
{
"sourceLanguage" : "en",
"strings" : {
"<a letter consisting of %lld characters>" : {
"comment" : "%lld is always 2 or more.",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "<písmeno složené z %lld znaků>"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "<ein aus %lld Zeichen bestehender Buchstabe>"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : "<a letter consisting of %lld characters>"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "<una letra que consta de %lld caracteres>"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "<un symbole constitué de %lld caractères>"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "<una lettera composta di %lld caratteri>"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "<%lld字から成る文字>"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "<een letter bestaande uit %lld tekens>"
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : "<uma letra que consiste em %lld caracteres>"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "%lld karakterden oluşan bir harf"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "<包含有%lld个字符>"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "<包含有%lld個字元>"
}
}
}
},
"Block:" : {
"localizations" : {
"cs" : {

View File

@ -1,176 +0,0 @@
//
// CharacterInfo.swift
//
// CotEditor
// https://coteditor.com
//
// Created by 1024jp on 2015-11-19.
//
// ---------------------------------------------------------------------------
//
// © 2015-2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
private enum EmojiVariationSelector: UInt32 {
case text = 0xFE0E
case emoji = 0xFE0F
var label: String {
switch self {
case .emoji:
String(localized: "EmojiVariationSelector.emoji.label",
defaultValue: "Emoji Style",
table: "Character",
comment: "label for the Unicode variation selector that forces to draw the character in the emoji style")
case .text:
String(localized: "EmojiVariationSelector.text.label",
defaultValue: "Text Style",
table: "Character",
comment: "label for the Unicode variation selector that forces to draw the character in the text style")
}
}
}
private enum SkinToneModifier: UInt32 {
case type12 = 0x1F3FB // 🏻 Light
case type3 = 0x1F3FC // 🏼 Medium Light
case type4 = 0x1F3FD // 🏽 Medium
case type5 = 0x1F3FE // 🏾 Medium Dark
case type6 = 0x1F3FF // 🏿 Dark
var label: String {
switch self {
case .type12:
String(localized: "SkinToneModifier.type12.label",
defaultValue: "Skin Tone I-II",
table: "Character",
comment: "label for Unicode emoji modifier applying the skin tone to the character")
case .type3:
String(localized: "SkinToneModifier.type3.label",
defaultValue: "Skin Tone III",
table: "Character",
comment: "label for Unicode emoji modifier applying the skin tone to the character")
case .type4:
String(localized: "SkinToneModifier.type4.label",
defaultValue: "Skin Tone IV",
table: "Character",
comment: "label for Unicode emoji modifier applying the skin tone to the character")
case .type5:
String(localized: "SkinToneModifier.type5.label",
defaultValue: "Skin Tone V",
table: "Character",
comment: "label for Unicode emoji modifier applying the skin tone to the character")
case .type6:
String(localized: "SkinToneModifier.type6.label",
defaultValue: "Skin Tone VI",
table: "Character",
comment: "label for Unicode emoji modifier applying the skin tone to the character")
}
}
}
// MARK: -
struct CharacterInfo {
// MARK: Public Properties
var character: Character
// MARK: Public Methods
var localizedDescription: String? {
let unicodes = self.character.unicodeScalars
if self.isComplex {
return String(localized: "<a letter consisting of \(unicodes.count) characters>",
table: "Character",
comment: "%lld is always 2 or more.")
}
guard var unicodeName = unicodes.first?.name else { return nil }
if self.isVariant, let variantDescription = unicodes.last?.variantDescription {
unicodeName += String(localized: " (\(variantDescription))")
}
return unicodeName
}
var pictureCharacter: Character? {
self.character.unicodeScalars.count == 1 // ignore CRLF
? self.character.unicodeScalars.first?.pictureRepresentation.flatMap(Character.init)
: nil
}
var isComplex: Bool {
self.character.unicodeScalars.count > 1 && !self.isVariant
}
// MARK: Private Methods
private var isVariant: Bool {
(self.character.unicodeScalars.count == 2 &&
self.character.unicodeScalars.last?.variantDescription != nil)
}
}
extension CharacterInfo: CustomStringConvertible {
var description: String {
String(self.character)
}
}
private extension Unicode.Scalar {
var variantDescription: String? {
if let selector = EmojiVariationSelector(rawValue: self.value) {
selector.label
} else if let modifier = SkinToneModifier(rawValue: self.value) {
modifier.label
} else if self.properties.isVariationSelector {
String(localized: "Variant",
table: "Character",
comment: "label for general Unicode variation selectors")
} else {
nil
}
}
}

View File

@ -23,6 +23,7 @@
// limitations under the License.
//
import CharacterInfo
import SwiftUI
struct CharacterInspectorView: View {
@ -237,6 +238,28 @@ private struct DeprecatedBadge: View {
}
private extension CharacterInfo {
var localizedDescription: String? {
let unicodes = self.character.unicodeScalars
if self.isComplex {
return String(localized: "<a letter consisting of \(unicodes.count) characters>",
table: "CharacterInspector",
comment: "%lld is always 2 or more.")
}
guard var unicodeName = unicodes.first?.name else { return nil }
if self.isVariant, let variantDescription = unicodes.last?.variantDescription {
unicodeName += String(localized: " (\(variantDescription))")
}
return unicodeName
}
}
// MARK: - Preview

View File

@ -26,6 +26,7 @@
import AppKit
import Combine
import CharacterInfo
import SwiftUI
final class EditorTextViewController: NSViewController, NSServicesMenuRequestor, NSTextViewDelegate {

View File

@ -0,0 +1,20 @@
// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "Libraries",
defaultLocalization: "en",
platforms: [
.macOS(.v14),
],
products: [
.library(name: "CharacterInfo", targets: ["CharacterInfo"]),
],
targets: [
.target(name: "CharacterInfo", resources: [.process("Resources")]),
.testTarget(name: "CharacterInfoTests", dependencies: ["CharacterInfo"]),
],
swiftLanguageVersions: [.v6]
)

View File

@ -0,0 +1,71 @@
//
// CharacterInfo.swift
// CharacterInfo
//
// CotEditor
// https://coteditor.com
//
// Created by 1024jp on 2015-11-19.
//
// ---------------------------------------------------------------------------
//
// © 2015-2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
public struct CharacterInfo: Sendable {
// MARK: Public Properties
public var character: Character
// MARK: Public Methods
public init(character: Character) {
self.character = character
}
public var pictureCharacter: Character? {
self.character.unicodeScalars.count == 1 // ignore CRLF
? self.character.unicodeScalars.first?.pictureRepresentation.flatMap(Character.init)
: nil
}
public var isComplex: Bool {
self.character.unicodeScalars.count > 1 && !self.isVariant
}
public var isVariant: Bool {
(self.character.unicodeScalars.count == 2 &&
self.character.unicodeScalars.last?.variantDescription != nil)
}
}
extension CharacterInfo: CustomStringConvertible {
public var description: String {
String(self.character)
}
}

View File

@ -1,83 +1,6 @@
{
"sourceLanguage" : "en",
"strings" : {
"<a letter consisting of %lld characters>" : {
"comment" : "%lld is always 2 or more.",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "<písmeno složené z %lld znaků>"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "<ein aus %lld Zeichen bestehender Buchstabe>"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : "<a letter consisting of %lld characters>"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "<una letra que consta de %lld caracteres>"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "<un symbole constitué de %lld caractères>"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "<una lettera composta di %lld caratteri>"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "<%lld字から成る文字>"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "<een letter bestaande uit %lld tekens>"
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : "<uma letra que consiste em %lld caracteres>"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "%lld karakterden oluşan bir harf"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "<包含有%lld个字符>"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "<包含有%lld個字元>"
}
}
}
},
"EmojiVariationSelector.emoji.label" : {
"comment" : "label for the Unicode variation selector that forces to draw the character in the emoji style",
"extractionState" : "extracted_with_value",

View File

@ -0,0 +1,66 @@
//
// SkinToneModifier.swift
// CharacterInfo
//
// CotEditor
// https://coteditor.com
//
// Created by 1024jp on 2015-11-19.
//
// ---------------------------------------------------------------------------
//
// © 2015-2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
enum SkinToneModifier: UInt32, Sendable {
case type12 = 0x1F3FB // 🏻 Light
case type3 = 0x1F3FC // 🏼 Medium Light
case type4 = 0x1F3FD // 🏽 Medium
case type5 = 0x1F3FE // 🏾 Medium Dark
case type6 = 0x1F3FF // 🏿 Dark
var label: String {
switch self {
case .type12:
String(localized: "SkinToneModifier.type12.label",
defaultValue: "Skin Tone I-II",
bundle: .module,
comment: "label for Unicode emoji modifier applying the skin tone to the character")
case .type3:
String(localized: "SkinToneModifier.type3.label",
defaultValue: "Skin Tone III",
bundle: .module,
comment: "label for Unicode emoji modifier applying the skin tone to the character")
case .type4:
String(localized: "SkinToneModifier.type4.label",
defaultValue: "Skin Tone IV",
bundle: .module,
comment: "label for Unicode emoji modifier applying the skin tone to the character")
case .type5:
String(localized: "SkinToneModifier.type5.label",
defaultValue: "Skin Tone V",
bundle: .module,
comment: "label for Unicode emoji modifier applying the skin tone to the character")
case .type6:
String(localized: "SkinToneModifier.type6.label",
defaultValue: "Skin Tone VI",
bundle: .module,
comment: "label for Unicode emoji modifier applying the skin tone to the character")
}
}
}

View File

@ -1,5 +1,6 @@
//
// Unicode.GeneralCategory.swift
// CharacterInfo
//
// CotEditor
// https://coteditor.com
@ -8,7 +9,7 @@
//
// ---------------------------------------------------------------------------
//
// © 2020-2023 1024jp
// © 2020-2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -23,7 +24,7 @@
// limitations under the License.
//
extension Unicode.GeneralCategory {
public extension Unicode.GeneralCategory {
/// The long value aliases for the category.
var longName: String {

View File

@ -1,5 +1,6 @@
//
// Unicode.Scalar+ControlCharacter.swift
// CharacterInfo
//
// CotEditor
// https://coteditor.com
@ -8,7 +9,7 @@
//
// ---------------------------------------------------------------------------
//
// © 2015-2023 1024jp
// © 2015-2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -23,9 +24,9 @@
// limitations under the License.
//
extension Unicode.Scalar {
public extension Unicode.Scalar {
/// Alternate picture character for invisible control character.
/// The alternate picture character for invisible control character if available.
var pictureRepresentation: Unicode.Scalar? {
switch self.value {

View File

@ -1,5 +1,6 @@
//
// Unicode.Scalar+Information.swift
// CharacterInfo
//
// CotEditor
// https://coteditor.com
@ -8,7 +9,7 @@
//
// ---------------------------------------------------------------------------
//
// © 2015-2023 1024jp
// © 2015-2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -23,7 +24,7 @@
// limitations under the License.
//
extension Unicode.Scalar {
public extension Unicode.Scalar {
/// Code point string in format like `U+000F`.
var codePoint: String {
@ -76,7 +77,7 @@ extension Unicode.Scalar {
.replacing(/\ ([A-Z])$/) { "-\($0.1)" }
.replacing("Description", with: "Desc.")
return String(localized: String.LocalizationValue(key), table: "UnicodeBlock")
return String(localized: String.LocalizationValue(key), table: "UnicodeBlock", bundle: .module)
}
}
@ -84,7 +85,7 @@ extension Unicode.Scalar {
// MARK: -
extension UTF32.CodeUnit {
public extension UTF32.CodeUnit {
/// Returns Unicode name.
///

View File

@ -0,0 +1,73 @@
//
// Unicode.Scalar+Variant.swift
// CharacterInfo
//
// CotEditor
// https://coteditor.com
//
// Created by 1024jp on 2015-11-19.
//
// ---------------------------------------------------------------------------
//
// © 2015-2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
public extension Unicode.Scalar {
var variantDescription: String? {
if let selector = EmojiVariationSelector(rawValue: self.value) {
selector.label
} else if let modifier = SkinToneModifier(rawValue: self.value) {
modifier.label
} else if self.properties.isVariationSelector {
String(localized: "Variant",
bundle: .module,
comment: "label for general Unicode variation selectors")
} else {
nil
}
}
}
// MARK: -
private enum EmojiVariationSelector: UInt32 {
case text = 0xFE0E
case emoji = 0xFE0F
var label: String {
switch self {
case .emoji:
String(localized: "EmojiVariationSelector.emoji.label",
defaultValue: "Emoji Style",
bundle: .module,
comment: "label for the Unicode variation selector that forces to draw the character in the emoji style")
case .text:
String(localized: "EmojiVariationSelector.text.label",
defaultValue: "Text Style",
bundle: .module,
comment: "label for the Unicode variation selector that forces to draw the character in the text style")
}
}
}

View File

@ -1,5 +1,6 @@
//
// Unicode.UTF32.CodeUnit+BlockName.swift
// CharacterInfo
//
// CotEditor
// https://coteditor.com
@ -8,7 +9,7 @@
//
// ---------------------------------------------------------------------------
//
// © 2018-2023 1024jp
// © 2018-2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -23,7 +24,7 @@
// limitations under the License.
//
extension Unicode.UTF32.CodeUnit {
public extension Unicode.UTF32.CodeUnit {
/// Unicode block name.
///

View File

@ -0,0 +1,69 @@
//
// CharacterInfoTests.swift
// CharacterInfoTests
//
// CotEditor
// https://coteditor.com
//
// Created by 1024jp on 2015-11-19.
//
// ---------------------------------------------------------------------------
//
// © 2015-2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Testing
@testable import CharacterInfo
struct CharacterInfoTests {
@Test func singleCharacterWithVSInfo() {
let charInfo = CharacterInfo(character: "☺︎")
#expect(charInfo.character == "☺︎")
#expect(!charInfo.isComplex)
#expect(charInfo.character.unicodeScalars.map(\.codePoint) == ["U+263A", "U+FE0E"])
#expect(charInfo.character.unicodeScalars.map(\.name) == ["WHITE SMILING FACE", "VARIATION SELECTOR-15"])
}
@Test func combiningCharacterInfo() {
let charInfo = CharacterInfo(character: "1")
#expect(charInfo.isComplex)
#expect(charInfo.character.unicodeScalars.map(\.codePoint) == ["U+0031", "U+FE0F", "U+20E3"])
}
@Test func nationalIndicatorInfo() {
let charInfo = CharacterInfo(character: "🇯🇵")
#expect(charInfo.isComplex)
#expect(charInfo.character.unicodeScalars.map(\.codePoint) == ["U+1F1EF", "U+1F1F5"])
}
@Test func controlCharacterInfo() {
let charInfo = CharacterInfo(character: " ")
#expect(charInfo.character == " ")
#expect(charInfo.pictureCharacter == "")
#expect(charInfo.character.unicodeScalars.map(\.name) == ["SPACE"])
}
}

View File

@ -0,0 +1,41 @@
//
// CodeUnitTests.swift
// CharacterInfoTests
//
// CotEditor
// https://coteditor.com
//
// Created by 1024jp on 2015-11-19.
//
// ---------------------------------------------------------------------------
//
// © 2015-2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Testing
@testable import CharacterInfo
struct CodeUnitTests {
@Test func singleSurrogate() {
let character: UTF32.CodeUnit = 0xD83D
#expect(character.unicodeName == "<lead surrogate-D83D>")
#expect(character.blockName == "High Surrogates")
#expect(Unicode.Scalar(character) == nil)
}
}

View File

@ -1,6 +1,6 @@
//
// CharacterInfoTests.swift
// Tests
// UnicodeCharacterTests.swift
// CharacterInfoTests
//
// CotEditor
// https://coteditor.com
@ -24,26 +24,10 @@
// limitations under the License.
//
import AppKit
import Testing
@testable import CotEditor
@testable import CharacterInfo
struct CharacterInfoTests {
// MARK: UTF32.CodeUnit Extension Tests
@Test func singleSurrogate() {
let character: UTF32.CodeUnit = 0xD83D
#expect(character.unicodeName == "<lead surrogate-D83D>")
#expect(character.blockName == "High Surrogates")
#expect(Unicode.Scalar(character) == nil)
}
// MARK: - UnicodeCharacter Tests
struct UnicodeCharacterTests {
@Test func singleChar() {
@ -97,8 +81,8 @@ struct CharacterInfoTests {
#expect(spacePictureCharacter.name == "SYMBOL FOR SPACE")
#expect(spaceCharacter.pictureRepresentation == spacePictureCharacter)
// test DELETE
let deleteCharacter = try #require(Unicode.Scalar(NSDeleteCharacter))
// test DELETE (NSDeleteCharacter)
let deleteCharacter = try #require(Unicode.Scalar(0x007f))
let deletePictureCharacter = Unicode.Scalar("")
#expect(deleteCharacter.name == "DELETE")
#expect(deletePictureCharacter.name == "SYMBOL FOR DELETE")
@ -109,47 +93,4 @@ struct CharacterInfoTests {
#expect(exclamationCharacter.name == "EXCLAMATION MARK")
#expect(exclamationCharacter.pictureRepresentation == nil)
}
// MARK: - CharacterInfo Tests
@Test func singleCharacterWithVSInfo() {
let charInfo = CharacterInfo(character: "☺︎")
#expect(charInfo.character == "☺︎")
#expect(!charInfo.isComplex)
#expect(charInfo.character.unicodeScalars.map(\.codePoint) == ["U+263A", "U+FE0E"])
#expect(charInfo.character.unicodeScalars.map(\.name) == ["WHITE SMILING FACE", "VARIATION SELECTOR-15"])
#expect(charInfo.localizedDescription == "WHITE SMILING FACE (Text Style)")
}
@Test func combiningCharacterInfo() {
let charInfo = CharacterInfo(character: "1")
#expect(charInfo.isComplex)
#expect(charInfo.character.unicodeScalars.map(\.codePoint) == ["U+0031", "U+FE0F", "U+20E3"])
#expect(charInfo.localizedDescription == "<a letter consisting of 3 characters>")
}
@Test func nationalIndicatorInfo() {
let charInfo = CharacterInfo(character: "🇯🇵")
#expect(charInfo.isComplex)
#expect(charInfo.character.unicodeScalars.map(\.codePoint) == ["U+1F1EF", "U+1F1F5"])
}
@Test func controlCharacterInfo() {
let charInfo = CharacterInfo(character: " ")
#expect(charInfo.character == " ")
#expect(charInfo.pictureCharacter == "")
#expect(charInfo.character.unicodeScalars.map(\.name) == ["SPACE"])
}
}