├── .gitignore ├── Demo.gif ├── LICENSE ├── Literals.playground ├── Contents.swift ├── Resources │ ├── FCBarcelona.png │ └── FCDnipro.png └── contents.xcplayground ├── Literals.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── Literals ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── FCBarcelona.imageset │ │ ├── Contents.json │ │ └── FCBarcelona.png │ └── FCDnipro.imageset │ │ ├── Contents.json │ │ └── FCDnipro.png ├── Base.lproj │ └── MainMenu.xib └── Info.plist ├── LiteralsExtension ├── ColorLiteralsCommand.swift ├── ColorLiteralsConverter.swift ├── ImageLiteralsCommand.swift ├── ImageLiteralsConverter.swift ├── Info.plist ├── LiteralsExtension.entitlements ├── SourceEditorExtension.swift ├── TextConverter+Command.swift └── TextConverter.swift ├── LiteralsTests ├── ColorLiteralsConverterTests.swift ├── ImageLiteralsConverterTests.swift └── Info.plist └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | .DS_Store 20 | 21 | ## Other 22 | *.moved-aside 23 | *.xcuserstate 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | .build/ 40 | 41 | # CocoaPods 42 | # 43 | # We recommend against adding the Pods directory to your .gitignore. However 44 | # you should judge for yourself, the pros and cons are mentioned at: 45 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 46 | # 47 | # Pods/ 48 | 49 | # Carthage 50 | # 51 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 52 | # Carthage/Checkouts 53 | 54 | Carthage/Build 55 | 56 | # fastlane 57 | # 58 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 59 | # screenshots whenever they are needed. 60 | # For more information about the recommended setup visit: 61 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 62 | 63 | fastlane/report.xml 64 | fastlane/Preview.html 65 | fastlane/screenshots 66 | fastlane/test_output 67 | -------------------------------------------------------------------------------- /Demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Igor-Palaguta/LiteralsExtension/f4ccee989087c562a1969357a241cc810931e75c/Demo.gif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 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 | -------------------------------------------------------------------------------- /Literals.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | let red = UIColor(red: 1, green: 0, blue: 0, alpha: 1) 4 | let green = UIColor.init(red: 0, green: 1, blue: 0, alpha: 1) 5 | 6 | let blue = UIColor(red: 0, 7 | green: 0, 8 | blue: 1, 9 | alpha: 1) 10 | 11 | let colors = [UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5), UIColor(red: 0, green: 0, blue: 0, alpha: 1)] 12 | 13 | //let nsBlack = NSColor(red: 0, green: 0, blue: 0, alpha: 1) 14 | 15 | let dnipro = UIImage(named: "FCDnipro.png") 16 | let bacelona = UIImage.init(named: "FCBarcelona") 17 | 18 | let images = [UIImage(named: "FCDnipro"), UIImage(named: "FCBarcelona")] 19 | -------------------------------------------------------------------------------- /Literals.playground/Resources/FCBarcelona.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Igor-Palaguta/LiteralsExtension/f4ccee989087c562a1969357a241cc810931e75c/Literals.playground/Resources/FCBarcelona.png -------------------------------------------------------------------------------- /Literals.playground/Resources/FCDnipro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Igor-Palaguta/LiteralsExtension/f4ccee989087c562a1969357a241cc810931e75c/Literals.playground/Resources/FCDnipro.png -------------------------------------------------------------------------------- /Literals.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Literals.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 780D3F8F1E2AD3A300398BF5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780D3F8E1E2AD3A300398BF5 /* AppDelegate.swift */; }; 11 | 780D3F911E2AD3A300398BF5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 780D3F901E2AD3A300398BF5 /* Assets.xcassets */; }; 12 | 780D3F941E2AD3A300398BF5 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 780D3F921E2AD3A300398BF5 /* MainMenu.xib */; }; 13 | 780D3FB01E2AD3C800398BF5 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 780D3FAF1E2AD3C800398BF5 /* Cocoa.framework */; }; 14 | 780D3FB51E2AD3C800398BF5 /* SourceEditorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780D3FB41E2AD3C800398BF5 /* SourceEditorExtension.swift */; }; 15 | 780D3FB71E2AD3C800398BF5 /* ColorLiteralsCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780D3FB61E2AD3C800398BF5 /* ColorLiteralsCommand.swift */; }; 16 | 780D3FBB1E2AD3C900398BF5 /* Convert Literals.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 780D3FAD1E2AD3C800398BF5 /* Convert Literals.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 17 | 780D3FC11E2AD40F00398BF5 /* TextConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780D3FC01E2AD40F00398BF5 /* TextConverter.swift */; }; 18 | 780D3FC31E2AD51A00398BF5 /* ColorLiteralsConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780D3FC21E2AD51A00398BF5 /* ColorLiteralsConverter.swift */; }; 19 | 780D3FC51E2AD68600398BF5 /* ColorLiteralsConverterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780D3FC41E2AD68600398BF5 /* ColorLiteralsConverterTests.swift */; }; 20 | 780D3FC61E2AD68D00398BF5 /* ColorLiteralsConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780D3FC21E2AD51A00398BF5 /* ColorLiteralsConverter.swift */; }; 21 | 780D3FC71E2AD68D00398BF5 /* TextConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780D3FC01E2AD40F00398BF5 /* TextConverter.swift */; }; 22 | 784980E31E2CD25500D18D3A /* ImageLiteralsConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784980E21E2CD25500D18D3A /* ImageLiteralsConverter.swift */; }; 23 | 784980E51E2CD26C00D18D3A /* ImageLiteralsCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784980E41E2CD26C00D18D3A /* ImageLiteralsCommand.swift */; }; 24 | 784980E71E2CD2A000D18D3A /* TextConverter+Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784980E61E2CD2A000D18D3A /* TextConverter+Command.swift */; }; 25 | 784980E91E2CD47200D18D3A /* ImageLiteralsConverterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784980E81E2CD47200D18D3A /* ImageLiteralsConverterTests.swift */; }; 26 | 784980EA1E2CD47900D18D3A /* ImageLiteralsConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784980E21E2CD25500D18D3A /* ImageLiteralsConverter.swift */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | 780D3F9B1E2AD3A400398BF5 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 780D3F831E2AD3A300398BF5 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 780D3F8A1E2AD3A300398BF5; 35 | remoteInfo = Literals; 36 | }; 37 | 780D3FB91E2AD3C800398BF5 /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = 780D3F831E2AD3A300398BF5 /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = 780D3FAC1E2AD3C800398BF5; 42 | remoteInfo = LiteralsExtension; 43 | }; 44 | /* End PBXContainerItemProxy section */ 45 | 46 | /* Begin PBXCopyFilesBuildPhase section */ 47 | 780D3FBF1E2AD3C900398BF5 /* Embed App Extensions */ = { 48 | isa = PBXCopyFilesBuildPhase; 49 | buildActionMask = 2147483647; 50 | dstPath = ""; 51 | dstSubfolderSpec = 13; 52 | files = ( 53 | 780D3FBB1E2AD3C900398BF5 /* Convert Literals.appex in Embed App Extensions */, 54 | ); 55 | name = "Embed App Extensions"; 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | /* End PBXCopyFilesBuildPhase section */ 59 | 60 | /* Begin PBXFileReference section */ 61 | 780D3F8B1E2AD3A300398BF5 /* Literals.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Literals.app; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | 780D3F8E1E2AD3A300398BF5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 63 | 780D3F901E2AD3A300398BF5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 64 | 780D3F931E2AD3A300398BF5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 65 | 780D3F951E2AD3A300398BF5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 66 | 780D3F9A1E2AD3A400398BF5 /* LiteralsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LiteralsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | 780D3FA01E2AD3A400398BF5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 68 | 780D3FAD1E2AD3C800398BF5 /* Convert Literals.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Convert Literals.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 69 | 780D3FAF1E2AD3C800398BF5 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 70 | 780D3FB31E2AD3C800398BF5 /* LiteralsExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LiteralsExtension.entitlements; sourceTree = ""; }; 71 | 780D3FB41E2AD3C800398BF5 /* SourceEditorExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceEditorExtension.swift; sourceTree = ""; }; 72 | 780D3FB61E2AD3C800398BF5 /* ColorLiteralsCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorLiteralsCommand.swift; sourceTree = ""; }; 73 | 780D3FB81E2AD3C800398BF5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 74 | 780D3FC01E2AD40F00398BF5 /* TextConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextConverter.swift; sourceTree = ""; }; 75 | 780D3FC21E2AD51A00398BF5 /* ColorLiteralsConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorLiteralsConverter.swift; sourceTree = ""; }; 76 | 780D3FC41E2AD68600398BF5 /* ColorLiteralsConverterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorLiteralsConverterTests.swift; sourceTree = ""; }; 77 | 784980E21E2CD25500D18D3A /* ImageLiteralsConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageLiteralsConverter.swift; sourceTree = ""; }; 78 | 784980E41E2CD26C00D18D3A /* ImageLiteralsCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageLiteralsCommand.swift; sourceTree = ""; }; 79 | 784980E61E2CD2A000D18D3A /* TextConverter+Command.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TextConverter+Command.swift"; sourceTree = ""; }; 80 | 784980E81E2CD47200D18D3A /* ImageLiteralsConverterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageLiteralsConverterTests.swift; sourceTree = ""; }; 81 | /* End PBXFileReference section */ 82 | 83 | /* Begin PBXFrameworksBuildPhase section */ 84 | 780D3F881E2AD3A300398BF5 /* Frameworks */ = { 85 | isa = PBXFrameworksBuildPhase; 86 | buildActionMask = 2147483647; 87 | files = ( 88 | ); 89 | runOnlyForDeploymentPostprocessing = 0; 90 | }; 91 | 780D3F971E2AD3A400398BF5 /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | ); 96 | runOnlyForDeploymentPostprocessing = 0; 97 | }; 98 | 780D3FAA1E2AD3C800398BF5 /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | 780D3FB01E2AD3C800398BF5 /* Cocoa.framework in Frameworks */, 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | /* End PBXFrameworksBuildPhase section */ 107 | 108 | /* Begin PBXGroup section */ 109 | 780D3F821E2AD3A300398BF5 = { 110 | isa = PBXGroup; 111 | children = ( 112 | 780D3F8D1E2AD3A300398BF5 /* Literals */, 113 | 780D3F9D1E2AD3A400398BF5 /* LiteralsTests */, 114 | 780D3FB11E2AD3C800398BF5 /* LiteralsExtension */, 115 | 780D3FAE1E2AD3C800398BF5 /* Frameworks */, 116 | 780D3F8C1E2AD3A300398BF5 /* Products */, 117 | ); 118 | indentWidth = 4; 119 | sourceTree = ""; 120 | tabWidth = 4; 121 | }; 122 | 780D3F8C1E2AD3A300398BF5 /* Products */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 780D3F8B1E2AD3A300398BF5 /* Literals.app */, 126 | 780D3F9A1E2AD3A400398BF5 /* LiteralsTests.xctest */, 127 | 780D3FAD1E2AD3C800398BF5 /* Convert Literals.appex */, 128 | ); 129 | name = Products; 130 | sourceTree = ""; 131 | }; 132 | 780D3F8D1E2AD3A300398BF5 /* Literals */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 780D3F8E1E2AD3A300398BF5 /* AppDelegate.swift */, 136 | 780D3F901E2AD3A300398BF5 /* Assets.xcassets */, 137 | 780D3F921E2AD3A300398BF5 /* MainMenu.xib */, 138 | 780D3F951E2AD3A300398BF5 /* Info.plist */, 139 | ); 140 | path = Literals; 141 | sourceTree = ""; 142 | }; 143 | 780D3F9D1E2AD3A400398BF5 /* LiteralsTests */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 780D3FA01E2AD3A400398BF5 /* Info.plist */, 147 | 780D3FC41E2AD68600398BF5 /* ColorLiteralsConverterTests.swift */, 148 | 784980E81E2CD47200D18D3A /* ImageLiteralsConverterTests.swift */, 149 | ); 150 | path = LiteralsTests; 151 | sourceTree = ""; 152 | }; 153 | 780D3FAE1E2AD3C800398BF5 /* Frameworks */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 780D3FAF1E2AD3C800398BF5 /* Cocoa.framework */, 157 | ); 158 | name = Frameworks; 159 | sourceTree = ""; 160 | }; 161 | 780D3FB11E2AD3C800398BF5 /* LiteralsExtension */ = { 162 | isa = PBXGroup; 163 | children = ( 164 | 780D3FB81E2AD3C800398BF5 /* Info.plist */, 165 | 780D3FB61E2AD3C800398BF5 /* ColorLiteralsCommand.swift */, 166 | 780D3FC21E2AD51A00398BF5 /* ColorLiteralsConverter.swift */, 167 | 784980E41E2CD26C00D18D3A /* ImageLiteralsCommand.swift */, 168 | 784980E21E2CD25500D18D3A /* ImageLiteralsConverter.swift */, 169 | 780D3FB41E2AD3C800398BF5 /* SourceEditorExtension.swift */, 170 | 780D3FC01E2AD40F00398BF5 /* TextConverter.swift */, 171 | 784980E61E2CD2A000D18D3A /* TextConverter+Command.swift */, 172 | 780D3FB21E2AD3C800398BF5 /* Supporting Files */, 173 | ); 174 | path = LiteralsExtension; 175 | sourceTree = ""; 176 | }; 177 | 780D3FB21E2AD3C800398BF5 /* Supporting Files */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | 780D3FB31E2AD3C800398BF5 /* LiteralsExtension.entitlements */, 181 | ); 182 | name = "Supporting Files"; 183 | sourceTree = ""; 184 | }; 185 | /* End PBXGroup section */ 186 | 187 | /* Begin PBXNativeTarget section */ 188 | 780D3F8A1E2AD3A300398BF5 /* Literals */ = { 189 | isa = PBXNativeTarget; 190 | buildConfigurationList = 780D3FA31E2AD3A400398BF5 /* Build configuration list for PBXNativeTarget "Literals" */; 191 | buildPhases = ( 192 | 780D3F871E2AD3A300398BF5 /* Sources */, 193 | 780D3F881E2AD3A300398BF5 /* Frameworks */, 194 | 780D3F891E2AD3A300398BF5 /* Resources */, 195 | 780D3FBF1E2AD3C900398BF5 /* Embed App Extensions */, 196 | ); 197 | buildRules = ( 198 | ); 199 | dependencies = ( 200 | 780D3FBA1E2AD3C800398BF5 /* PBXTargetDependency */, 201 | ); 202 | name = Literals; 203 | productName = Literals; 204 | productReference = 780D3F8B1E2AD3A300398BF5 /* Literals.app */; 205 | productType = "com.apple.product-type.application"; 206 | }; 207 | 780D3F991E2AD3A400398BF5 /* LiteralsTests */ = { 208 | isa = PBXNativeTarget; 209 | buildConfigurationList = 780D3FA61E2AD3A400398BF5 /* Build configuration list for PBXNativeTarget "LiteralsTests" */; 210 | buildPhases = ( 211 | 780D3F961E2AD3A400398BF5 /* Sources */, 212 | 780D3F971E2AD3A400398BF5 /* Frameworks */, 213 | 780D3F981E2AD3A400398BF5 /* Resources */, 214 | ); 215 | buildRules = ( 216 | ); 217 | dependencies = ( 218 | 780D3F9C1E2AD3A400398BF5 /* PBXTargetDependency */, 219 | ); 220 | name = LiteralsTests; 221 | productName = LiteralsTests; 222 | productReference = 780D3F9A1E2AD3A400398BF5 /* LiteralsTests.xctest */; 223 | productType = "com.apple.product-type.bundle.unit-test"; 224 | }; 225 | 780D3FAC1E2AD3C800398BF5 /* LiteralsExtension */ = { 226 | isa = PBXNativeTarget; 227 | buildConfigurationList = 780D3FBC1E2AD3C900398BF5 /* Build configuration list for PBXNativeTarget "LiteralsExtension" */; 228 | buildPhases = ( 229 | 780D3FA91E2AD3C800398BF5 /* Sources */, 230 | 780D3FAA1E2AD3C800398BF5 /* Frameworks */, 231 | 780D3FAB1E2AD3C800398BF5 /* Resources */, 232 | ); 233 | buildRules = ( 234 | ); 235 | dependencies = ( 236 | ); 237 | name = LiteralsExtension; 238 | productName = LiteralsExtension; 239 | productReference = 780D3FAD1E2AD3C800398BF5 /* Convert Literals.appex */; 240 | productType = "com.apple.product-type.xcode-extension"; 241 | }; 242 | /* End PBXNativeTarget section */ 243 | 244 | /* Begin PBXProject section */ 245 | 780D3F831E2AD3A300398BF5 /* Project object */ = { 246 | isa = PBXProject; 247 | attributes = { 248 | LastSwiftUpdateCheck = 0820; 249 | LastUpgradeCheck = 1140; 250 | ORGANIZATIONNAME = "Igor Palaguta"; 251 | TargetAttributes = { 252 | 780D3F8A1E2AD3A300398BF5 = { 253 | CreatedOnToolsVersion = 8.2; 254 | DevelopmentTeam = AETQMU8637; 255 | ProvisioningStyle = Automatic; 256 | }; 257 | 780D3F991E2AD3A400398BF5 = { 258 | CreatedOnToolsVersion = 8.2; 259 | ProvisioningStyle = Automatic; 260 | TestTargetID = 780D3F8A1E2AD3A300398BF5; 261 | }; 262 | 780D3FAC1E2AD3C800398BF5 = { 263 | CreatedOnToolsVersion = 8.2; 264 | DevelopmentTeam = AETQMU8637; 265 | ProvisioningStyle = Automatic; 266 | }; 267 | }; 268 | }; 269 | buildConfigurationList = 780D3F861E2AD3A300398BF5 /* Build configuration list for PBXProject "Literals" */; 270 | compatibilityVersion = "Xcode 3.2"; 271 | developmentRegion = en; 272 | hasScannedForEncodings = 0; 273 | knownRegions = ( 274 | en, 275 | Base, 276 | ); 277 | mainGroup = 780D3F821E2AD3A300398BF5; 278 | productRefGroup = 780D3F8C1E2AD3A300398BF5 /* Products */; 279 | projectDirPath = ""; 280 | projectRoot = ""; 281 | targets = ( 282 | 780D3F8A1E2AD3A300398BF5 /* Literals */, 283 | 780D3F991E2AD3A400398BF5 /* LiteralsTests */, 284 | 780D3FAC1E2AD3C800398BF5 /* LiteralsExtension */, 285 | ); 286 | }; 287 | /* End PBXProject section */ 288 | 289 | /* Begin PBXResourcesBuildPhase section */ 290 | 780D3F891E2AD3A300398BF5 /* Resources */ = { 291 | isa = PBXResourcesBuildPhase; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | 780D3F911E2AD3A300398BF5 /* Assets.xcassets in Resources */, 295 | 780D3F941E2AD3A300398BF5 /* MainMenu.xib in Resources */, 296 | ); 297 | runOnlyForDeploymentPostprocessing = 0; 298 | }; 299 | 780D3F981E2AD3A400398BF5 /* Resources */ = { 300 | isa = PBXResourcesBuildPhase; 301 | buildActionMask = 2147483647; 302 | files = ( 303 | ); 304 | runOnlyForDeploymentPostprocessing = 0; 305 | }; 306 | 780D3FAB1E2AD3C800398BF5 /* Resources */ = { 307 | isa = PBXResourcesBuildPhase; 308 | buildActionMask = 2147483647; 309 | files = ( 310 | ); 311 | runOnlyForDeploymentPostprocessing = 0; 312 | }; 313 | /* End PBXResourcesBuildPhase section */ 314 | 315 | /* Begin PBXSourcesBuildPhase section */ 316 | 780D3F871E2AD3A300398BF5 /* Sources */ = { 317 | isa = PBXSourcesBuildPhase; 318 | buildActionMask = 2147483647; 319 | files = ( 320 | 780D3F8F1E2AD3A300398BF5 /* AppDelegate.swift in Sources */, 321 | ); 322 | runOnlyForDeploymentPostprocessing = 0; 323 | }; 324 | 780D3F961E2AD3A400398BF5 /* Sources */ = { 325 | isa = PBXSourcesBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | 784980EA1E2CD47900D18D3A /* ImageLiteralsConverter.swift in Sources */, 329 | 780D3FC51E2AD68600398BF5 /* ColorLiteralsConverterTests.swift in Sources */, 330 | 780D3FC61E2AD68D00398BF5 /* ColorLiteralsConverter.swift in Sources */, 331 | 784980E91E2CD47200D18D3A /* ImageLiteralsConverterTests.swift in Sources */, 332 | 780D3FC71E2AD68D00398BF5 /* TextConverter.swift in Sources */, 333 | ); 334 | runOnlyForDeploymentPostprocessing = 0; 335 | }; 336 | 780D3FA91E2AD3C800398BF5 /* Sources */ = { 337 | isa = PBXSourcesBuildPhase; 338 | buildActionMask = 2147483647; 339 | files = ( 340 | 784980E31E2CD25500D18D3A /* ImageLiteralsConverter.swift in Sources */, 341 | 784980E51E2CD26C00D18D3A /* ImageLiteralsCommand.swift in Sources */, 342 | 780D3FB51E2AD3C800398BF5 /* SourceEditorExtension.swift in Sources */, 343 | 780D3FB71E2AD3C800398BF5 /* ColorLiteralsCommand.swift in Sources */, 344 | 780D3FC31E2AD51A00398BF5 /* ColorLiteralsConverter.swift in Sources */, 345 | 780D3FC11E2AD40F00398BF5 /* TextConverter.swift in Sources */, 346 | 784980E71E2CD2A000D18D3A /* TextConverter+Command.swift in Sources */, 347 | ); 348 | runOnlyForDeploymentPostprocessing = 0; 349 | }; 350 | /* End PBXSourcesBuildPhase section */ 351 | 352 | /* Begin PBXTargetDependency section */ 353 | 780D3F9C1E2AD3A400398BF5 /* PBXTargetDependency */ = { 354 | isa = PBXTargetDependency; 355 | target = 780D3F8A1E2AD3A300398BF5 /* Literals */; 356 | targetProxy = 780D3F9B1E2AD3A400398BF5 /* PBXContainerItemProxy */; 357 | }; 358 | 780D3FBA1E2AD3C800398BF5 /* PBXTargetDependency */ = { 359 | isa = PBXTargetDependency; 360 | target = 780D3FAC1E2AD3C800398BF5 /* LiteralsExtension */; 361 | targetProxy = 780D3FB91E2AD3C800398BF5 /* PBXContainerItemProxy */; 362 | }; 363 | /* End PBXTargetDependency section */ 364 | 365 | /* Begin PBXVariantGroup section */ 366 | 780D3F921E2AD3A300398BF5 /* MainMenu.xib */ = { 367 | isa = PBXVariantGroup; 368 | children = ( 369 | 780D3F931E2AD3A300398BF5 /* Base */, 370 | ); 371 | name = MainMenu.xib; 372 | sourceTree = ""; 373 | }; 374 | /* End PBXVariantGroup section */ 375 | 376 | /* Begin XCBuildConfiguration section */ 377 | 780D3FA11E2AD3A400398BF5 /* Debug */ = { 378 | isa = XCBuildConfiguration; 379 | buildSettings = { 380 | ALWAYS_SEARCH_USER_PATHS = NO; 381 | CLANG_ANALYZER_NONNULL = YES; 382 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 383 | CLANG_CXX_LIBRARY = "libc++"; 384 | CLANG_ENABLE_MODULES = YES; 385 | CLANG_ENABLE_OBJC_ARC = YES; 386 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 387 | CLANG_WARN_BOOL_CONVERSION = YES; 388 | CLANG_WARN_COMMA = YES; 389 | CLANG_WARN_CONSTANT_CONVERSION = YES; 390 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 391 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 392 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 393 | CLANG_WARN_EMPTY_BODY = YES; 394 | CLANG_WARN_ENUM_CONVERSION = YES; 395 | CLANG_WARN_INFINITE_RECURSION = YES; 396 | CLANG_WARN_INT_CONVERSION = YES; 397 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 398 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 399 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 400 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 401 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 402 | CLANG_WARN_STRICT_PROTOTYPES = YES; 403 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 404 | CLANG_WARN_UNREACHABLE_CODE = YES; 405 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 406 | CODE_SIGN_IDENTITY = "-"; 407 | COPY_PHASE_STRIP = NO; 408 | DEBUG_INFORMATION_FORMAT = dwarf; 409 | ENABLE_STRICT_OBJC_MSGSEND = YES; 410 | ENABLE_TESTABILITY = YES; 411 | GCC_C_LANGUAGE_STANDARD = gnu99; 412 | GCC_DYNAMIC_NO_PIC = NO; 413 | GCC_NO_COMMON_BLOCKS = YES; 414 | GCC_OPTIMIZATION_LEVEL = 0; 415 | GCC_PREPROCESSOR_DEFINITIONS = ( 416 | "DEBUG=1", 417 | "$(inherited)", 418 | ); 419 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 420 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 421 | GCC_WARN_UNDECLARED_SELECTOR = YES; 422 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 423 | GCC_WARN_UNUSED_FUNCTION = YES; 424 | GCC_WARN_UNUSED_VARIABLE = YES; 425 | MACOSX_DEPLOYMENT_TARGET = 10.11; 426 | MTL_ENABLE_DEBUG_INFO = YES; 427 | ONLY_ACTIVE_ARCH = YES; 428 | SDKROOT = macosx; 429 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 430 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 431 | SWIFT_VERSION = 5.0; 432 | }; 433 | name = Debug; 434 | }; 435 | 780D3FA21E2AD3A400398BF5 /* Release */ = { 436 | isa = XCBuildConfiguration; 437 | buildSettings = { 438 | ALWAYS_SEARCH_USER_PATHS = NO; 439 | CLANG_ANALYZER_NONNULL = YES; 440 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 441 | CLANG_CXX_LIBRARY = "libc++"; 442 | CLANG_ENABLE_MODULES = YES; 443 | CLANG_ENABLE_OBJC_ARC = YES; 444 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 445 | CLANG_WARN_BOOL_CONVERSION = YES; 446 | CLANG_WARN_COMMA = YES; 447 | CLANG_WARN_CONSTANT_CONVERSION = YES; 448 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 449 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 450 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 451 | CLANG_WARN_EMPTY_BODY = YES; 452 | CLANG_WARN_ENUM_CONVERSION = YES; 453 | CLANG_WARN_INFINITE_RECURSION = YES; 454 | CLANG_WARN_INT_CONVERSION = YES; 455 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 456 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 457 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 458 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 459 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 460 | CLANG_WARN_STRICT_PROTOTYPES = YES; 461 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 462 | CLANG_WARN_UNREACHABLE_CODE = YES; 463 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 464 | CODE_SIGN_IDENTITY = "-"; 465 | COPY_PHASE_STRIP = NO; 466 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 467 | ENABLE_NS_ASSERTIONS = NO; 468 | ENABLE_STRICT_OBJC_MSGSEND = YES; 469 | GCC_C_LANGUAGE_STANDARD = gnu99; 470 | GCC_NO_COMMON_BLOCKS = YES; 471 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 472 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 473 | GCC_WARN_UNDECLARED_SELECTOR = YES; 474 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 475 | GCC_WARN_UNUSED_FUNCTION = YES; 476 | GCC_WARN_UNUSED_VARIABLE = YES; 477 | MACOSX_DEPLOYMENT_TARGET = 10.11; 478 | MTL_ENABLE_DEBUG_INFO = NO; 479 | SDKROOT = macosx; 480 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 481 | SWIFT_VERSION = 5.0; 482 | }; 483 | name = Release; 484 | }; 485 | 780D3FA41E2AD3A400398BF5 /* Debug */ = { 486 | isa = XCBuildConfiguration; 487 | buildSettings = { 488 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 489 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 490 | CODE_SIGN_IDENTITY = "Mac Developer"; 491 | COMBINE_HIDPI_IMAGES = YES; 492 | DEVELOPMENT_TEAM = AETQMU8637; 493 | INFOPLIST_FILE = Literals/Info.plist; 494 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 495 | PRODUCT_BUNDLE_IDENTIFIER = com.igorpalaguta.Literals; 496 | PRODUCT_NAME = "$(TARGET_NAME)"; 497 | }; 498 | name = Debug; 499 | }; 500 | 780D3FA51E2AD3A400398BF5 /* Release */ = { 501 | isa = XCBuildConfiguration; 502 | buildSettings = { 503 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 504 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 505 | CODE_SIGN_IDENTITY = "Mac Developer"; 506 | COMBINE_HIDPI_IMAGES = YES; 507 | DEVELOPMENT_TEAM = AETQMU8637; 508 | INFOPLIST_FILE = Literals/Info.plist; 509 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 510 | PRODUCT_BUNDLE_IDENTIFIER = com.igorpalaguta.Literals; 511 | PRODUCT_NAME = "$(TARGET_NAME)"; 512 | }; 513 | name = Release; 514 | }; 515 | 780D3FA71E2AD3A400398BF5 /* Debug */ = { 516 | isa = XCBuildConfiguration; 517 | buildSettings = { 518 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 519 | BUNDLE_LOADER = "$(TEST_HOST)"; 520 | CODE_SIGN_IDENTITY = "Mac Developer"; 521 | COMBINE_HIDPI_IMAGES = YES; 522 | DEVELOPMENT_TEAM = ""; 523 | INFOPLIST_FILE = LiteralsTests/Info.plist; 524 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 525 | PRODUCT_BUNDLE_IDENTIFIER = com.igorpalaguta.LiteralsTests; 526 | PRODUCT_NAME = "$(TARGET_NAME)"; 527 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Literals.app/Contents/MacOS/Literals"; 528 | }; 529 | name = Debug; 530 | }; 531 | 780D3FA81E2AD3A400398BF5 /* Release */ = { 532 | isa = XCBuildConfiguration; 533 | buildSettings = { 534 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 535 | BUNDLE_LOADER = "$(TEST_HOST)"; 536 | CODE_SIGN_IDENTITY = "Mac Developer"; 537 | COMBINE_HIDPI_IMAGES = YES; 538 | DEVELOPMENT_TEAM = ""; 539 | INFOPLIST_FILE = LiteralsTests/Info.plist; 540 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 541 | PRODUCT_BUNDLE_IDENTIFIER = com.igorpalaguta.LiteralsTests; 542 | PRODUCT_NAME = "$(TARGET_NAME)"; 543 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Literals.app/Contents/MacOS/Literals"; 544 | }; 545 | name = Release; 546 | }; 547 | 780D3FBD1E2AD3C900398BF5 /* Debug */ = { 548 | isa = XCBuildConfiguration; 549 | buildSettings = { 550 | CODE_SIGN_ENTITLEMENTS = LiteralsExtension/LiteralsExtension.entitlements; 551 | CODE_SIGN_IDENTITY = "Mac Developer"; 552 | COMBINE_HIDPI_IMAGES = YES; 553 | DEVELOPMENT_TEAM = AETQMU8637; 554 | INFOPLIST_FILE = LiteralsExtension/Info.plist; 555 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks"; 556 | MACOSX_DEPLOYMENT_TARGET = 10.11; 557 | PRODUCT_BUNDLE_IDENTIFIER = com.igorpalaguta.Literals.LiteralsExtension; 558 | PRODUCT_NAME = "Convert Literals"; 559 | SKIP_INSTALL = YES; 560 | }; 561 | name = Debug; 562 | }; 563 | 780D3FBE1E2AD3C900398BF5 /* Release */ = { 564 | isa = XCBuildConfiguration; 565 | buildSettings = { 566 | CODE_SIGN_ENTITLEMENTS = LiteralsExtension/LiteralsExtension.entitlements; 567 | CODE_SIGN_IDENTITY = "Mac Developer"; 568 | COMBINE_HIDPI_IMAGES = YES; 569 | DEVELOPMENT_TEAM = AETQMU8637; 570 | INFOPLIST_FILE = LiteralsExtension/Info.plist; 571 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks"; 572 | MACOSX_DEPLOYMENT_TARGET = 10.11; 573 | PRODUCT_BUNDLE_IDENTIFIER = com.igorpalaguta.Literals.LiteralsExtension; 574 | PRODUCT_NAME = "Convert Literals"; 575 | SKIP_INSTALL = YES; 576 | }; 577 | name = Release; 578 | }; 579 | /* End XCBuildConfiguration section */ 580 | 581 | /* Begin XCConfigurationList section */ 582 | 780D3F861E2AD3A300398BF5 /* Build configuration list for PBXProject "Literals" */ = { 583 | isa = XCConfigurationList; 584 | buildConfigurations = ( 585 | 780D3FA11E2AD3A400398BF5 /* Debug */, 586 | 780D3FA21E2AD3A400398BF5 /* Release */, 587 | ); 588 | defaultConfigurationIsVisible = 0; 589 | defaultConfigurationName = Release; 590 | }; 591 | 780D3FA31E2AD3A400398BF5 /* Build configuration list for PBXNativeTarget "Literals" */ = { 592 | isa = XCConfigurationList; 593 | buildConfigurations = ( 594 | 780D3FA41E2AD3A400398BF5 /* Debug */, 595 | 780D3FA51E2AD3A400398BF5 /* Release */, 596 | ); 597 | defaultConfigurationIsVisible = 0; 598 | defaultConfigurationName = Release; 599 | }; 600 | 780D3FA61E2AD3A400398BF5 /* Build configuration list for PBXNativeTarget "LiteralsTests" */ = { 601 | isa = XCConfigurationList; 602 | buildConfigurations = ( 603 | 780D3FA71E2AD3A400398BF5 /* Debug */, 604 | 780D3FA81E2AD3A400398BF5 /* Release */, 605 | ); 606 | defaultConfigurationIsVisible = 0; 607 | defaultConfigurationName = Release; 608 | }; 609 | 780D3FBC1E2AD3C900398BF5 /* Build configuration list for PBXNativeTarget "LiteralsExtension" */ = { 610 | isa = XCConfigurationList; 611 | buildConfigurations = ( 612 | 780D3FBD1E2AD3C900398BF5 /* Debug */, 613 | 780D3FBE1E2AD3C900398BF5 /* Release */, 614 | ); 615 | defaultConfigurationIsVisible = 0; 616 | defaultConfigurationName = Release; 617 | }; 618 | /* End XCConfigurationList section */ 619 | }; 620 | rootObject = 780D3F831E2AD3A300398BF5 /* Project object */; 621 | } 622 | -------------------------------------------------------------------------------- /Literals.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Literals/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | 3 | @NSApplicationMain 4 | class AppDelegate: NSObject, NSApplicationDelegate { 5 | 6 | @IBOutlet var window: NSWindow! 7 | 8 | func applicationDidFinishLaunching(_ aNotification: Notification) { 9 | // Insert code here to initialize your application 10 | } 11 | 12 | func applicationWillTerminate(_ aNotification: Notification) { 13 | // Insert code here to tear down your application 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Literals/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Literals/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Literals/Assets.xcassets/FCBarcelona.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "FCBarcelona.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Literals/Assets.xcassets/FCBarcelona.imageset/FCBarcelona.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Igor-Palaguta/LiteralsExtension/f4ccee989087c562a1969357a241cc810931e75c/Literals/Assets.xcassets/FCBarcelona.imageset/FCBarcelona.png -------------------------------------------------------------------------------- /Literals/Assets.xcassets/FCDnipro.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "FCDnipro.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Literals/Assets.xcassets/FCDnipro.imageset/FCDnipro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Igor-Palaguta/LiteralsExtension/f4ccee989087c562a1969357a241cc810931e75c/Literals/Assets.xcassets/FCDnipro.imageset/FCDnipro.png -------------------------------------------------------------------------------- /Literals/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | Default 538 | 539 | 540 | 541 | 542 | 543 | 544 | Left to Right 545 | 546 | 547 | 548 | 549 | 550 | 551 | Right to Left 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | Default 563 | 564 | 565 | 566 | 567 | 568 | 569 | Left to Right 570 | 571 | 572 | 573 | 574 | 575 | 576 | Right to Left 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | -------------------------------------------------------------------------------- /Literals/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2017 Igor Palaguta. All rights reserved. 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /LiteralsExtension/ColorLiteralsCommand.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XcodeKit 3 | 4 | final class ColorLiteralsCommand: NSObject, XCSourceEditorCommand { 5 | func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void) { 6 | let converter = ColorLiteralsConverter() 7 | converter.convert(with: invocation, completionHandler: completionHandler) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /LiteralsExtension/ColorLiteralsConverter.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | struct ColorLiteralsConverter: TextConverter { 4 | private static let rgbaColorRegex: NSRegularExpression = { 5 | let componentFormat = "%@:\\s*((?:[\\d\\.]+(?:\\s*/\\s*[\\d\\.]+)?))" 6 | let rgba = ["red", "green", "blue", "alpha"] 7 | let rgbaPattern = rgba 8 | .map { String(format: componentFormat, $0) } 9 | .joined(separator: "\\s*,\\s*") 10 | 11 | let pattern = "(?:(?:UI|NS)Color(?:\\.init)?)\\(\\s*\(rgbaPattern)\\s*\\)" 12 | 13 | return try! NSRegularExpression(pattern: pattern, options: []) 14 | }() 15 | 16 | func convert(text: String, in range: NSRange) -> String { 17 | var result = text as NSString 18 | 19 | let matches = Self.rgbaColorRegex.matches(in: text, 20 | options: [], 21 | range: range) 22 | 23 | for match in matches.reversed() { 24 | let components = [ 25 | ("red", result.substring(with: match.range(at: 1))), 26 | ("green", result.substring(with: match.range(at: 2))), 27 | ("blue", result.substring(with: match.range(at: 3))), 28 | ("alpha", result.substring(with: match.range(at: 4))) 29 | ] 30 | .map { "\($0): \($1.evaluated())" } 31 | .joined(separator: ", ") 32 | 33 | result = result.replacingCharacters(in: match.range, with: "#colorLiteral(\(components))") as NSString 34 | } 35 | 36 | return result as String 37 | } 38 | } 39 | 40 | private extension String { 41 | private static let formatter: NumberFormatter = { 42 | let formatter = NumberFormatter() 43 | formatter.numberStyle = .decimal 44 | formatter.groupingSeparator = "" 45 | formatter.decimalSeparator = "." 46 | formatter.minimumIntegerDigits = 1 47 | formatter.maximumFractionDigits = 3 48 | return formatter 49 | }() 50 | 51 | func evaluated() -> String { 52 | guard contains("/") else { 53 | return self 54 | } 55 | 56 | // 1.0 casts expression to float 57 | // e.g: 5 / 10 = 0, but 1.0 * 5 / 10 = 0.5 58 | let expression = NSExpression(format: "1.0 * \(self)") 59 | guard let result = expression.expressionValue(with: nil, context: nil) as? NSNumber, 60 | let formattedResult = Self.formatter.string(from: result) else { 61 | return self 62 | } 63 | return formattedResult 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /LiteralsExtension/ImageLiteralsCommand.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XcodeKit 3 | 4 | final class ImageLiteralsCommand: NSObject, XCSourceEditorCommand { 5 | func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void) { 6 | let converter = ImageLiteralsConverter() 7 | converter.convert(with: invocation, completionHandler: completionHandler) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /LiteralsExtension/ImageLiteralsConverter.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | struct ImageLiteralsConverter: TextConverter { 4 | private static let imageRegex: NSRegularExpression = { 5 | let pattern = "(?:UIImage(?:\\.init)?)\\(\\s*named:\\s*\"(.+?)\"\\s*\\)" 6 | return try! NSRegularExpression(pattern: pattern, options: []) 7 | }() 8 | 9 | func convert(text: String, in range: NSRange) -> String { 10 | var result = text as NSString 11 | 12 | let matches = Self.imageRegex.matches(in: text, 13 | options: [], 14 | range: range) 15 | 16 | for match in matches.reversed() { 17 | let name = result.substring(with: match.range(at: 1)) 18 | result = result.replacingCharacters(in: match.range, with: "#imageLiteral(resourceName: \"\(name)\")") as NSString 19 | } 20 | return result as String 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /LiteralsExtension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Convert Literals 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | XCSourceEditorCommandDefinitions 30 | 31 | 32 | XCSourceEditorCommandClassName 33 | $(PRODUCT_MODULE_NAME).ColorLiteralsCommand 34 | XCSourceEditorCommandIdentifier 35 | $(PRODUCT_BUNDLE_IDENTIFIER).ColorLiteralsCommand 36 | XCSourceEditorCommandName 37 | Use Color Literals 38 | 39 | 40 | XCSourceEditorCommandClassName 41 | $(PRODUCT_MODULE_NAME).ImageLiteralsCommand 42 | XCSourceEditorCommandIdentifier 43 | $(PRODUCT_BUNDLE_IDENTIFIER).ImageLiteralsCommand 44 | XCSourceEditorCommandName 45 | Use Image Literals 46 | 47 | 48 | XCSourceEditorExtensionPrincipalClass 49 | $(PRODUCT_MODULE_NAME).SourceEditorExtension 50 | 51 | NSExtensionPointIdentifier 52 | com.apple.dt.Xcode.extension.source-editor 53 | 54 | NSHumanReadableCopyright 55 | Copyright © 2017 Igor Palaguta. All rights reserved. 56 | 57 | 58 | -------------------------------------------------------------------------------- /LiteralsExtension/LiteralsExtension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LiteralsExtension/SourceEditorExtension.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XcodeKit 3 | 4 | final class SourceEditorExtension: NSObject, XCSourceEditorExtension { 5 | } 6 | -------------------------------------------------------------------------------- /LiteralsExtension/TextConverter+Command.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XcodeKit 3 | 4 | enum TextConverterError: Error { 5 | case notSwiftLanguage 6 | } 7 | 8 | extension TextConverter { 9 | func convert(with invocation: XCSourceEditorCommandInvocation, 10 | completionHandler: @escaping (Error?) -> Void) { 11 | 12 | let supportedContentTypes = ["public.swift-source", "com.apple.dt.playground"] 13 | guard supportedContentTypes.contains(invocation.buffer.contentUTI) else { 14 | return completionHandler(TextConverterError.notSwiftLanguage) 15 | } 16 | 17 | for selection in invocation.selections.reversed() { 18 | let linesSet = IndexSet(selection.start.line...selection.end.line) 19 | 20 | let lines = invocation[linesAt: linesSet] 21 | let code = lines.joined() 22 | 23 | let tailLength = invocation[lineAt: selection.end.line].nsLength - selection.end.column 24 | 25 | let changedCode = convert(text: code, 26 | in: NSRange(location: selection.start.column, length: code.nsLength - tailLength - selection.start.column)) 27 | 28 | let changedLines = changedCode.lines 29 | invocation.buffer.lines.replaceObjects(in: NSRange(location: selection.start.line, length: linesSet.count), 30 | withObjectsFrom: changedLines, 31 | range: NSRange(location: 0, length: changedLines.count)) 32 | } 33 | 34 | completionHandler(nil) 35 | } 36 | } 37 | 38 | private extension XCSourceEditorCommandInvocation { 39 | var selections: [XCSourceTextRange] { 40 | let selections = buffer.selections.compactMap { $0 as? XCSourceTextRange } 41 | 42 | if selections.isEmpty { 43 | return [bufferRange] 44 | } 45 | 46 | if selections.count == 1, let selection = selections.first, selection.start == selection.end { 47 | return [bufferRange] 48 | } 49 | 50 | return selections 51 | } 52 | 53 | subscript(linesAt indexSet: IndexSet) -> [String] { 54 | return buffer.lines.objects(at: indexSet).map { $0 as! String } 55 | } 56 | 57 | subscript(lineAt index: Int) -> String { 58 | return buffer.lines[index] as! String 59 | } 60 | 61 | private var bufferRange: XCSourceTextRange { 62 | let start = XCSourceTextPosition(line: 0, column: 0) 63 | let end = XCSourceTextPosition(line: buffer.lines.count - 1, column: lastLine.nsLength) 64 | return XCSourceTextRange(start: start, end: end) 65 | } 66 | 67 | private var lastLine: String { 68 | return buffer.lines.lastObject! as! String 69 | } 70 | } 71 | 72 | extension XCSourceTextPosition: Equatable { 73 | public static func == (lhs: XCSourceTextPosition, rhs: XCSourceTextPosition) -> Bool { 74 | return lhs.line == rhs.line && lhs.column == rhs.column 75 | } 76 | } 77 | 78 | private extension String { 79 | var nsLength: Int { 80 | return (self as NSString).length 81 | } 82 | 83 | var lines: [String] { 84 | let lines = components(separatedBy: "\n").map { $0 + "\n" } 85 | if hasSuffix("\n") { 86 | return Array(lines.dropLast()) 87 | } 88 | return lines 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /LiteralsExtension/TextConverter.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | protocol TextConverter { 4 | func convert(text: String, in range: NSRange) -> String 5 | } 6 | -------------------------------------------------------------------------------- /LiteralsTests/ColorLiteralsConverterTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | final class ColorLiteralsConverterTests: XCTestCase { 4 | private let converter = ColorLiteralsConverter() 5 | 6 | private func convert(_ text: String, in range: NSRange? = nil) -> String { 7 | return converter.convert(text: text, in: range ?? NSRange(location: 0, length: (text as NSString).length)) 8 | } 9 | 10 | func testUIColor() { 11 | XCTAssertEqual(convert("UIColor(red: 1, green: 0, blue: 0, alpha: 1)"), "#colorLiteral(red: 1, green: 0, blue: 0, alpha: 1)") 12 | } 13 | 14 | func testNSColor() { 15 | XCTAssertEqual(convert("NSColor(red: 1, green: 1, blue: 0, alpha: 1)"), "#colorLiteral(red: 1, green: 1, blue: 0, alpha: 1)") 16 | } 17 | 18 | func testExplicitInit() { 19 | XCTAssertEqual(convert("NSColor.init(red: 0.5, green: 0.5, blue: 0.5, alpha: 1)"), "#colorLiteral(red: 0.5, green: 0.5, blue: 0.5, alpha: 1)") 20 | XCTAssertEqual(convert("UIColor.init(red: 0.2, green: 0.2, blue: 0.2, alpha: 0.5)"), "#colorLiteral(red: 0.2, green: 0.2, blue: 0.2, alpha: 0.5)") 21 | } 22 | 23 | func testMultilineConvert() { 24 | XCTAssertEqual(convert("UIColor(red: 1,\ngreen: 0,\nblue: 0,\nalpha: 1)"), "#colorLiteral(red: 1, green: 0, blue: 0, alpha: 1)") 25 | XCTAssertEqual(convert("UIColor(red: 1, green: 0, blue: 0, alpha: 1)\nNSColor(red: 1, green: 1, blue: 0, alpha: 1)"), "#colorLiteral(red: 1, green: 0, blue: 0, alpha: 1)\n#colorLiteral(red: 1, green: 1, blue: 0, alpha: 1)") 26 | } 27 | 28 | func testLeadingSpace() { 29 | XCTAssertEqual(convert("NSColor( red: 1, green: 0, blue: 0, alpha: 1)"), "#colorLiteral(red: 1, green: 0, blue: 0, alpha: 1)") 30 | } 31 | 32 | func testRange() { 33 | XCTAssertEqual(convert("UIColor(red: 1, green: 0, blue: 0, alpha: 1), UIColor(red: 0, green: 1, blue: 0, alpha: 1)", in: NSRange(location: 46, length: 44)), "UIColor(red: 1, green: 0, blue: 0, alpha: 1), #colorLiteral(red: 0, green: 1, blue: 0, alpha: 1)") 34 | XCTAssertEqual(convert("UIColor(red: 1, green: 0, blue: 0, alpha: 1)", in: NSRange(location: 1, length: 43)), "UIColor(red: 1, green: 0, blue: 0, alpha: 1)") 35 | } 36 | 37 | func testDivision() { 38 | XCTAssertEqual( 39 | convert("UIColor(red: 255/255, green: 0, blue: 0, alpha: 1)"), 40 | "#colorLiteral(red: 1, green: 0, blue: 0, alpha: 1)" 41 | ) 42 | 43 | XCTAssertEqual( 44 | convert("UIColor(red: 5 / 255, green: 0, blue: 0, alpha: 1)"), 45 | "#colorLiteral(red: 0.02, green: 0, blue: 0, alpha: 1)" 46 | ) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /LiteralsTests/ImageLiteralsConverterTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | final class ImageLiteralsConverterTests: XCTestCase { 4 | private let converter = ImageLiteralsConverter() 5 | 6 | private func convert(_ text: String, in range: NSRange? = nil) -> String { 7 | return converter.convert(text: text, in: range ?? NSRange(location: 0, length: (text as NSString).length)) 8 | } 9 | 10 | // image literals don't work in tests, compare with strings 11 | private func imageLiteral(_ resourceName: String) -> String { 12 | return "#" + "imageLiteral(resourceName: \"\(resourceName)\")" 13 | } 14 | 15 | func testConvert() { 16 | XCTAssertEqual(convert("UIImage(named: \"FCDnipro.png\")"), imageLiteral("FCDnipro.png")) 17 | } 18 | 19 | func testWithoutExtension() { 20 | XCTAssertEqual(convert("UIImage(named: \"FCDnipro\")"), imageLiteral("FCDnipro")) 21 | } 22 | 23 | func testExplicitInit() { 24 | XCTAssertEqual(convert("UIImage.init(named: \"FCDnipro\")"), imageLiteral("FCDnipro")) 25 | } 26 | 27 | func testMultilineConvert() { 28 | XCTAssertEqual(convert("UIImage(named: \"FCDnipro\"), UIImage.init(named: \"FCBarcelona\")"), "\(imageLiteral("FCDnipro")), \(imageLiteral("FCBarcelona"))") 29 | } 30 | 31 | func testLeadingSpace() { 32 | XCTAssertEqual(convert("UIImage( named: \"FCDnipro\" )"), imageLiteral("FCDnipro")) 33 | } 34 | 35 | func testRange() { 36 | XCTAssertEqual(convert("UIImage(named: \"FCDnipro\"), UIImage(named: \"FCBarcelona\")", in: NSRange(location: 0, length: 26)), "\(imageLiteral("FCDnipro")), UIImage(named: \"FCBarcelona\")") 37 | XCTAssertEqual(convert("UIImage(named: \"FCDnipro\"), UIImage(named: \"FCBarcelona\")", in: NSRange(location: 28, length: 29)), "UIImage(named: \"FCDnipro\"), \(imageLiteral("FCBarcelona"))") 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /LiteralsTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Literals Extension 2 | ================== 3 | 4 | This Xcode Source Code Extension generates Color and Image Literals 5 | 6 | Usage 7 | ----- 8 | 9 | Select code with colors or images that should be converted to literals. If nothing selected, whole file is converted 10 | 11 | ![Demo](Demo.gif) 12 | 13 | Installation 14 | ------------ 15 | 16 | 1. Open ``Literals.xcodeproj`` 17 | 2. Enable target signing for both the Application and the Source Code Extension using your own developer ID 18 | 3. Product > Archive 19 | 4. Right click archive > Show in Finder 20 | 5. Right click archive > Show Package Contents 21 | 6. Open Products, Applications 22 | 7. Drag ``Literals.app`` to your Applications folder 23 | 8. Run ``Literals.app`` and exit again. 24 | 9. Go to System Preferences -> Extensions -> Xcode Source Editor and enable the extension 25 | 10. The menu-item should now be available from Xcode's Editor menu. 26 | --------------------------------------------------------------------------------