├── .gitignore ├── Marker.xcodeproj ├── project.pbxproj └── xcshareddata │ └── xcschemes │ ├── Marker.xcscheme │ └── MarkerExtension.xcscheme ├── Marker ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Base.lproj │ └── Main.storyboard ├── Info.plist ├── Marker.entitlements └── ViewController.swift ├── MarkerExtension ├── Info.plist ├── MarkerCommand.swift ├── MarkerExtension.entitlements └── SourceEditorExtension.swift ├── MarkerTests ├── Info.plist └── MarkerTests.swift └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/xcode,macos,swift 3 | # Edit at https://www.gitignore.io/?templates=xcode,macos,swift 4 | 5 | ### macOS ### 6 | # General 7 | .DS_Store 8 | .AppleDouble 9 | .LSOverride 10 | 11 | # Icon must end with two \r 12 | Icon 13 | 14 | # Thumbnails 15 | ._* 16 | 17 | # Files that might appear in the root of a volume 18 | .DocumentRevisions-V100 19 | .fseventsd 20 | .Spotlight-V100 21 | .TemporaryItems 22 | .Trashes 23 | .VolumeIcon.icns 24 | .com.apple.timemachine.donotpresent 25 | 26 | # Directories potentially created on remote AFP share 27 | .AppleDB 28 | .AppleDesktop 29 | Network Trash Folder 30 | Temporary Items 31 | .apdisk 32 | 33 | ### Swift ### 34 | # Xcode 35 | # 36 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 37 | 38 | ## Build generated 39 | build/ 40 | DerivedData/ 41 | 42 | ## Various settings 43 | *.pbxuser 44 | !default.pbxuser 45 | *.mode1v3 46 | !default.mode1v3 47 | *.mode2v3 48 | !default.mode2v3 49 | *.perspectivev3 50 | !default.perspectivev3 51 | xcuserdata/ 52 | 53 | ## Other 54 | *.moved-aside 55 | *.xccheckout 56 | *.xcscmblueprint 57 | 58 | ## Obj-C/Swift specific 59 | *.hmap 60 | *.ipa 61 | *.dSYM.zip 62 | *.dSYM 63 | 64 | ## Playgrounds 65 | timeline.xctimeline 66 | playground.xcworkspace 67 | 68 | # Swift Package Manager 69 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 70 | # Packages/ 71 | # Package.pins 72 | # Package.resolved 73 | .build/ 74 | 75 | # CocoaPods 76 | # We recommend against adding the Pods directory to your .gitignore. However 77 | # you should judge for yourself, the pros and cons are mentioned at: 78 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 79 | # Pods/ 80 | # Add this line if you want to avoid checking in source code from the Xcode workspace 81 | # *.xcworkspace 82 | 83 | # Carthage 84 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 85 | # Carthage/Checkouts 86 | 87 | Carthage/Build 88 | 89 | # fastlane 90 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 91 | # screenshots whenever they are needed. 92 | # For more information about the recommended setup visit: 93 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 94 | 95 | fastlane/report.xml 96 | fastlane/Preview.html 97 | fastlane/screenshots/**/*.png 98 | fastlane/test_output 99 | 100 | # Code Injection 101 | # After new code Injection tools there's a generated folder /iOSInjectionProject 102 | # https://github.com/johnno1962/injectionforxcode 103 | 104 | iOSInjectionProject/ 105 | 106 | ### Xcode ### 107 | # Xcode 108 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 109 | 110 | ## User settings 111 | 112 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 113 | 114 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 115 | 116 | ### Xcode Patch ### 117 | *.xcodeproj/* 118 | !*.xcodeproj/project.pbxproj 119 | !*.xcodeproj/xcshareddata/ 120 | !*.xcworkspace/contents.xcworkspacedata 121 | /*.gcno 122 | **/xcshareddata/WorkspaceSettings.xcsettings 123 | 124 | # End of https://www.gitignore.io/api/xcode,macos,swift 125 | -------------------------------------------------------------------------------- /Marker.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | ED00123B2245550100335F3D /* MarkerCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED66813F223C75CC00E10E0D /* MarkerCommand.swift */; }; 11 | ED03CD91223EC98D00A1DCFD /* MarkerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED03CD90223EC98D00A1DCFD /* MarkerTests.swift */; }; 12 | ED03CD99223EC9AD00A1DCFD /* XcodeKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED03CD98223EC9AD00A1DCFD /* XcodeKit.framework */; }; 13 | ED668125223C75AF00E10E0D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED668124223C75AF00E10E0D /* AppDelegate.swift */; }; 14 | ED668127223C75AF00E10E0D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED668126223C75AF00E10E0D /* ViewController.swift */; }; 15 | ED668129223C75B100E10E0D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ED668128223C75B100E10E0D /* Assets.xcassets */; }; 16 | ED66812C223C75B100E10E0D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = ED66812A223C75B100E10E0D /* Main.storyboard */; }; 17 | ED66813B223C75CC00E10E0D /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED66813A223C75CC00E10E0D /* Cocoa.framework */; }; 18 | ED66813E223C75CC00E10E0D /* SourceEditorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED66813D223C75CC00E10E0D /* SourceEditorExtension.swift */; }; 19 | ED668140223C75CC00E10E0D /* MarkerCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED66813F223C75CC00E10E0D /* MarkerCommand.swift */; }; 20 | ED668145223C75CC00E10E0D /* MarkerExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = ED668138223C75CC00E10E0D /* MarkerExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXContainerItemProxy section */ 24 | ED03CD93223EC98D00A1DCFD /* PBXContainerItemProxy */ = { 25 | isa = PBXContainerItemProxy; 26 | containerPortal = ED668119223C75AF00E10E0D /* Project object */; 27 | proxyType = 1; 28 | remoteGlobalIDString = ED668120223C75AF00E10E0D; 29 | remoteInfo = Marker; 30 | }; 31 | ED668143223C75CC00E10E0D /* PBXContainerItemProxy */ = { 32 | isa = PBXContainerItemProxy; 33 | containerPortal = ED668119223C75AF00E10E0D /* Project object */; 34 | proxyType = 1; 35 | remoteGlobalIDString = ED668137223C75CC00E10E0D; 36 | remoteInfo = MarkerExtension; 37 | }; 38 | /* End PBXContainerItemProxy section */ 39 | 40 | /* Begin PBXCopyFilesBuildPhase section */ 41 | ED668149223C75CC00E10E0D /* Embed App Extensions */ = { 42 | isa = PBXCopyFilesBuildPhase; 43 | buildActionMask = 2147483647; 44 | dstPath = ""; 45 | dstSubfolderSpec = 13; 46 | files = ( 47 | ED668145223C75CC00E10E0D /* MarkerExtension.appex in Embed App Extensions */, 48 | ); 49 | name = "Embed App Extensions"; 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXCopyFilesBuildPhase section */ 53 | 54 | /* Begin PBXFileReference section */ 55 | ED03CD8E223EC98D00A1DCFD /* MarkerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MarkerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | ED03CD90223EC98D00A1DCFD /* MarkerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkerTests.swift; sourceTree = ""; }; 57 | ED03CD92223EC98D00A1DCFD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | ED03CD98223EC9AD00A1DCFD /* XcodeKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XcodeKit.framework; path = Library/Frameworks/XcodeKit.framework; sourceTree = DEVELOPER_DIR; }; 59 | ED668121223C75AF00E10E0D /* Marker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Marker.app; sourceTree = BUILT_PRODUCTS_DIR; }; 60 | ED668124223C75AF00E10E0D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 61 | ED668126223C75AF00E10E0D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 62 | ED668128223C75B100E10E0D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 63 | ED66812B223C75B100E10E0D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 64 | ED66812D223C75B100E10E0D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 65 | ED66812E223C75B100E10E0D /* Marker.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Marker.entitlements; sourceTree = ""; }; 66 | ED668138223C75CC00E10E0D /* MarkerExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MarkerExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | ED66813A223C75CC00E10E0D /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 68 | ED66813D223C75CC00E10E0D /* SourceEditorExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceEditorExtension.swift; sourceTree = ""; }; 69 | ED66813F223C75CC00E10E0D /* MarkerCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkerCommand.swift; sourceTree = ""; }; 70 | ED668141223C75CC00E10E0D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 71 | ED668142223C75CC00E10E0D /* MarkerExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MarkerExtension.entitlements; sourceTree = ""; }; 72 | /* End PBXFileReference section */ 73 | 74 | /* Begin PBXFrameworksBuildPhase section */ 75 | ED03CD8B223EC98D00A1DCFD /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | ED03CD99223EC9AD00A1DCFD /* XcodeKit.framework in Frameworks */, 80 | ); 81 | runOnlyForDeploymentPostprocessing = 0; 82 | }; 83 | ED66811E223C75AF00E10E0D /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | ); 88 | runOnlyForDeploymentPostprocessing = 0; 89 | }; 90 | ED668135223C75CC00E10E0D /* Frameworks */ = { 91 | isa = PBXFrameworksBuildPhase; 92 | buildActionMask = 2147483647; 93 | files = ( 94 | ED66813B223C75CC00E10E0D /* Cocoa.framework in Frameworks */, 95 | ); 96 | runOnlyForDeploymentPostprocessing = 0; 97 | }; 98 | /* End PBXFrameworksBuildPhase section */ 99 | 100 | /* Begin PBXGroup section */ 101 | ED03CD8F223EC98D00A1DCFD /* MarkerTests */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | ED03CD90223EC98D00A1DCFD /* MarkerTests.swift */, 105 | ED03CD92223EC98D00A1DCFD /* Info.plist */, 106 | ); 107 | path = MarkerTests; 108 | sourceTree = ""; 109 | }; 110 | ED668118223C75AF00E10E0D = { 111 | isa = PBXGroup; 112 | children = ( 113 | ED668123223C75AF00E10E0D /* Marker */, 114 | ED66813C223C75CC00E10E0D /* MarkerExtension */, 115 | ED03CD8F223EC98D00A1DCFD /* MarkerTests */, 116 | ED668139223C75CC00E10E0D /* Frameworks */, 117 | ED668122223C75AF00E10E0D /* Products */, 118 | ); 119 | sourceTree = ""; 120 | }; 121 | ED668122223C75AF00E10E0D /* Products */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | ED668121223C75AF00E10E0D /* Marker.app */, 125 | ED668138223C75CC00E10E0D /* MarkerExtension.appex */, 126 | ED03CD8E223EC98D00A1DCFD /* MarkerTests.xctest */, 127 | ); 128 | name = Products; 129 | sourceTree = ""; 130 | }; 131 | ED668123223C75AF00E10E0D /* Marker */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | ED668124223C75AF00E10E0D /* AppDelegate.swift */, 135 | ED668126223C75AF00E10E0D /* ViewController.swift */, 136 | ED668128223C75B100E10E0D /* Assets.xcassets */, 137 | ED66812A223C75B100E10E0D /* Main.storyboard */, 138 | ED66812D223C75B100E10E0D /* Info.plist */, 139 | ED66812E223C75B100E10E0D /* Marker.entitlements */, 140 | ); 141 | path = Marker; 142 | sourceTree = ""; 143 | }; 144 | ED668139223C75CC00E10E0D /* Frameworks */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | ED03CD98223EC9AD00A1DCFD /* XcodeKit.framework */, 148 | ED66813A223C75CC00E10E0D /* Cocoa.framework */, 149 | ); 150 | name = Frameworks; 151 | sourceTree = ""; 152 | }; 153 | ED66813C223C75CC00E10E0D /* MarkerExtension */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | ED66813D223C75CC00E10E0D /* SourceEditorExtension.swift */, 157 | ED66813F223C75CC00E10E0D /* MarkerCommand.swift */, 158 | ED668141223C75CC00E10E0D /* Info.plist */, 159 | ED668142223C75CC00E10E0D /* MarkerExtension.entitlements */, 160 | ); 161 | path = MarkerExtension; 162 | sourceTree = ""; 163 | }; 164 | /* End PBXGroup section */ 165 | 166 | /* Begin PBXNativeTarget section */ 167 | ED03CD8D223EC98D00A1DCFD /* MarkerTests */ = { 168 | isa = PBXNativeTarget; 169 | buildConfigurationList = ED03CD97223EC98D00A1DCFD /* Build configuration list for PBXNativeTarget "MarkerTests" */; 170 | buildPhases = ( 171 | ED03CD8A223EC98D00A1DCFD /* Sources */, 172 | ED03CD8B223EC98D00A1DCFD /* Frameworks */, 173 | ED03CD8C223EC98D00A1DCFD /* Resources */, 174 | ); 175 | buildRules = ( 176 | ); 177 | dependencies = ( 178 | ED03CD94223EC98D00A1DCFD /* PBXTargetDependency */, 179 | ); 180 | name = MarkerTests; 181 | productName = MarkerTests; 182 | productReference = ED03CD8E223EC98D00A1DCFD /* MarkerTests.xctest */; 183 | productType = "com.apple.product-type.bundle.unit-test"; 184 | }; 185 | ED668120223C75AF00E10E0D /* Marker */ = { 186 | isa = PBXNativeTarget; 187 | buildConfigurationList = ED668131223C75B100E10E0D /* Build configuration list for PBXNativeTarget "Marker" */; 188 | buildPhases = ( 189 | ED66811D223C75AF00E10E0D /* Sources */, 190 | ED66811E223C75AF00E10E0D /* Frameworks */, 191 | ED66811F223C75AF00E10E0D /* Resources */, 192 | ED668149223C75CC00E10E0D /* Embed App Extensions */, 193 | ); 194 | buildRules = ( 195 | ); 196 | dependencies = ( 197 | ED668144223C75CC00E10E0D /* PBXTargetDependency */, 198 | ); 199 | name = Marker; 200 | productName = Marker; 201 | productReference = ED668121223C75AF00E10E0D /* Marker.app */; 202 | productType = "com.apple.product-type.application"; 203 | }; 204 | ED668137223C75CC00E10E0D /* MarkerExtension */ = { 205 | isa = PBXNativeTarget; 206 | buildConfigurationList = ED668146223C75CC00E10E0D /* Build configuration list for PBXNativeTarget "MarkerExtension" */; 207 | buildPhases = ( 208 | ED668134223C75CC00E10E0D /* Sources */, 209 | ED668135223C75CC00E10E0D /* Frameworks */, 210 | ED668136223C75CC00E10E0D /* Resources */, 211 | ); 212 | buildRules = ( 213 | ); 214 | dependencies = ( 215 | ); 216 | name = MarkerExtension; 217 | productName = MarkerExtension; 218 | productReference = ED668138223C75CC00E10E0D /* MarkerExtension.appex */; 219 | productType = "com.apple.product-type.xcode-extension"; 220 | }; 221 | /* End PBXNativeTarget section */ 222 | 223 | /* Begin PBXProject section */ 224 | ED668119223C75AF00E10E0D /* Project object */ = { 225 | isa = PBXProject; 226 | attributes = { 227 | LastSwiftUpdateCheck = 1010; 228 | LastUpgradeCheck = 1010; 229 | ORGANIZATIONNAME = "Hot Beverage"; 230 | TargetAttributes = { 231 | ED03CD8D223EC98D00A1DCFD = { 232 | CreatedOnToolsVersion = 10.1; 233 | LastSwiftMigration = 1020; 234 | TestTargetID = ED668120223C75AF00E10E0D; 235 | }; 236 | ED668120223C75AF00E10E0D = { 237 | CreatedOnToolsVersion = 10.1; 238 | LastSwiftMigration = 1020; 239 | }; 240 | ED668137223C75CC00E10E0D = { 241 | CreatedOnToolsVersion = 10.1; 242 | LastSwiftMigration = 1020; 243 | }; 244 | }; 245 | }; 246 | buildConfigurationList = ED66811C223C75AF00E10E0D /* Build configuration list for PBXProject "Marker" */; 247 | compatibilityVersion = "Xcode 9.3"; 248 | developmentRegion = en; 249 | hasScannedForEncodings = 0; 250 | knownRegions = ( 251 | en, 252 | Base, 253 | ); 254 | mainGroup = ED668118223C75AF00E10E0D; 255 | productRefGroup = ED668122223C75AF00E10E0D /* Products */; 256 | projectDirPath = ""; 257 | projectRoot = ""; 258 | targets = ( 259 | ED668120223C75AF00E10E0D /* Marker */, 260 | ED668137223C75CC00E10E0D /* MarkerExtension */, 261 | ED03CD8D223EC98D00A1DCFD /* MarkerTests */, 262 | ); 263 | }; 264 | /* End PBXProject section */ 265 | 266 | /* Begin PBXResourcesBuildPhase section */ 267 | ED03CD8C223EC98D00A1DCFD /* Resources */ = { 268 | isa = PBXResourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | ); 272 | runOnlyForDeploymentPostprocessing = 0; 273 | }; 274 | ED66811F223C75AF00E10E0D /* Resources */ = { 275 | isa = PBXResourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | ED668129223C75B100E10E0D /* Assets.xcassets in Resources */, 279 | ED66812C223C75B100E10E0D /* Main.storyboard in Resources */, 280 | ); 281 | runOnlyForDeploymentPostprocessing = 0; 282 | }; 283 | ED668136223C75CC00E10E0D /* Resources */ = { 284 | isa = PBXResourcesBuildPhase; 285 | buildActionMask = 2147483647; 286 | files = ( 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | }; 290 | /* End PBXResourcesBuildPhase section */ 291 | 292 | /* Begin PBXSourcesBuildPhase section */ 293 | ED03CD8A223EC98D00A1DCFD /* Sources */ = { 294 | isa = PBXSourcesBuildPhase; 295 | buildActionMask = 2147483647; 296 | files = ( 297 | ED03CD91223EC98D00A1DCFD /* MarkerTests.swift in Sources */, 298 | ED00123B2245550100335F3D /* MarkerCommand.swift in Sources */, 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | ED66811D223C75AF00E10E0D /* Sources */ = { 303 | isa = PBXSourcesBuildPhase; 304 | buildActionMask = 2147483647; 305 | files = ( 306 | ED668127223C75AF00E10E0D /* ViewController.swift in Sources */, 307 | ED668125223C75AF00E10E0D /* AppDelegate.swift in Sources */, 308 | ); 309 | runOnlyForDeploymentPostprocessing = 0; 310 | }; 311 | ED668134223C75CC00E10E0D /* Sources */ = { 312 | isa = PBXSourcesBuildPhase; 313 | buildActionMask = 2147483647; 314 | files = ( 315 | ED66813E223C75CC00E10E0D /* SourceEditorExtension.swift in Sources */, 316 | ED668140223C75CC00E10E0D /* MarkerCommand.swift in Sources */, 317 | ); 318 | runOnlyForDeploymentPostprocessing = 0; 319 | }; 320 | /* End PBXSourcesBuildPhase section */ 321 | 322 | /* Begin PBXTargetDependency section */ 323 | ED03CD94223EC98D00A1DCFD /* PBXTargetDependency */ = { 324 | isa = PBXTargetDependency; 325 | target = ED668120223C75AF00E10E0D /* Marker */; 326 | targetProxy = ED03CD93223EC98D00A1DCFD /* PBXContainerItemProxy */; 327 | }; 328 | ED668144223C75CC00E10E0D /* PBXTargetDependency */ = { 329 | isa = PBXTargetDependency; 330 | target = ED668137223C75CC00E10E0D /* MarkerExtension */; 331 | targetProxy = ED668143223C75CC00E10E0D /* PBXContainerItemProxy */; 332 | }; 333 | /* End PBXTargetDependency section */ 334 | 335 | /* Begin PBXVariantGroup section */ 336 | ED66812A223C75B100E10E0D /* Main.storyboard */ = { 337 | isa = PBXVariantGroup; 338 | children = ( 339 | ED66812B223C75B100E10E0D /* Base */, 340 | ); 341 | name = Main.storyboard; 342 | sourceTree = ""; 343 | }; 344 | /* End PBXVariantGroup section */ 345 | 346 | /* Begin XCBuildConfiguration section */ 347 | ED03CD95223EC98D00A1DCFD /* Debug */ = { 348 | isa = XCBuildConfiguration; 349 | buildSettings = { 350 | BUNDLE_LOADER = "$(TEST_HOST)"; 351 | CODE_SIGN_STYLE = Automatic; 352 | COMBINE_HIDPI_IMAGES = YES; 353 | DEVELOPMENT_TEAM = 9KT5BGB8MA; 354 | FRAMEWORK_SEARCH_PATHS = "${DEVELOPER_FRAMEWORKS_DIR}"; 355 | INFOPLIST_FILE = MarkerTests/Info.plist; 356 | LD_RUNPATH_SEARCH_PATHS = ( 357 | "${DEVELOPER_FRAMEWORKS_DIR}", 358 | "$(inherited)", 359 | "@executable_path/../Frameworks", 360 | "@loader_path/../Frameworks", 361 | ); 362 | PRODUCT_BUNDLE_IDENTIFIER = com.hotbeverage.MarkerTests; 363 | PRODUCT_NAME = "$(TARGET_NAME)"; 364 | SWIFT_VERSION = 5.0; 365 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Marker.app/Contents/MacOS/Marker"; 366 | }; 367 | name = Debug; 368 | }; 369 | ED03CD96223EC98D00A1DCFD /* Release */ = { 370 | isa = XCBuildConfiguration; 371 | buildSettings = { 372 | BUNDLE_LOADER = "$(TEST_HOST)"; 373 | CODE_SIGN_STYLE = Automatic; 374 | COMBINE_HIDPI_IMAGES = YES; 375 | DEVELOPMENT_TEAM = 9KT5BGB8MA; 376 | FRAMEWORK_SEARCH_PATHS = "${DEVELOPER_FRAMEWORKS_DIR}"; 377 | INFOPLIST_FILE = MarkerTests/Info.plist; 378 | LD_RUNPATH_SEARCH_PATHS = ( 379 | "${DEVELOPER_FRAMEWORKS_DIR}", 380 | "$(inherited)", 381 | "@executable_path/../Frameworks", 382 | "@loader_path/../Frameworks", 383 | ); 384 | PRODUCT_BUNDLE_IDENTIFIER = com.hotbeverage.MarkerTests; 385 | PRODUCT_NAME = "$(TARGET_NAME)"; 386 | SWIFT_VERSION = 5.0; 387 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Marker.app/Contents/MacOS/Marker"; 388 | }; 389 | name = Release; 390 | }; 391 | ED66812F223C75B100E10E0D /* Debug */ = { 392 | isa = XCBuildConfiguration; 393 | buildSettings = { 394 | ALWAYS_SEARCH_USER_PATHS = NO; 395 | CLANG_ANALYZER_NONNULL = YES; 396 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 397 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 398 | CLANG_CXX_LIBRARY = "libc++"; 399 | CLANG_ENABLE_MODULES = YES; 400 | CLANG_ENABLE_OBJC_ARC = YES; 401 | CLANG_ENABLE_OBJC_WEAK = YES; 402 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 403 | CLANG_WARN_BOOL_CONVERSION = YES; 404 | CLANG_WARN_COMMA = YES; 405 | CLANG_WARN_CONSTANT_CONVERSION = YES; 406 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 407 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 408 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 409 | CLANG_WARN_EMPTY_BODY = YES; 410 | CLANG_WARN_ENUM_CONVERSION = YES; 411 | CLANG_WARN_INFINITE_RECURSION = YES; 412 | CLANG_WARN_INT_CONVERSION = YES; 413 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 414 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 415 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 416 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 417 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 418 | CLANG_WARN_STRICT_PROTOTYPES = YES; 419 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 420 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 421 | CLANG_WARN_UNREACHABLE_CODE = YES; 422 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 423 | CODE_SIGN_IDENTITY = "Mac Developer"; 424 | COPY_PHASE_STRIP = NO; 425 | DEBUG_INFORMATION_FORMAT = dwarf; 426 | ENABLE_STRICT_OBJC_MSGSEND = YES; 427 | ENABLE_TESTABILITY = YES; 428 | GCC_C_LANGUAGE_STANDARD = gnu11; 429 | GCC_DYNAMIC_NO_PIC = NO; 430 | GCC_NO_COMMON_BLOCKS = YES; 431 | GCC_OPTIMIZATION_LEVEL = 0; 432 | GCC_PREPROCESSOR_DEFINITIONS = ( 433 | "DEBUG=1", 434 | "$(inherited)", 435 | ); 436 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 437 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 438 | GCC_WARN_UNDECLARED_SELECTOR = YES; 439 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 440 | GCC_WARN_UNUSED_FUNCTION = YES; 441 | GCC_WARN_UNUSED_VARIABLE = YES; 442 | MACOSX_DEPLOYMENT_TARGET = 10.14; 443 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 444 | MTL_FAST_MATH = YES; 445 | ONLY_ACTIVE_ARCH = YES; 446 | SDKROOT = macosx; 447 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 448 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 449 | }; 450 | name = Debug; 451 | }; 452 | ED668130223C75B100E10E0D /* Release */ = { 453 | isa = XCBuildConfiguration; 454 | buildSettings = { 455 | ALWAYS_SEARCH_USER_PATHS = NO; 456 | CLANG_ANALYZER_NONNULL = YES; 457 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 458 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 459 | CLANG_CXX_LIBRARY = "libc++"; 460 | CLANG_ENABLE_MODULES = YES; 461 | CLANG_ENABLE_OBJC_ARC = YES; 462 | CLANG_ENABLE_OBJC_WEAK = YES; 463 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 464 | CLANG_WARN_BOOL_CONVERSION = YES; 465 | CLANG_WARN_COMMA = YES; 466 | CLANG_WARN_CONSTANT_CONVERSION = YES; 467 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 468 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 469 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 470 | CLANG_WARN_EMPTY_BODY = YES; 471 | CLANG_WARN_ENUM_CONVERSION = YES; 472 | CLANG_WARN_INFINITE_RECURSION = YES; 473 | CLANG_WARN_INT_CONVERSION = YES; 474 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 475 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 476 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 477 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 478 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 479 | CLANG_WARN_STRICT_PROTOTYPES = YES; 480 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 481 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 482 | CLANG_WARN_UNREACHABLE_CODE = YES; 483 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 484 | CODE_SIGN_IDENTITY = "Mac Developer"; 485 | COPY_PHASE_STRIP = NO; 486 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 487 | ENABLE_NS_ASSERTIONS = NO; 488 | ENABLE_STRICT_OBJC_MSGSEND = YES; 489 | GCC_C_LANGUAGE_STANDARD = gnu11; 490 | GCC_NO_COMMON_BLOCKS = YES; 491 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 492 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 493 | GCC_WARN_UNDECLARED_SELECTOR = YES; 494 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 495 | GCC_WARN_UNUSED_FUNCTION = YES; 496 | GCC_WARN_UNUSED_VARIABLE = YES; 497 | MACOSX_DEPLOYMENT_TARGET = 10.14; 498 | MTL_ENABLE_DEBUG_INFO = NO; 499 | MTL_FAST_MATH = YES; 500 | SDKROOT = macosx; 501 | SWIFT_COMPILATION_MODE = wholemodule; 502 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 503 | }; 504 | name = Release; 505 | }; 506 | ED668132223C75B100E10E0D /* Debug */ = { 507 | isa = XCBuildConfiguration; 508 | buildSettings = { 509 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 510 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 511 | CODE_SIGN_ENTITLEMENTS = Marker/Marker.entitlements; 512 | CODE_SIGN_IDENTITY = "Mac Developer"; 513 | CODE_SIGN_STYLE = Automatic; 514 | COMBINE_HIDPI_IMAGES = YES; 515 | DEVELOPMENT_TEAM = 9KT5BGB8MA; 516 | INFOPLIST_FILE = Marker/Info.plist; 517 | LD_RUNPATH_SEARCH_PATHS = ( 518 | "$(inherited)", 519 | "@executable_path/../Frameworks", 520 | ); 521 | PRODUCT_BUNDLE_IDENTIFIER = com.hotbeverage.Marker; 522 | PRODUCT_NAME = "$(TARGET_NAME)"; 523 | PROVISIONING_PROFILE_SPECIFIER = ""; 524 | SWIFT_VERSION = 5.0; 525 | }; 526 | name = Debug; 527 | }; 528 | ED668133223C75B100E10E0D /* Release */ = { 529 | isa = XCBuildConfiguration; 530 | buildSettings = { 531 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 532 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 533 | CODE_SIGN_ENTITLEMENTS = Marker/Marker.entitlements; 534 | CODE_SIGN_IDENTITY = "Mac Developer"; 535 | CODE_SIGN_STYLE = Automatic; 536 | COMBINE_HIDPI_IMAGES = YES; 537 | DEVELOPMENT_TEAM = 9KT5BGB8MA; 538 | INFOPLIST_FILE = Marker/Info.plist; 539 | LD_RUNPATH_SEARCH_PATHS = ( 540 | "$(inherited)", 541 | "@executable_path/../Frameworks", 542 | ); 543 | PRODUCT_BUNDLE_IDENTIFIER = com.hotbeverage.Marker; 544 | PRODUCT_NAME = "$(TARGET_NAME)"; 545 | PROVISIONING_PROFILE_SPECIFIER = ""; 546 | SWIFT_VERSION = 5.0; 547 | }; 548 | name = Release; 549 | }; 550 | ED668147223C75CC00E10E0D /* Debug */ = { 551 | isa = XCBuildConfiguration; 552 | buildSettings = { 553 | CODE_SIGN_ENTITLEMENTS = MarkerExtension/MarkerExtension.entitlements; 554 | CODE_SIGN_IDENTITY = "Mac Developer"; 555 | CODE_SIGN_STYLE = Automatic; 556 | COMBINE_HIDPI_IMAGES = YES; 557 | DEVELOPMENT_TEAM = 9KT5BGB8MA; 558 | INFOPLIST_FILE = MarkerExtension/Info.plist; 559 | LD_RUNPATH_SEARCH_PATHS = ( 560 | "$(inherited)", 561 | "@executable_path/../Frameworks", 562 | "@executable_path/../../../../Frameworks", 563 | ); 564 | PRODUCT_BUNDLE_IDENTIFIER = com.hotbeverage.Marker.MarkerExtension; 565 | PRODUCT_NAME = "$(TARGET_NAME)"; 566 | PROVISIONING_PROFILE_SPECIFIER = ""; 567 | SKIP_INSTALL = YES; 568 | SWIFT_VERSION = 5.0; 569 | }; 570 | name = Debug; 571 | }; 572 | ED668148223C75CC00E10E0D /* Release */ = { 573 | isa = XCBuildConfiguration; 574 | buildSettings = { 575 | CODE_SIGN_ENTITLEMENTS = MarkerExtension/MarkerExtension.entitlements; 576 | CODE_SIGN_IDENTITY = "Mac Developer"; 577 | CODE_SIGN_STYLE = Automatic; 578 | COMBINE_HIDPI_IMAGES = YES; 579 | DEVELOPMENT_TEAM = 9KT5BGB8MA; 580 | INFOPLIST_FILE = MarkerExtension/Info.plist; 581 | LD_RUNPATH_SEARCH_PATHS = ( 582 | "$(inherited)", 583 | "@executable_path/../Frameworks", 584 | "@executable_path/../../../../Frameworks", 585 | ); 586 | PRODUCT_BUNDLE_IDENTIFIER = com.hotbeverage.Marker.MarkerExtension; 587 | PRODUCT_NAME = "$(TARGET_NAME)"; 588 | PROVISIONING_PROFILE_SPECIFIER = ""; 589 | SKIP_INSTALL = YES; 590 | SWIFT_VERSION = 5.0; 591 | }; 592 | name = Release; 593 | }; 594 | /* End XCBuildConfiguration section */ 595 | 596 | /* Begin XCConfigurationList section */ 597 | ED03CD97223EC98D00A1DCFD /* Build configuration list for PBXNativeTarget "MarkerTests" */ = { 598 | isa = XCConfigurationList; 599 | buildConfigurations = ( 600 | ED03CD95223EC98D00A1DCFD /* Debug */, 601 | ED03CD96223EC98D00A1DCFD /* Release */, 602 | ); 603 | defaultConfigurationIsVisible = 0; 604 | defaultConfigurationName = Release; 605 | }; 606 | ED66811C223C75AF00E10E0D /* Build configuration list for PBXProject "Marker" */ = { 607 | isa = XCConfigurationList; 608 | buildConfigurations = ( 609 | ED66812F223C75B100E10E0D /* Debug */, 610 | ED668130223C75B100E10E0D /* Release */, 611 | ); 612 | defaultConfigurationIsVisible = 0; 613 | defaultConfigurationName = Release; 614 | }; 615 | ED668131223C75B100E10E0D /* Build configuration list for PBXNativeTarget "Marker" */ = { 616 | isa = XCConfigurationList; 617 | buildConfigurations = ( 618 | ED668132223C75B100E10E0D /* Debug */, 619 | ED668133223C75B100E10E0D /* Release */, 620 | ); 621 | defaultConfigurationIsVisible = 0; 622 | defaultConfigurationName = Release; 623 | }; 624 | ED668146223C75CC00E10E0D /* Build configuration list for PBXNativeTarget "MarkerExtension" */ = { 625 | isa = XCConfigurationList; 626 | buildConfigurations = ( 627 | ED668147223C75CC00E10E0D /* Debug */, 628 | ED668148223C75CC00E10E0D /* Release */, 629 | ); 630 | defaultConfigurationIsVisible = 0; 631 | defaultConfigurationName = Release; 632 | }; 633 | /* End XCConfigurationList section */ 634 | }; 635 | rootObject = ED668119223C75AF00E10E0D /* Project object */; 636 | } 637 | -------------------------------------------------------------------------------- /Marker.xcodeproj/xcshareddata/xcschemes/Marker.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Marker.xcodeproj/xcshareddata/xcschemes/MarkerExtension.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 16 | 22 | 23 | 24 | 30 | 36 | 37 | 38 | 39 | 40 | 45 | 46 | 48 | 54 | 55 | 56 | 57 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 79 | 82 | 83 | 84 | 90 | 91 | 92 | 93 | 96 | 97 | 98 | 99 | 100 | 101 | 108 | 110 | 116 | 117 | 118 | 119 | 121 | 122 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /Marker/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Marker 4 | // 5 | // Created by Zoe Smith on 15/3/19. 6 | // Copyright © 2019 Hot Beverage. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Marker/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 | } -------------------------------------------------------------------------------- /Marker/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Marker/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | Default 529 | 530 | 531 | 532 | 533 | 534 | 535 | Left to Right 536 | 537 | 538 | 539 | 540 | 541 | 542 | Right to Left 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | Default 554 | 555 | 556 | 557 | 558 | 559 | 560 | Left to Right 561 | 562 | 563 | 564 | 565 | 566 | 567 | Right to Left 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 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 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | -------------------------------------------------------------------------------- /Marker/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 © 2019 Hot Beverage. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /Marker/Marker.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Marker/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Marker 4 | // 5 | // Created by Zoe Smith on 15/3/19. 6 | // Copyright © 2019 Hot Beverage. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override var representedObject: Any? { 20 | didSet { 21 | // Update the view, if already loaded. 22 | } 23 | } 24 | 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /MarkerExtension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Marked 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Marks 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 | XCSourceEditorExtensionPrincipalClass 30 | $(PRODUCT_MODULE_NAME).SourceEditorExtension 31 | 32 | NSExtensionPointIdentifier 33 | com.apple.dt.Xcode.extension.source-editor 34 | 35 | NSHumanReadableCopyright 36 | Copyright © 2019 Hot Beverage. All rights reserved. 37 | 38 | 39 | -------------------------------------------------------------------------------- /MarkerExtension/MarkerCommand.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SourceEditorCommand.swift 3 | // MarkerExtension 4 | // 5 | // Created by Zoe Smith on 15/3/19. 6 | // Copyright © 2019 Hot Beverage. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XcodeKit 11 | 12 | public class MarkerCommand: NSObject, XCSourceEditorCommand { 13 | 14 | public func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void ) -> Void { 15 | // There's only one menu command dealt with by this MarkerCommand class 16 | // so we don't need to use invocation.commandIdentifier to identify it 17 | replaceLines(in: invocation.buffer.lines, by: formattingMarks) 18 | completionHandler(nil) 19 | } 20 | 21 | func replaceLines(in lines: NSMutableArray, by replacing: @escaping (String) -> String?) { 22 | guard let strings = lines as? [String] else { 23 | return 24 | } 25 | let newStrings: [(Int, String)] = strings.enumerated().compactMap { 26 | let (index, line) = $0 27 | guard let replacementLine = replacing(line) else { 28 | return nil 29 | } 30 | return (index, replacementLine) 31 | } 32 | newStrings.forEach { 33 | let (index, newString) = $0 34 | lines[index] = newString 35 | } 36 | } 37 | 38 | enum Mark: String { 39 | case todo = "// TODO:" 40 | case fixme = "// FIXME:" 41 | case mark = "// MARK:" 42 | 43 | init?(_ string: String) { 44 | guard let mark = Mark.init(rawValue: "// " + string.uppercased() + ":") else { 45 | return nil 46 | } 47 | self = mark 48 | } 49 | } 50 | 51 | public func formattingMarks(in input: String) -> String? { 52 | // We're only interested in one possible match per line 53 | guard let match = regex.matches(in: input, options: [], range: NSMakeRange(0, input.utf16.count)).first else { 54 | return nil 55 | } 56 | 57 | guard let completeMark = Range(match.range(withName: "completemark"), in: input) else { 58 | return nil 59 | } 60 | 61 | // Bail if the mark is already correctly formatted 62 | if let _ = Mark(rawValue: String(input[completeMark])) { 63 | return nil 64 | } 65 | 66 | // Get a well-formatted mark 67 | guard let mark = Range(match.range(withName: "mark"), in: input), 68 | let replacement = Mark(String(input[mark]))?.rawValue else { 69 | return nil 70 | } 71 | 72 | // If there was a trailing colon, collapse any whitespace between it and the mark: 73 | let colon = Range(match.range(withName: "colon"), in: input) 74 | let upperBoundForReplacement = colon?.upperBound ?? mark.upperBound 75 | // Start the lower bound just before the comment slashes to normalize space there too 76 | let replacementRange = completeMark.lowerBound.. 88 | // 89 | \s* 90 | (? 91 | fixme|todo|mark) 92 | ( \s* (?:) | \s+ ) 93 | ) 94 | """# 95 | 96 | /* 97 | (?xi) flags to allow spacing in the pattern 98 | ^ match only at beginning of string 99 | \\s* allow some leading whitespace 100 | (? capture group so no replacement is returned for a well formed MARK: 101 | // match only comments, not documentation comments 102 | \\* allow some whitespace after comment - this will be normalized to one space 103 | (? capture group for marks 104 | fixme|todo|mark case-insensitive matching as per options 105 | ( \\s* (?:) match EITHER optional whitespace followed by a colon, recording the colon for later 106 | | \\s+ ) OR some whitespace, which will be normalized 107 | */ 108 | 109 | let regex = try! NSRegularExpression(pattern: pattern) 110 | -------------------------------------------------------------------------------- /MarkerExtension/MarkerExtension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MarkerExtension/SourceEditorExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SourceEditorExtension.swift 3 | // MarkerExtension 4 | // 5 | // Created by Zoe Smith on 15/3/19. 6 | // Copyright © 2019 Hot Beverage. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XcodeKit 11 | import os.log 12 | 13 | class SourceEditorExtension: NSObject, XCSourceEditorExtension { 14 | 15 | func extensionDidFinishLaunching() { 16 | os_log("Extension ready", type: .debug) 17 | } 18 | 19 | var commandDefinitions: [[XCSourceEditorCommandDefinitionKey: Any]] { 20 | let namespace = Bundle(for: type(of: self)).bundleIdentifier! 21 | let marker = MarkerCommand.className() 22 | return [[.identifierKey: namespace + marker, 23 | .classNameKey: marker, 24 | .nameKey: NSLocalizedString("Format Marks", comment: "format marks menu item")]] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MarkerTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | -------------------------------------------------------------------------------- /MarkerTests/MarkerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MarkerTests.swift 3 | // MarkerTests 4 | // 5 | // Created by Zoe Smith on 17/3/19. 6 | // Copyright © 2019 Hot Beverage. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import XcodeKit 11 | 12 | class MarkerTests: XCTestCase { 13 | 14 | let markerCommand = MarkerCommand() 15 | 16 | func testNoOps() { 17 | let tests = ["// TODO: This", "// FIXME: Something else", "// MARK: Not this", "// MARK:- Not this either"] 18 | let expected: [String?] = [nil, nil, nil, nil] 19 | XCTAssertEqual(tests.map(markerCommand.formattingMarks), expected) 20 | } 21 | 22 | func testMissingColons() { 23 | let tests = ["//TODO This", "//FIXME Something else", "//MARK Not this", "//MARK Not this either"] 24 | let expected: [String?] = ["// TODO: This", "// FIXME: Something else", "// MARK: Not this", "// MARK: Not this either"] 25 | XCTAssertEqual(tests.map(markerCommand.formattingMarks), expected) 26 | } 27 | 28 | func testCapitalization() { 29 | let tests = ["//toDo This", "//fixme Something else", "//mark Not this", "//mark: Not this either"] 30 | let expected: [String?] = ["// TODO: This", "// FIXME: Something else", "// MARK: Not this", "// MARK: Not this either"] 31 | XCTAssertEqual(tests.map(markerCommand.formattingMarks), expected) 32 | } 33 | 34 | func testIgnoreWordPrefixes() { 35 | let tests = ["//toDoThis", "//fixmeSomething else", "//marked Not this", "//marked: Not this either"] 36 | let expected: [String?] = [nil, nil, nil, nil] 37 | XCTAssertEqual(tests.map(markerCommand.formattingMarks), expected) 38 | } 39 | 40 | func testNormalizeSpacing() { 41 | let tests = ["//TODO : This", "//MARK :- This", "//fixme : good grief"] 42 | let expected: [String?] = ["// TODO: This", "// MARK:- This", "// FIXME: good grief"] 43 | XCTAssertEqual(tests.map(markerCommand.formattingMarks), expected) 44 | } 45 | 46 | func testIgnoreRandomCode() { 47 | let tests = ["func somethingFancy() { ", 48 | "var markOne: String", 49 | "protocol Mark : FancyProtocol", 50 | "struct FixMe {"] 51 | let expected: [String?] = Array(repeating: nil, count: tests.count) 52 | XCTAssertEqual(tests.map(markerCommand.formattingMarks), expected) 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Marker Extension 2 | 3 | Sample code to accompany blog post on Xcode extensions: 4 | implements an Xcode Source Editor extension to format Swift code. 5 | 6 | This extension uses regular expressions to reformat malformed code marks (`TODO`, `FIXME` and `MARK`) 7 | to be uppercased with a trailing colon, 8 | enabling Xcode to recognize and add them to quick navigation links. 9 | 10 | This formatting rule was inspired by one of the many rules provided by the 11 | [SwiftFormat](https://www.github.com/nicklockwood/SwiftFormat) project. 12 | A fuller implementation like SwiftFormat's which also recognizes code marks inside `/* */` comments 13 | is left as an exercise for the reader 😇. 14 | --------------------------------------------------------------------------------