├── .gitignore ├── FinderMenu ├── Assets.xcassets │ ├── Contents.json │ └── AppIcon.appiconset │ │ ├── 003-mouse-2.png │ │ ├── 003-mouse-2 (1).png │ │ ├── 003-mouse-2 (2).png │ │ ├── 003-mouse-2 (3).png │ │ ├── 003-mouse-2 (4).png │ │ ├── 003-mouse-2 (5).png │ │ ├── 003-mouse-2 (1)-1.png │ │ ├── 003-mouse-2 (4)-1.png │ │ ├── 003-mouse-2 (5)-1.png │ │ ├── 003-mouse-2 (6)-1.png │ │ └── Contents.json ├── FinderMenu.entitlements ├── resources │ └── launchd │ │ ├── com.samiyuru.findermenu-service.plist │ │ └── install-service.sh ├── Info.plist └── main.swift ├── Media ├── finder-right-click-new-text.gif └── finder-right-click-open-terminal.gif ├── FinderMenu.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ └── samiyuru.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── project.pbxproj ├── FinderMenuItems ├── FinderMenuItems.entitlements ├── Info.plist └── RightClickActions.swift ├── FinderMenuService ├── FinderMenuService.entitlements ├── Info.plist └── main.swift ├── Scripts ├── Git Pull Changes.sh ├── Open Terminal Here.sh ├── Git Push Changes.sh └── Open Text File Here.sh ├── Commons ├── Info.plist └── Commons.swift └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | /.idea 3 | /FinderMenu.xcodeproj/xcuserdata 4 | /FinderMenu.xcodeproj/xcshareddata 5 | -------------------------------------------------------------------------------- /FinderMenu/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Media/finder-right-click-new-text.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samiyuru/custom-finder-right-click-menu/HEAD/Media/finder-right-click-new-text.gif -------------------------------------------------------------------------------- /Media/finder-right-click-open-terminal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samiyuru/custom-finder-right-click-menu/HEAD/Media/finder-right-click-open-terminal.gif -------------------------------------------------------------------------------- /FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samiyuru/custom-finder-right-click-menu/HEAD/FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2.png -------------------------------------------------------------------------------- /FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samiyuru/custom-finder-right-click-menu/HEAD/FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (1).png -------------------------------------------------------------------------------- /FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samiyuru/custom-finder-right-click-menu/HEAD/FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (2).png -------------------------------------------------------------------------------- /FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samiyuru/custom-finder-right-click-menu/HEAD/FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (3).png -------------------------------------------------------------------------------- /FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (4).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samiyuru/custom-finder-right-click-menu/HEAD/FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (4).png -------------------------------------------------------------------------------- /FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (5).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samiyuru/custom-finder-right-click-menu/HEAD/FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (5).png -------------------------------------------------------------------------------- /FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (1)-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samiyuru/custom-finder-right-click-menu/HEAD/FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (1)-1.png -------------------------------------------------------------------------------- /FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (4)-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samiyuru/custom-finder-right-click-menu/HEAD/FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (4)-1.png -------------------------------------------------------------------------------- /FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (5)-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samiyuru/custom-finder-right-click-menu/HEAD/FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (5)-1.png -------------------------------------------------------------------------------- /FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (6)-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samiyuru/custom-finder-right-click-menu/HEAD/FinderMenu/Assets.xcassets/AppIcon.appiconset/003-mouse-2 (6)-1.png -------------------------------------------------------------------------------- /FinderMenu.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /FinderMenu/FinderMenu.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /FinderMenu.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /FinderMenuItems/FinderMenuItems.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.application-groups 8 | 9 | com.samiyuru.FinderMenu 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /FinderMenuService/FinderMenuService.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.application-groups 8 | 9 | com.samiyuru.FinderMenu 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /FinderMenu/resources/launchd/com.samiyuru.findermenu-service.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | com.samiyuru.findermenu-service 7 | ProgramArguments 8 | 9 | %@ 10 | 11 | RunAtLoad 12 | 13 | KeepAlive 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Scripts/Git Pull Changes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ###################################################### 4 | # Created by Samiyuru Senarathne on 1/22/20. 5 | # Copyright Samiyuru Senarathne 2020 6 | # 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 8 | # OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 9 | # LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 10 | # FITNESS FOR A PARTICULAR PURPOSE AND 11 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 13 | # OR OTHER LIABILITY, WHETHER IN AN ACTION OF 14 | # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 15 | # OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 16 | # OTHER DEALINGS IN THE SOFTWARE. 17 | # 18 | # Open terminal in the path given by the param. 19 | # Param is the directory to open the Terminal in. 20 | ###################################################### 21 | 22 | cd "$1" 23 | git pull -------------------------------------------------------------------------------- /Scripts/Open Terminal Here.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ###################################################### 4 | # Created by Samiyuru Senarathne on 1/22/20. 5 | # Copyright Samiyuru Senarathne 2020 6 | # 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 8 | # OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 9 | # LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 10 | # FITNESS FOR A PARTICULAR PURPOSE AND 11 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 13 | # OR OTHER LIABILITY, WHETHER IN AN ACTION OF 14 | # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 15 | # OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 16 | # OTHER DEALINGS IN THE SOFTWARE. 17 | # 18 | # Open terminal in the path given by the param. 19 | # Param is the directory to open the Terminal in. 20 | ###################################################### 21 | 22 | open -a "Terminal" "$1" 23 | -------------------------------------------------------------------------------- /Scripts/Git Push Changes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ###################################################### 4 | # Created by Samiyuru Senarathne on 1/22/20. 5 | # Copyright Samiyuru Senarathne 2020 6 | # 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 8 | # OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 9 | # LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 10 | # FITNESS FOR A PARTICULAR PURPOSE AND 11 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 13 | # OR OTHER LIABILITY, WHETHER IN AN ACTION OF 14 | # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 15 | # OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 16 | # OTHER DEALINGS IN THE SOFTWARE. 17 | # 18 | # Open terminal in the path given by the param. 19 | # Param is the directory to open the Terminal in. 20 | ###################################################### 21 | 22 | cd "$1" 23 | git add --all 24 | git commit -m "$(date)" 25 | git push -------------------------------------------------------------------------------- /Commons/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSHumanReadableCopyright 22 | Copyright © 2020 Samiyuru Senarathne. All rights reserved. 23 | 24 | 25 | -------------------------------------------------------------------------------- /FinderMenu/resources/launchd/install-service.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ###################################################### 4 | # Created by Samiyuru Senarathne on 1/22/20. 5 | # Copyright Samiyuru Senarathne 2020 6 | # 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 8 | # OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 9 | # LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 10 | # FITNESS FOR A PARTICULAR PURPOSE AND 11 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 13 | # OR OTHER LIABILITY, WHETHER IN AN ACTION OF 14 | # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 15 | # OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 16 | # OTHER DEALINGS IN THE SOFTWARE. 17 | # 18 | # Install launchd given by the paramter. 19 | # Param is the plist id. 20 | # The plist should be already copied to 21 | # ~/Library/LaunchAgents 22 | ###################################################### 23 | 24 | id="$1" 25 | plist="$id.plist" 26 | cd ~/Library/LaunchAgents 27 | launchctl unload "$plist" 28 | launchctl load "$plist" 29 | launchctl list | grep "$id" 30 | -------------------------------------------------------------------------------- /FinderMenuService/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2020 Samiyuru Senarathne. All rights reserved. 27 | NSSupportsAutomaticTermination 28 | 29 | NSSupportsSuddenTermination 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /FinderMenu/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2020 Samiyuru Senarathne. All rights reserved. 27 | NSPrincipalClass 28 | NSApplication 29 | NSSupportsAutomaticTermination 30 | 31 | NSSupportsSuddenTermination 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Scripts/Open Text File Here.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ###################################################### 4 | # Created by Samiyuru Senarathne on 1/22/20. 5 | # Copyright Samiyuru Senarathne 2020 6 | # 7 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 8 | # OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 9 | # LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 10 | # FITNESS FOR A PARTICULAR PURPOSE AND 11 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 13 | # OR OTHER LIABILITY, WHETHER IN AN ACTION OF 14 | # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 15 | # OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 16 | # OTHER DEALINGS IN THE SOFTWARE. 17 | # 18 | # Create a new text file with a name not existing 19 | # in the dir given as a param. 20 | # Open the created text with TextEdit. 21 | # Param is the directory to create the text file. 22 | ###################################################### 23 | 24 | DEF_FILE_NAME="NewText" 25 | FILE_EXT="txt" 26 | 27 | # Default text file name. 28 | filePath="${1}/${DEF_FILE_NAME}.${FILE_EXT}" 29 | fileNo=1 30 | 31 | # Try new names until a non-existing one is found. 32 | while [ -f "${filePath}" ] 33 | do 34 | filePath="${1}/${DEF_FILE_NAME}_${fileNo}.${FILE_EXT}" 35 | fileNo=$((fileNo+1)) 36 | done 37 | 38 | # Create the text file. 39 | touch "${filePath}" 40 | 41 | # Open the file with TextEdit. 42 | open -a TextEdit "${filePath}" 43 | -------------------------------------------------------------------------------- /FinderMenuItems/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | FinderMenuItems 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | LSUIElement 26 | 27 | NSExtension 28 | 29 | NSExtensionAttributes 30 | 31 | NSExtensionPointIdentifier 32 | com.apple.FinderSync 33 | NSExtensionPrincipalClass 34 | $(PRODUCT_MODULE_NAME).RightClickActions 35 | 36 | NSHumanReadableCopyright 37 | Copyright © 2020 Samiyuru Senarathne. All rights reserved. 38 | NSPrincipalClass 39 | NSApplication 40 | 41 | 42 | -------------------------------------------------------------------------------- /FinderMenu.xcodeproj/xcuserdata/samiyuru.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CommandService.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 2 11 | 12 | Commons.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 3 16 | 17 | FinderMenu.xcscheme_^#shared#^_ 18 | 19 | orderHint 20 | 0 21 | 22 | RightClickItems.xcscheme_^#shared#^_ 23 | 24 | orderHint 25 | 1 26 | 27 | RightClickService.xcscheme_^#shared#^_ 28 | 29 | orderHint 30 | 2 31 | 32 | 33 | SuppressBuildableAutocreation 34 | 35 | 6B8F97AC23D828CA00BDB90D 36 | 37 | primary 38 | 39 | 40 | 6B8F97C623D82D2100BDB90D 41 | 42 | primary 43 | 44 | 45 | 6B8F986823DD38C600BDB90D 46 | 47 | primary 48 | 49 | 50 | 6B8F988E23DD3B1C00BDB90D 51 | 52 | primary 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /FinderMenu/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "003-mouse-2.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "003-mouse-2 (1).png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "003-mouse-2 (1)-1.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "003-mouse-2 (2).png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "003-mouse-2 (3).png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "003-mouse-2 (4)-1.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "003-mouse-2 (4).png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "003-mouse-2 (5).png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "003-mouse-2 (5)-1.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "003-mouse-2 (6)-1.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Commons/Commons.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Commons.swift 3 | // Commons 4 | // 5 | // Created by Samiyuru Senarathne on 1/25/20. 6 | // Copyright © 2020 Samiyuru Senarathne. 7 | // 8 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 9 | // OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 10 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11 | // FITNESS FOR A PARTICULAR PURPOSE AND 12 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 13 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 14 | // OR OTHER LIABILITY, WHETHER IN AN ACTION OF 15 | // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 16 | // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 17 | // OTHER DEALINGS IN THE SOFTWARE. 18 | // 19 | 20 | import Foundation 21 | 22 | public let MENU_ITEM_CLICKED_NOTIF = "menuItemClickedNotif" 23 | public let MENU_ITEM_INFO_NOTIF = "menuItemInfoNotif" 24 | public let MENU_ITEM_INFO_REQUEST_NOTIF = "menuItemInfoRequestNotif" 25 | 26 | // Get the directory for the menu item programs. 27 | // The programs can be apple scripts, bash scripts or executables. 28 | public func programsDir() -> URL { 29 | // Name of the menu programs directory. 30 | let menuProgramsDirName = ".findermenu" 31 | 32 | // Get the path to user home dir. 33 | let scriptParentDirURL = FileManager.default.homeDirectoryForCurrentUser 34 | 35 | // Get the URL for menu programs dir path. 36 | let menuProgramsDirURL = scriptParentDirURL.appendingPathComponent(menuProgramsDirName) 37 | 38 | return menuProgramsDirURL 39 | } 40 | 41 | // Class to represent an item in the right click menu. 42 | public class MenuItemInfo: Encodable, Decodable { 43 | 44 | public var id: Int 45 | public var title: String 46 | 47 | public init(id: Int, title: String) { 48 | self.id = id 49 | self.title = title 50 | } 51 | 52 | public static func fromJson(menuItemInfosStr: String?) -> [MenuItemInfo]? { 53 | guard let jsonData = menuItemInfosStr?.data(using: .utf8) else { 54 | return nil 55 | } 56 | return try? JSONDecoder().decode([MenuItemInfo].self, from: jsonData) 57 | } 58 | 59 | public static func json(menuItemInfos: [MenuItemInfo]?) -> String? { 60 | guard let jsonData = (try? JSONEncoder().encode(menuItemInfos)) else { 61 | return nil 62 | } 63 | return String(data: jsonData, encoding: .utf8) 64 | } 65 | 66 | } 67 | 68 | // Class to represent a click of a right click item. 69 | public class MenuItemClickInfo: Encodable, Decodable { 70 | 71 | public var id: Int 72 | public var target: String 73 | 74 | public init(id: Int, target: String) { 75 | self.id = id 76 | self.target = target 77 | } 78 | 79 | public static func fromJson(str: String?) -> MenuItemClickInfo? { 80 | guard let jsonData = str?.data(using: .utf8) else { 81 | return nil 82 | } 83 | return try? JSONDecoder().decode(MenuItemClickInfo.self, from: jsonData) 84 | } 85 | 86 | public func json() -> String? { 87 | guard let jsonData = (try? JSONEncoder().encode(self)) else { 88 | return nil 89 | } 90 | return String(data: jsonData, encoding: .utf8) 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MacOS Finder Custom Directory Right Click Menu 2 | 3 | This application allows you to add custom right click menu items to directories opened in MacOS Finder. 4 | Right click menu items can be added as shell scripts. 5 | The application comes with two script files inbuilt to create new text documents in the current directory and to open terminal from the current directory. 6 | The application has been tested to work on MacOS Catalina Version 10.15.2. 7 | 8 | ## Download the Application 9 | 10 | [Download the app here](https://samiyuru.com/project/macOS-finder-right-click-menu). 11 | 12 | You can download a pre built app file that is ready to run from the above link. 13 | 14 | You can build the application from the source code on MacOS using Xcode. 15 | 16 | 17 | ## Using the Application 18 | 19 | Using the application is very simple. 20 | Copy FinderMenu.app to your "/Applications" directory. 21 | Run the FinderMenu.app once from the "/Applications" directory in your system to setup right click menu items. 22 | 23 | When you run FinderMenu.app once, the application will take the following steps to setup the right click menu items. 24 | 25 | * Install a launch agent to serve the custom right click menu items. 26 | * Install a Finder extension to include custom right click menu items in the Finder. 27 | * Create "~/FinderMenu" directory to place custom right click menu scripts. 28 | * Enable "FinderMenuItems" in "System Preferences > Extensions > Finder Extensions" in case it is not already enabled. 29 | 30 | Right click menu service in FinderMenu.app automatically starts with your system. 31 | Because of that you do not have to run FinderMenu.app ever again unless you do not want to make changes to the menu item scripts. 32 | However, FinderMenu.app should always be present in your "/Applications" directory for the menus to work. 33 | 34 | Following gif shows how the provided "New Text File Here" menu item works. 35 | 36 | ![alt text](Media/finder-right-click-new-text.gif "New text File Here") 37 | 38 | The next gif shows how the provided "Open Terminal Here" menu item works. 39 | 40 | ![alt text](Media/finder-right-click-open-terminal.gif "Open Terminal Here") 41 | 42 | ## Adding Custom Menu Items 43 | 44 | Adding a new right click menu item is as simple as creating a shell script in the "\~/FinderMenu" directory. 45 | The shell script should accept the path to the directory as the first argument when running the script. 46 | File name of the script file becomes the menu item name in the right click menu. 47 | When the menu item is clicked, the script is executed with the directory path as the first argument. 48 | You can refer to the given scripts in "\~/FinderMenu" for examples. 49 | When you place a new script in "\~/FinderMenu", make sure to run FinderMenu.app once to refresh the right click menu with the new script. 50 | 51 | 52 | ## Uninstall the Application 53 | 54 | You can take the following steps if you need to completely uninstall the application form your system. 55 | 56 | * Delete the FinderMenu.app from "/Applications" directory. 57 | * Delete the "\~/FinderMenu" directory. 58 | * Disable the finder extension by gong to "System Preferences > Extensions > All" and disabling the FinderMenu item. 59 | * Remove the launch agent by deleting "\~/Library/LaunchAgents/com.samiyuru.findermenu-service.plist" 60 | 61 | 62 | ## Credits 63 | 64 | The icon used in the application is a modified version of an icon made by [Freepik](https://www.flaticon.com/authors/freepik) from [www.flaticon.com](https://www.flaticon.com). 65 | 66 | 67 | ## License 68 | 69 | Copyright © Sami Menik 2025. 70 | 71 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 72 | 73 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 74 | 75 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 76 | -------------------------------------------------------------------------------- /FinderMenu/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // FinderMenu 4 | // 5 | // Created by Samiyuru Senarathne on 1/22/20. 6 | // Copyright © 2020 Samiyuru Senarathne. 7 | // 8 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 9 | // OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 10 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11 | // FITNESS FOR A PARTICULAR PURPOSE AND 12 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 13 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 14 | // OR OTHER LIABILITY, WHETHER IN AN ACTION OF 15 | // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 16 | // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 17 | // OTHER DEALINGS IN THE SOFTWARE. 18 | // 19 | 20 | import Cocoa 21 | import FinderSync 22 | import Commons 23 | 24 | // The name of the launch agent (in plist). 25 | let launchAgentName = "com.samiyuru.findermenu-service" 26 | 27 | // AppDelegate that is used in main.swift top level code. 28 | class AppDelegate: NSObject, NSApplicationDelegate { 29 | 30 | // This is called after the application is launched by the main.swift. 31 | func applicationDidFinishLaunching(_ aNotification: Notification) { 32 | // Open extension preferences if the extension is not enabled. 33 | if !FIFinderSyncController.isExtensionEnabled { 34 | FIFinderSyncController.showExtensionManagementInterface() 35 | } 36 | 37 | // Exit the application because the application is just the carrier 38 | // of the Finder Sync extension. 39 | NSApplication.shared.terminate(self) 40 | } 41 | 42 | } 43 | 44 | // Show error alert. 45 | func errorAlert(text: String) { 46 | let alert = NSAlert() 47 | alert.messageText = "Error occured!" 48 | alert.informativeText = text 49 | alert.alertStyle = .critical 50 | alert.addButton(withTitle: "OK") 51 | alert.runModal() 52 | } 53 | 54 | // Get the URL of the user's launch agents directory. 55 | func launchAgentsDirURL() -> URL { 56 | return FileManager.default.homeDirectoryForCurrentUser 57 | .appendingPathComponent("Library") 58 | .appendingPathComponent("LaunchAgents") 59 | } 60 | 61 | // Copy file in the bundle. 62 | func copyFile(fileName: String, fileExt: String, detination: URL) -> Bool? { 63 | // Access file. 64 | guard let fileURL = Bundle.main.url(forResource: fileName, withExtension: fileExt) else { 65 | errorAlert(text: "Failed to locate script file.") 66 | return nil 67 | } 68 | 69 | // Try to delete destination. 70 | try? FileManager.default.removeItem(at: detination) 71 | 72 | // Copy file. 73 | do { 74 | try FileManager.default.copyItem(at: fileURL, to: detination) 75 | return true 76 | } catch { 77 | return false 78 | } 79 | } 80 | 81 | // Copy the default right click menu scripts available in the bundle to 82 | // the ~/FinderMenu dir. 83 | func copyDefaultScripts() { 84 | // Create the programs dir. 85 | let programsDirUrl = programsDir() 86 | do { 87 | try FileManager.default.createDirectory(at: programsDirUrl, withIntermediateDirectories: true) 88 | } catch { 89 | errorAlert(text: "Failed to create programs directory.") 90 | return 91 | } 92 | 93 | // Copy scripts. 94 | if (!(copyFile(fileName: "Open Terminal Here", fileExt: "sh", detination: programsDir().appendingPathComponent("Open Terminal Here.sh")) ?? false) 95 | || !(copyFile(fileName: "Open Text File Here", fileExt: "sh", detination: programsDir().appendingPathComponent("Open Text File Here.sh")) ?? false)){ 96 | errorAlert(text: "Failed to copy scripts.") 97 | } 98 | } 99 | 100 | // Create the plist with exec path. 101 | func generateAndCopyPlist() -> Bool { 102 | guard let plistURL = Bundle.main.url(forResource: launchAgentName, withExtension: "plist") else { 103 | errorAlert(text: "Failed to locate plist file.") 104 | return false 105 | } 106 | do { 107 | var plistStr = try String(contentsOf: plistURL, encoding: .utf8) 108 | guard let serviceExecURL = Bundle.main.resourceURL? 109 | .appendingPathComponent("FinderMenuService.app") 110 | .appendingPathComponent("Contents") 111 | .appendingPathComponent("MacOS") 112 | .appendingPathComponent("FinderMenuService") else { 113 | errorAlert(text: "Failed to locate service executable.") 114 | return false 115 | } 116 | plistStr = String(format: plistStr, serviceExecURL.path) 117 | let launchAgentURL = launchAgentsDirURL().appendingPathComponent("\(launchAgentName).plist") 118 | try plistStr.write(to: launchAgentURL, atomically: false, encoding: .utf8) 119 | return true 120 | } 121 | catch { 122 | errorAlert(text: "Failed to copy plist file.") 123 | return false 124 | } 125 | } 126 | 127 | // Run script to launch the launch agent for right click service. 128 | func initLaunchd() { 129 | if (!generateAndCopyPlist()) { 130 | return 131 | } 132 | guard let serviceInitScriptURL = Bundle.main.url(forResource: "install-service", withExtension: "sh") else { 133 | errorAlert(text: "Failed to locate service initializer script.") 134 | return 135 | } 136 | 137 | // Initialize termination handler closure. 138 | let terminationHandler = { 139 | (process: Process) -> Void in 140 | NSLog("Script terminated \(process.terminationStatus).") 141 | if (process.terminationStatus != 0) { 142 | errorAlert(text: "Failed setup the right click service.") 143 | } 144 | } 145 | 146 | // Run script. 147 | guard let _ = try? Process.run(serviceInitScriptURL, arguments: [launchAgentName], terminationHandler: terminationHandler) else { 148 | errorAlert(text: "Failed to run the process.") 149 | return 150 | } 151 | 152 | NSLog("launchd setup completed.") 153 | } 154 | 155 | // Initalize AppDeligate and set it as the deligate of the app. 156 | let delegate = AppDelegate() 157 | NSApplication.shared.delegate = delegate 158 | 159 | // Copy the default right cick script files to ~/FinderMenu. 160 | copyDefaultScripts() 161 | 162 | // Initialize launch agent for right click service. 163 | initLaunchd() 164 | 165 | // Start application run loop. 166 | _ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv) 167 | -------------------------------------------------------------------------------- /FinderMenuItems/RightClickActions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FinderSync.swift 3 | // FinderMenuItems 4 | // 5 | // Created by Samiyuru Senarathne on 1/22/20. 6 | // Copyright © 2020 Samiyuru Senarathne. 7 | // 8 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 9 | // OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 10 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11 | // FITNESS FOR A PARTICULAR PURPOSE AND 12 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 13 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 14 | // OR OTHER LIABILITY, WHETHER IN AN ACTION OF 15 | // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 16 | // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 17 | // OTHER DEALINGS IN THE SOFTWARE. 18 | // 19 | 20 | import Cocoa 21 | import FinderSync 22 | import Commons 23 | 24 | // This class is the primary class that is referred to in the plist of the Finder Sync extension. 25 | class RightClickActions: FIFinderSync { 26 | 27 | // Cached menu instance. 28 | var menu: NSMenu? 29 | 30 | // Constructor of the class. 31 | override init() { 32 | super.init() 33 | 34 | // Log the nitialization. 35 | NSLog("RightClickActions() launched from %@", Bundle.main.bundlePath as NSString) 36 | 37 | // Set up the directory we are syncing. 38 | FIFinderSyncController.default().directoryURLs = [URL(fileURLWithPath: "/")] 39 | 40 | // Register notification handler. 41 | let notifCenter = DistributedNotificationCenter.default() 42 | notifCenter.addObserver(self, 43 | selector: #selector(onMenuItemInfo), 44 | name: Notification.Name(rawValue: MENU_ITEM_INFO_NOTIF), 45 | object: nil) 46 | 47 | // Request menu item info. 48 | sendMenuItemInfoRequestNtotification() 49 | } 50 | 51 | // handler that will be called when menu item info array is sent. 52 | @objc func onMenuItemInfo(notification: NSNotification) { 53 | // Access the object as String. 54 | guard let menuItemInfosJsonStr = (notification.object as? String) else { 55 | NSLog("Failed to convert the notification object to json string.") 56 | return 57 | } 58 | 59 | // Log the notification. 60 | NSLog("\(MENU_ITEM_INFO_NOTIF) received \(menuItemInfosJsonStr).") 61 | 62 | // Convert json to menu item infos. 63 | guard let menuItemInfos = MenuItemInfo.fromJson(menuItemInfosStr: menuItemInfosJsonStr) else { 64 | NSLog("Failed to convert json to menu item info array.") 65 | return 66 | } 67 | 68 | // Create and update the menu according to the new menu item infos. 69 | self.menu = createMenu(menuItemInfos: menuItemInfos) 70 | } 71 | 72 | // Create a menu item with a given name and a URL association. 73 | func createMenuItem(menuItemInfo:MenuItemInfo) -> NSMenuItem { 74 | let menuItem = NSMenuItem(title: menuItemInfo.title, action: #selector(menuItemAction(_:)), keyEquivalent:""); 75 | // Associate script info with menu item using script info index. 76 | menuItem.tag = menuItemInfo.id 77 | return menuItem 78 | } 79 | 80 | // Create a menu by reading the config file. 81 | func createMenu(menuItemInfos: [MenuItemInfo]?) -> NSMenu? { 82 | // Guared unwrap script info array. 83 | guard let menuItemInfos = menuItemInfos else { 84 | return nil 85 | } 86 | 87 | // Initialize menu object. 88 | let menu = NSMenu() 89 | 90 | // Create a menue item for each script info dict in the array. 91 | for menuItemInfo in menuItemInfos { 92 | let menuItem = createMenuItem(menuItemInfo: menuItemInfo) 93 | menu.addItem(menuItem) 94 | } 95 | 96 | return menu 97 | } 98 | 99 | // Send menu intem info request to the right click service. 100 | func sendMenuItemInfoRequestNtotification() { 101 | NSLog("\(MENU_ITEM_INFO_REQUEST_NOTIF) sending...") 102 | 103 | // Reference to notification center. 104 | let notifCenter = DistributedNotificationCenter.default() 105 | 106 | // Post the notification. 107 | notifCenter.post(name: Notification.Name(rawValue: MENU_ITEM_INFO_REQUEST_NOTIF), 108 | object: nil) 109 | } 110 | 111 | // Send notification to the command service when right click item is clicked. 112 | func sendMenuItemClickedNotification(id: Int, target: URL) { 113 | NSLog("\(MENU_ITEM_CLICKED_NOTIF) sending...") 114 | 115 | // Reference to notification center. 116 | let notifCenter = DistributedNotificationCenter.default() 117 | 118 | // Create a json of click info. 119 | let menuItemClickInfo = MenuItemClickInfo(id: id, target: target.path) 120 | 121 | guard let menuItemClickInfoJson = menuItemClickInfo.json() else { 122 | NSLog("Failed to deserialize menu item click info.") 123 | return 124 | } 125 | 126 | // Post the notification. 127 | notifCenter.post(name: Notification.Name(rawValue: MENU_ITEM_CLICKED_NOTIF), 128 | object: menuItemClickInfoJson) 129 | } 130 | 131 | // Action handler of each manu item. 132 | @objc func menuItemAction(_ sender: AnyObject?) { 133 | guard let target = FIFinderSyncController.default().targetedURL() else { 134 | NSLog("Failed to retrieve the target directory.") 135 | return 136 | } 137 | 138 | // Get menu item from the sender. 139 | guard let menuItem = sender as? NSMenuItem else { 140 | NSLog("Sender menu item is not retrievable."); 141 | return 142 | } 143 | 144 | // Send click notification. 145 | sendMenuItemClickedNotification(id: menuItem.tag, target: target) 146 | } 147 | 148 | // Provide a list of menu items for the right click menu. 149 | override func menu(for menuKind: FIMenuKind) -> NSMenu? { 150 | // Identify finder open directory background click. 151 | if (menuKind == FIMenuKind.contextualMenuForContainer){ 152 | NSLog("Directory background right click.") 153 | 154 | // Retturn the menu from the instance variable. 155 | return self.menu 156 | } else { 157 | NSLog("Not a directory background.") 158 | 159 | // Return no menu. 160 | return nil 161 | } 162 | } 163 | 164 | } 165 | 166 | -------------------------------------------------------------------------------- /FinderMenuService/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // FinderMenu 4 | // 5 | // Created by Samiyuru Senarathne on 1/22/20. 6 | // Copyright © 2020 Samiyuru Senarathne. 7 | // 8 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 9 | // OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 10 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11 | // FITNESS FOR A PARTICULAR PURPOSE AND 12 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 13 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 14 | // OR OTHER LIABILITY, WHETHER IN AN ACTION OF 15 | // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 16 | // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 17 | // OTHER DEALINGS IN THE SOFTWARE. 18 | // 19 | 20 | import Cocoa 21 | import Commons 22 | 23 | // Types of scripts. 24 | enum ScriptTypes { 25 | case applescript 26 | case shellscript 27 | case executable 28 | } 29 | 30 | // Class to hold script information. 31 | public class ScriptInfo { 32 | 33 | // Creating instance variables. 34 | var id: Int = 0 35 | var title: String 36 | var path: URL 37 | var type: ScriptTypes 38 | 39 | // Constructor for the class. 40 | init(title: String, path: URL, type: ScriptTypes) { 41 | self.title = title 42 | self.path = path 43 | self.type = type 44 | } 45 | } 46 | 47 | // Class to hold functions related to menu item scripts. 48 | class MenuItemManager { 49 | 50 | // Dictionary to associate script info with menu items using script info array index. 51 | var scriptInfos: [ScriptInfo]? 52 | 53 | // Constructor for menu item manager. 54 | init() { 55 | // Read script paths and create script info. 56 | self.scriptInfos = readScriptPaths() 57 | } 58 | 59 | // Theere is a defined directory to save menu item scripts. 60 | // Script file name defines the title and the extension defines the type. 61 | // Each script is loaded as a ScriptInfo object containing title, path, type. 62 | func readScriptPaths() -> [ScriptInfo]? { 63 | // Get the URL for menu programs dir path. 64 | let menuProgramsDirURL = programsDir() 65 | 66 | // Log script dir URL. 67 | NSLog("Script dir located at \(menuProgramsDirURL).") 68 | 69 | // Check if the path is a directory. 70 | if (!menuProgramsDirURL.hasDirectoryPath || !((try? menuProgramsDirURL.checkResourceIsReachable()) ?? false)) { 71 | NSLog("Scripts path is not a directory at \(menuProgramsDirURL).") 72 | return nil 73 | } 74 | 75 | // Iterate files in scripts directory. 76 | guard let fileURLs = (try? FileManager.default.contentsOfDirectory(at: menuProgramsDirURL, includingPropertiesForKeys: nil, options: FileManager.DirectoryEnumerationOptions.skipsHiddenFiles)) else { 77 | NSLog("Failed to read files in \(menuProgramsDirURL).") 78 | return nil 79 | } 80 | 81 | // Create script info array. 82 | var scriptInfoArray: [ScriptInfo] = [] 83 | 84 | for fileURL in fileURLs { 85 | if let scriptInfo = createScriptInfo(scriptPath: fileURL) { 86 | // Tag is used to associate menu item with script info using array index. 87 | scriptInfo.id = scriptInfoArray.count 88 | scriptInfoArray.append(scriptInfo) 89 | } 90 | } 91 | 92 | return scriptInfoArray 93 | } 94 | 95 | // Get the script type from URL. 96 | func getScriptType(scriptPath: URL) -> ScriptTypes? { 97 | // Get the extension of the URL. Can be empty. 98 | let fileExtension = scriptPath.pathExtension.lowercased(); 99 | 100 | // Applescript extensions. 101 | let appleScriptExts = ["scpt", "scptd", "applescript"] 102 | 103 | // Shell script extensions. 104 | let shellScriptExts = ["sh"] 105 | 106 | // Check if the extension is apple script. 107 | if appleScriptExts.contains(fileExtension) { 108 | return ScriptTypes.applescript 109 | } else if shellScriptExts.contains(fileExtension) { 110 | return ScriptTypes.shellscript 111 | } else if (fileExtension.isEmpty) { 112 | return ScriptTypes.executable 113 | } else { 114 | return nil 115 | } 116 | } 117 | 118 | // Create a script info object for the script path URL. 119 | func createScriptInfo(scriptPath: URL) -> ScriptInfo? { 120 | // Check if the path is a file. 121 | if !scriptPath.isFileURL || !((try? scriptPath.checkResourceIsReachable()) ?? false) { 122 | NSLog("Script is not a file or not accessible at \(scriptPath)"); 123 | return nil 124 | } 125 | 126 | // Check if the file type is supported 127 | guard let fileType = getScriptType(scriptPath: scriptPath) else { 128 | NSLog("Unsupported script type \(scriptPath).") 129 | return nil 130 | } 131 | 132 | // Get the file name from URL. 133 | let scriptName = scriptPath.deletingPathExtension().lastPathComponent 134 | // Check if the file name exists. 135 | if scriptName.isEmpty { 136 | NSLog("File name is not available to get.") 137 | return nil 138 | } 139 | 140 | // Return scrip info object. 141 | return ScriptInfo(title: scriptName, path: scriptPath, type: fileType) 142 | } 143 | 144 | // Run script using the script info dictionary and provide target as a parameter. 145 | func runScript(scriptInfo: ScriptInfo?, target: URL) { 146 | NSLog("Runing script \(String(describing: scriptInfo)) for \(target).") 147 | 148 | guard let scriptInfo = scriptInfo else { 149 | NSLog("Script info not available.") 150 | return 151 | } 152 | 153 | // Initialize termination handler closure. 154 | let terminationHandler = { 155 | (process: Process) -> Void in 156 | NSLog("Script terminated \(process.terminationStatus).") 157 | } 158 | 159 | // required parameters. 160 | var programURL: URL 161 | var arguments: [String] 162 | 163 | // Initialize parameters according to the script type. 164 | switch scriptInfo.type { 165 | case ScriptTypes.applescript: 166 | programURL = URL(fileURLWithPath: "/usr/bin/osascript") 167 | arguments = [scriptInfo.path.path, target.path] 168 | case ScriptTypes.shellscript: 169 | programURL = URL(fileURLWithPath: "/bin/bash") 170 | arguments = [scriptInfo.path.path, target.path] 171 | case ScriptTypes.executable: 172 | programURL = scriptInfo.path 173 | arguments = [target.path] 174 | } 175 | 176 | // Run the process. 177 | guard let _ = try? Process.run(programURL, arguments: arguments, terminationHandler: terminationHandler) else { 178 | NSLog("Failed to run the process.") 179 | return 180 | } 181 | } 182 | 183 | } 184 | 185 | // Class responsible for handling notifications. 186 | class NotificationHandler { 187 | 188 | private let menuItemManager: MenuItemManager 189 | 190 | init(menuItemManager: MenuItemManager) { 191 | self.menuItemManager = menuItemManager 192 | 193 | // Send the mnu item infos after reading the scripts in case the Finder Extension is already started and handler missed the request. 194 | sendMenuItemInfosNotification() 195 | } 196 | 197 | // Convert script info array to menu item info array. 198 | func createMenuInfos(scriptInfos: [ScriptInfo]?) -> [MenuItemInfo]? { 199 | // Guarded unwrap. 200 | guard let scriptInfos = scriptInfos else { 201 | return nil 202 | } 203 | 204 | // Convert the array. 205 | var menuItemInfos = [MenuItemInfo]() 206 | for scriptInfo:ScriptInfo in scriptInfos { 207 | let menuItemInfo = MenuItemInfo(id: scriptInfo.id, title: scriptInfo.title) 208 | menuItemInfos.append(menuItemInfo) 209 | } 210 | 211 | // Return menu items info array. 212 | return menuItemInfos 213 | } 214 | 215 | // Send the menu items infos to the finder extension. 216 | func sendMenuItemInfosNotification() { 217 | NSLog("\(MENU_ITEM_INFO_NOTIF) sending...") 218 | 219 | // reference the notification center. 220 | let notifCenter = DistributedNotificationCenter.default() 221 | 222 | // Get menu items info. 223 | let menuItemsInfos = createMenuInfos(scriptInfos: self.menuItemManager.scriptInfos) 224 | 225 | // Convert to json. 226 | guard let menuItemsInfoJson = MenuItemInfo.json(menuItemInfos: menuItemsInfos) else { 227 | NSLog("Failed to convert menuItemsInfoJson to json.") 228 | return 229 | } 230 | 231 | // Post the notification. 232 | notifCenter.post(name: Notification.Name(rawValue: MENU_ITEM_INFO_NOTIF), 233 | object: menuItemsInfoJson) 234 | } 235 | 236 | // Menu item info request handler. 237 | @objc func onMenuItemInfoRequest(notification: NSNotification) { 238 | NSLog("\(MENU_ITEM_INFO_REQUEST_NOTIF) received \(notification.object as? String ?? "").") 239 | sendMenuItemInfosNotification() 240 | } 241 | 242 | // Menu item info request hendler. 243 | @objc func onMenuItemClicked(notification: NSNotification) { 244 | // Get the onject as string. 245 | guard let menuItemClickInfosJsonStr = (notification.object as? String) else { 246 | NSLog("Failed to convert the notification object to json string.") 247 | return 248 | } 249 | 250 | // Log the notification. 251 | NSLog("\(MENU_ITEM_CLICKED_NOTIF) received \(menuItemClickInfosJsonStr).") 252 | 253 | // Convert json to menu item infos. 254 | guard let menuItemClickInfo = MenuItemClickInfo.fromJson(str: menuItemClickInfosJsonStr) else { 255 | NSLog("Failed to convert json to menu item info array.") 256 | return 257 | } 258 | 259 | // Get target URL. 260 | let target = URL(fileURLWithPath: menuItemClickInfo.target) 261 | 262 | // Get ScriptInfo object. 263 | let scriptInfo = menuItemManager.scriptInfos?[menuItemClickInfo.id] 264 | 265 | // Run script. 266 | menuItemManager.runScript(scriptInfo: scriptInfo, target: target) 267 | } 268 | 269 | // Start hadeling notifications from the finder extension. 270 | func handleNotifactions() { 271 | // reference the notification center. 272 | let notifCenter = DistributedNotificationCenter.default() 273 | 274 | // Add observer to listen to click events. 275 | notifCenter.addObserver(self, 276 | selector: #selector(onMenuItemInfoRequest), 277 | name: Notification.Name(rawValue: MENU_ITEM_INFO_REQUEST_NOTIF), 278 | object: nil) 279 | 280 | // Add observer to listen to info requests. 281 | notifCenter.addObserver(self, 282 | selector: #selector(onMenuItemClicked), 283 | name: Notification.Name(rawValue: MENU_ITEM_CLICKED_NOTIF), 284 | object: nil) 285 | } 286 | 287 | } 288 | 289 | // Log the service start. 290 | NSLog("Starting the service...") 291 | 292 | // Initialize a menu item manager. 293 | let menuItemManager = MenuItemManager() 294 | 295 | // Initialize notification handler. 296 | let notificationHandler = NotificationHandler(menuItemManager: menuItemManager) 297 | 298 | // Start handling notifications. 299 | notificationHandler.handleNotifactions() 300 | 301 | // Start the run loop. 302 | RunLoop.current.run() 303 | 304 | -------------------------------------------------------------------------------- /FinderMenu.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6B8F97B323D828CB00BDB90D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6B8F97B223D828CB00BDB90D /* Assets.xcassets */; }; 11 | 6B8F97C123D82A1300BDB90D /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B8F97C023D82A1300BDB90D /* main.swift */; }; 12 | 6B8F97CA23D82D2100BDB90D /* RightClickActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B8F97C923D82D2100BDB90D /* RightClickActions.swift */; }; 13 | 6B8F97CF23D82D2100BDB90D /* FinderMenuItems.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 6B8F97C723D82D2100BDB90D /* FinderMenuItems.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 14 | 6BC8C4C523DD79C90010A119 /* Commons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BC8C4C423DD79C90010A119 /* Commons.swift */; }; 15 | 6BC8C4C623DD79F10010A119 /* Commons.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BF9386123DD79880016EE36 /* Commons.framework */; }; 16 | 6BC8C4C723DD79F10010A119 /* Commons.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6BF9386123DD79880016EE36 /* Commons.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 17 | 6BC8C4CA23DD79F70010A119 /* Commons.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BF9386123DD79880016EE36 /* Commons.framework */; }; 18 | 6BC8C4CB23DD79F70010A119 /* Commons.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6BF9386123DD79880016EE36 /* Commons.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 19 | 6BC8C4CE23DD7AAA0010A119 /* FinderMenuService.app in Resources */ = {isa = PBXBuildFile; fileRef = 6B8F988F23DD3B1C00BDB90D /* FinderMenuService.app */; }; 20 | 6BC8C4D623DE505E0010A119 /* com.samiyuru.findermenu-service.plist in Resources */ = {isa = PBXBuildFile; fileRef = 6BC8C4D523DE505E0010A119 /* com.samiyuru.findermenu-service.plist */; }; 21 | 6BC8C4D923DE532B0010A119 /* Open Text File Here.sh in Resources */ = {isa = PBXBuildFile; fileRef = 6BC8C4D723DE532B0010A119 /* Open Text File Here.sh */; }; 22 | 6BC8C4DA23DE532B0010A119 /* Open Terminal Here.sh in Resources */ = {isa = PBXBuildFile; fileRef = 6BC8C4D823DE532B0010A119 /* Open Terminal Here.sh */; }; 23 | 6BC8C4DD23DE53F10010A119 /* install-service.sh in Resources */ = {isa = PBXBuildFile; fileRef = 6BC8C4DC23DE53F10010A119 /* install-service.sh */; }; 24 | 6BC8C4DE23DE72010010A119 /* Commons.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BF9386123DD79880016EE36 /* Commons.framework */; }; 25 | 6BC8C4DF23DE72010010A119 /* Commons.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6BF9386123DD79880016EE36 /* Commons.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 26 | 6BF9384323DD71180016EE36 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BF9384223DD71180016EE36 /* main.swift */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | 6B8F97CD23D82D2100BDB90D /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 6B8F97A523D828CA00BDB90D /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 6B8F97C623D82D2100BDB90D; 35 | remoteInfo = RightClickItems; 36 | }; 37 | 6BC8C4C823DD79F10010A119 /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = 6B8F97A523D828CA00BDB90D /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = 6BF9386023DD79880016EE36; 42 | remoteInfo = Commons; 43 | }; 44 | 6BC8C4CC23DD79F70010A119 /* PBXContainerItemProxy */ = { 45 | isa = PBXContainerItemProxy; 46 | containerPortal = 6B8F97A523D828CA00BDB90D /* Project object */; 47 | proxyType = 1; 48 | remoteGlobalIDString = 6BF9386023DD79880016EE36; 49 | remoteInfo = Commons; 50 | }; 51 | 6BC8C4CF23DD7AAA0010A119 /* PBXContainerItemProxy */ = { 52 | isa = PBXContainerItemProxy; 53 | containerPortal = 6B8F97A523D828CA00BDB90D /* Project object */; 54 | proxyType = 1; 55 | remoteGlobalIDString = 6B8F988E23DD3B1C00BDB90D; 56 | remoteInfo = RightClickService; 57 | }; 58 | 6BC8C4E023DE72010010A119 /* PBXContainerItemProxy */ = { 59 | isa = PBXContainerItemProxy; 60 | containerPortal = 6B8F97A523D828CA00BDB90D /* Project object */; 61 | proxyType = 1; 62 | remoteGlobalIDString = 6BF9386023DD79880016EE36; 63 | remoteInfo = Commons; 64 | }; 65 | /* End PBXContainerItemProxy section */ 66 | 67 | /* Begin PBXCopyFilesBuildPhase section */ 68 | 6B8F97D323D82D2100BDB90D /* Embed App Extensions */ = { 69 | isa = PBXCopyFilesBuildPhase; 70 | buildActionMask = 2147483647; 71 | dstPath = ""; 72 | dstSubfolderSpec = 13; 73 | files = ( 74 | 6B8F97CF23D82D2100BDB90D /* FinderMenuItems.appex in Embed App Extensions */, 75 | ); 76 | name = "Embed App Extensions"; 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | 6B8F97F723DCCF4600BDB90D /* Embed XPC Services */ = { 80 | isa = PBXCopyFilesBuildPhase; 81 | buildActionMask = 2147483647; 82 | dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices"; 83 | dstSubfolderSpec = 16; 84 | files = ( 85 | ); 86 | name = "Embed XPC Services"; 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | 6BC8C4E223DE72010010A119 /* Embed Frameworks */ = { 90 | isa = PBXCopyFilesBuildPhase; 91 | buildActionMask = 2147483647; 92 | dstPath = ""; 93 | dstSubfolderSpec = 10; 94 | files = ( 95 | 6BC8C4DF23DE72010010A119 /* Commons.framework in Embed Frameworks */, 96 | ); 97 | name = "Embed Frameworks"; 98 | runOnlyForDeploymentPostprocessing = 0; 99 | }; 100 | 6BF9383523DD3C090016EE36 /* Embed Frameworks */ = { 101 | isa = PBXCopyFilesBuildPhase; 102 | buildActionMask = 2147483647; 103 | dstPath = ""; 104 | dstSubfolderSpec = 10; 105 | files = ( 106 | 6BC8C4CB23DD79F70010A119 /* Commons.framework in Embed Frameworks */, 107 | ); 108 | name = "Embed Frameworks"; 109 | runOnlyForDeploymentPostprocessing = 0; 110 | }; 111 | 6BF9383F23DD68780016EE36 /* Embed Frameworks */ = { 112 | isa = PBXCopyFilesBuildPhase; 113 | buildActionMask = 2147483647; 114 | dstPath = ""; 115 | dstSubfolderSpec = 10; 116 | files = ( 117 | 6BC8C4C723DD79F10010A119 /* Commons.framework in Embed Frameworks */, 118 | ); 119 | name = "Embed Frameworks"; 120 | runOnlyForDeploymentPostprocessing = 0; 121 | }; 122 | /* End PBXCopyFilesBuildPhase section */ 123 | 124 | /* Begin PBXFileReference section */ 125 | 6B8F97AD23D828CA00BDB90D /* FinderMenu.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FinderMenu.app; sourceTree = BUILT_PRODUCTS_DIR; }; 126 | 6B8F97B223D828CB00BDB90D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 127 | 6B8F97B723D828CB00BDB90D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 128 | 6B8F97B823D828CB00BDB90D /* FinderMenu.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = FinderMenu.entitlements; sourceTree = ""; }; 129 | 6B8F97C023D82A1300BDB90D /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 130 | 6B8F97C723D82D2100BDB90D /* FinderMenuItems.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = FinderMenuItems.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 131 | 6B8F97C923D82D2100BDB90D /* RightClickActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RightClickActions.swift; sourceTree = ""; }; 132 | 6B8F97CB23D82D2100BDB90D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 133 | 6B8F97CC23D82D2100BDB90D /* FinderMenuItems.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = FinderMenuItems.entitlements; sourceTree = ""; }; 134 | 6B8F988F23DD3B1C00BDB90D /* FinderMenuService.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FinderMenuService.app; sourceTree = BUILT_PRODUCTS_DIR; }; 135 | 6B8F989823DD3B1D00BDB90D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 136 | 6B8F989923DD3B1D00BDB90D /* FinderMenuService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = FinderMenuService.entitlements; sourceTree = ""; }; 137 | 6BC8C4C423DD79C90010A119 /* Commons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Commons.swift; sourceTree = ""; }; 138 | 6BC8C4D523DE505E0010A119 /* com.samiyuru.findermenu-service.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "com.samiyuru.findermenu-service.plist"; sourceTree = ""; }; 139 | 6BC8C4D723DE532B0010A119 /* Open Text File Here.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "Open Text File Here.sh"; path = "Scripts/Open Text File Here.sh"; sourceTree = SOURCE_ROOT; }; 140 | 6BC8C4D823DE532B0010A119 /* Open Terminal Here.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "Open Terminal Here.sh"; path = "Scripts/Open Terminal Here.sh"; sourceTree = SOURCE_ROOT; }; 141 | 6BC8C4DC23DE53F10010A119 /* install-service.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-service.sh"; sourceTree = ""; }; 142 | 6BF9384223DD71180016EE36 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 143 | 6BF9386123DD79880016EE36 /* Commons.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Commons.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 144 | 6BF9386423DD79880016EE36 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 145 | /* End PBXFileReference section */ 146 | 147 | /* Begin PBXFrameworksBuildPhase section */ 148 | 6B8F97AA23D828CA00BDB90D /* Frameworks */ = { 149 | isa = PBXFrameworksBuildPhase; 150 | buildActionMask = 2147483647; 151 | files = ( 152 | 6BC8C4DE23DE72010010A119 /* Commons.framework in Frameworks */, 153 | ); 154 | runOnlyForDeploymentPostprocessing = 0; 155 | }; 156 | 6B8F97C423D82D2100BDB90D /* Frameworks */ = { 157 | isa = PBXFrameworksBuildPhase; 158 | buildActionMask = 2147483647; 159 | files = ( 160 | 6BC8C4C623DD79F10010A119 /* Commons.framework in Frameworks */, 161 | ); 162 | runOnlyForDeploymentPostprocessing = 0; 163 | }; 164 | 6B8F988C23DD3B1C00BDB90D /* Frameworks */ = { 165 | isa = PBXFrameworksBuildPhase; 166 | buildActionMask = 2147483647; 167 | files = ( 168 | 6BC8C4CA23DD79F70010A119 /* Commons.framework in Frameworks */, 169 | ); 170 | runOnlyForDeploymentPostprocessing = 0; 171 | }; 172 | 6BF9385E23DD79880016EE36 /* Frameworks */ = { 173 | isa = PBXFrameworksBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | runOnlyForDeploymentPostprocessing = 0; 178 | }; 179 | /* End PBXFrameworksBuildPhase section */ 180 | 181 | /* Begin PBXGroup section */ 182 | 6B8F97A423D828CA00BDB90D = { 183 | isa = PBXGroup; 184 | children = ( 185 | 6B8F97AF23D828CA00BDB90D /* FinderMenu */, 186 | 6B8F97C823D82D2100BDB90D /* FinderMenuItems */, 187 | 6B8F989023DD3B1C00BDB90D /* FinderMenuService */, 188 | 6BF9386223DD79880016EE36 /* Commons */, 189 | 6B8F97AE23D828CA00BDB90D /* Products */, 190 | 6BF9383A23DD68780016EE36 /* Frameworks */, 191 | ); 192 | sourceTree = ""; 193 | }; 194 | 6B8F97AE23D828CA00BDB90D /* Products */ = { 195 | isa = PBXGroup; 196 | children = ( 197 | 6B8F97AD23D828CA00BDB90D /* FinderMenu.app */, 198 | 6B8F97C723D82D2100BDB90D /* FinderMenuItems.appex */, 199 | 6B8F988F23DD3B1C00BDB90D /* FinderMenuService.app */, 200 | 6BF9386123DD79880016EE36 /* Commons.framework */, 201 | ); 202 | name = Products; 203 | sourceTree = ""; 204 | }; 205 | 6B8F97AF23D828CA00BDB90D /* FinderMenu */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | 6BC8C4D223DE50140010A119 /* resources */, 209 | 6B8F97B223D828CB00BDB90D /* Assets.xcassets */, 210 | 6B8F97B723D828CB00BDB90D /* Info.plist */, 211 | 6B8F97B823D828CB00BDB90D /* FinderMenu.entitlements */, 212 | 6B8F97C023D82A1300BDB90D /* main.swift */, 213 | ); 214 | path = FinderMenu; 215 | sourceTree = ""; 216 | }; 217 | 6B8F97C823D82D2100BDB90D /* FinderMenuItems */ = { 218 | isa = PBXGroup; 219 | children = ( 220 | 6B8F97C923D82D2100BDB90D /* RightClickActions.swift */, 221 | 6B8F97CB23D82D2100BDB90D /* Info.plist */, 222 | 6B8F97CC23D82D2100BDB90D /* FinderMenuItems.entitlements */, 223 | ); 224 | path = FinderMenuItems; 225 | sourceTree = ""; 226 | }; 227 | 6B8F989023DD3B1C00BDB90D /* FinderMenuService */ = { 228 | isa = PBXGroup; 229 | children = ( 230 | 6B8F989823DD3B1D00BDB90D /* Info.plist */, 231 | 6B8F989923DD3B1D00BDB90D /* FinderMenuService.entitlements */, 232 | 6BF9384223DD71180016EE36 /* main.swift */, 233 | ); 234 | path = FinderMenuService; 235 | sourceTree = ""; 236 | }; 237 | 6BC8C4D223DE50140010A119 /* resources */ = { 238 | isa = PBXGroup; 239 | children = ( 240 | 6BC8C4D423DE50400010A119 /* launchd */, 241 | 6BC8C4D323DE502D0010A119 /* scripts */, 242 | ); 243 | path = resources; 244 | sourceTree = ""; 245 | }; 246 | 6BC8C4D323DE502D0010A119 /* scripts */ = { 247 | isa = PBXGroup; 248 | children = ( 249 | 6BC8C4D823DE532B0010A119 /* Open Terminal Here.sh */, 250 | 6BC8C4D723DE532B0010A119 /* Open Text File Here.sh */, 251 | ); 252 | path = scripts; 253 | sourceTree = ""; 254 | }; 255 | 6BC8C4D423DE50400010A119 /* launchd */ = { 256 | isa = PBXGroup; 257 | children = ( 258 | 6BC8C4DC23DE53F10010A119 /* install-service.sh */, 259 | 6BC8C4D523DE505E0010A119 /* com.samiyuru.findermenu-service.plist */, 260 | ); 261 | path = launchd; 262 | sourceTree = ""; 263 | }; 264 | 6BF9383A23DD68780016EE36 /* Frameworks */ = { 265 | isa = PBXGroup; 266 | children = ( 267 | ); 268 | name = Frameworks; 269 | sourceTree = ""; 270 | }; 271 | 6BF9386223DD79880016EE36 /* Commons */ = { 272 | isa = PBXGroup; 273 | children = ( 274 | 6BC8C4C423DD79C90010A119 /* Commons.swift */, 275 | 6BF9386423DD79880016EE36 /* Info.plist */, 276 | ); 277 | path = Commons; 278 | sourceTree = ""; 279 | }; 280 | /* End PBXGroup section */ 281 | 282 | /* Begin PBXHeadersBuildPhase section */ 283 | 6BF9385C23DD79880016EE36 /* Headers */ = { 284 | isa = PBXHeadersBuildPhase; 285 | buildActionMask = 2147483647; 286 | files = ( 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | }; 290 | /* End PBXHeadersBuildPhase section */ 291 | 292 | /* Begin PBXNativeTarget section */ 293 | 6B8F97AC23D828CA00BDB90D /* FinderMenu */ = { 294 | isa = PBXNativeTarget; 295 | buildConfigurationList = 6B8F97BB23D828CB00BDB90D /* Build configuration list for PBXNativeTarget "FinderMenu" */; 296 | buildPhases = ( 297 | 6B8F97A923D828CA00BDB90D /* Sources */, 298 | 6B8F97AA23D828CA00BDB90D /* Frameworks */, 299 | 6B8F97AB23D828CA00BDB90D /* Resources */, 300 | 6B8F97D323D82D2100BDB90D /* Embed App Extensions */, 301 | 6B8F97F723DCCF4600BDB90D /* Embed XPC Services */, 302 | 6BC8C4E223DE72010010A119 /* Embed Frameworks */, 303 | ); 304 | buildRules = ( 305 | ); 306 | dependencies = ( 307 | 6B8F97CE23D82D2100BDB90D /* PBXTargetDependency */, 308 | 6BC8C4D023DD7AAA0010A119 /* PBXTargetDependency */, 309 | 6BC8C4E123DE72010010A119 /* PBXTargetDependency */, 310 | ); 311 | name = FinderMenu; 312 | productName = FinderMenu; 313 | productReference = 6B8F97AD23D828CA00BDB90D /* FinderMenu.app */; 314 | productType = "com.apple.product-type.application"; 315 | }; 316 | 6B8F97C623D82D2100BDB90D /* FinderMenuItems */ = { 317 | isa = PBXNativeTarget; 318 | buildConfigurationList = 6B8F97D023D82D2100BDB90D /* Build configuration list for PBXNativeTarget "FinderMenuItems" */; 319 | buildPhases = ( 320 | 6B8F97C323D82D2100BDB90D /* Sources */, 321 | 6B8F97C423D82D2100BDB90D /* Frameworks */, 322 | 6B8F97C523D82D2100BDB90D /* Resources */, 323 | 6BF9383F23DD68780016EE36 /* Embed Frameworks */, 324 | ); 325 | buildRules = ( 326 | ); 327 | dependencies = ( 328 | 6BC8C4C923DD79F10010A119 /* PBXTargetDependency */, 329 | ); 330 | name = FinderMenuItems; 331 | productName = RightClickItems; 332 | productReference = 6B8F97C723D82D2100BDB90D /* FinderMenuItems.appex */; 333 | productType = "com.apple.product-type.app-extension"; 334 | }; 335 | 6B8F988E23DD3B1C00BDB90D /* FinderMenuService */ = { 336 | isa = PBXNativeTarget; 337 | buildConfigurationList = 6B8F989A23DD3B1D00BDB90D /* Build configuration list for PBXNativeTarget "FinderMenuService" */; 338 | buildPhases = ( 339 | 6B8F988B23DD3B1C00BDB90D /* Sources */, 340 | 6B8F988C23DD3B1C00BDB90D /* Frameworks */, 341 | 6B8F988D23DD3B1C00BDB90D /* Resources */, 342 | 6BF9383523DD3C090016EE36 /* Embed Frameworks */, 343 | ); 344 | buildRules = ( 345 | ); 346 | dependencies = ( 347 | 6BC8C4CD23DD79F70010A119 /* PBXTargetDependency */, 348 | ); 349 | name = FinderMenuService; 350 | productName = RightClickService; 351 | productReference = 6B8F988F23DD3B1C00BDB90D /* FinderMenuService.app */; 352 | productType = "com.apple.product-type.application"; 353 | }; 354 | 6BF9386023DD79880016EE36 /* Commons */ = { 355 | isa = PBXNativeTarget; 356 | buildConfigurationList = 6BF9386A23DD79890016EE36 /* Build configuration list for PBXNativeTarget "Commons" */; 357 | buildPhases = ( 358 | 6BF9385C23DD79880016EE36 /* Headers */, 359 | 6BF9385D23DD79880016EE36 /* Sources */, 360 | 6BF9385E23DD79880016EE36 /* Frameworks */, 361 | 6BF9385F23DD79880016EE36 /* Resources */, 362 | ); 363 | buildRules = ( 364 | ); 365 | dependencies = ( 366 | ); 367 | name = Commons; 368 | productName = Commons; 369 | productReference = 6BF9386123DD79880016EE36 /* Commons.framework */; 370 | productType = "com.apple.product-type.framework"; 371 | }; 372 | /* End PBXNativeTarget section */ 373 | 374 | /* Begin PBXProject section */ 375 | 6B8F97A523D828CA00BDB90D /* Project object */ = { 376 | isa = PBXProject; 377 | attributes = { 378 | LastSwiftUpdateCheck = 1130; 379 | LastUpgradeCheck = 1140; 380 | ORGANIZATIONNAME = "Samiyuru Senarathne"; 381 | TargetAttributes = { 382 | 6B8F97AC23D828CA00BDB90D = { 383 | CreatedOnToolsVersion = 11.3.1; 384 | }; 385 | 6B8F97C623D82D2100BDB90D = { 386 | CreatedOnToolsVersion = 11.3.1; 387 | }; 388 | 6B8F988E23DD3B1C00BDB90D = { 389 | CreatedOnToolsVersion = 11.3.1; 390 | LastSwiftMigration = 1130; 391 | }; 392 | 6BF9386023DD79880016EE36 = { 393 | CreatedOnToolsVersion = 11.3.1; 394 | LastSwiftMigration = 1130; 395 | }; 396 | }; 397 | }; 398 | buildConfigurationList = 6B8F97A823D828CA00BDB90D /* Build configuration list for PBXProject "FinderMenu" */; 399 | compatibilityVersion = "Xcode 9.3"; 400 | developmentRegion = en; 401 | hasScannedForEncodings = 0; 402 | knownRegions = ( 403 | en, 404 | Base, 405 | ); 406 | mainGroup = 6B8F97A423D828CA00BDB90D; 407 | productRefGroup = 6B8F97AE23D828CA00BDB90D /* Products */; 408 | projectDirPath = ""; 409 | projectRoot = ""; 410 | targets = ( 411 | 6B8F97AC23D828CA00BDB90D /* FinderMenu */, 412 | 6B8F97C623D82D2100BDB90D /* FinderMenuItems */, 413 | 6B8F988E23DD3B1C00BDB90D /* FinderMenuService */, 414 | 6BF9386023DD79880016EE36 /* Commons */, 415 | ); 416 | }; 417 | /* End PBXProject section */ 418 | 419 | /* Begin PBXResourcesBuildPhase section */ 420 | 6B8F97AB23D828CA00BDB90D /* Resources */ = { 421 | isa = PBXResourcesBuildPhase; 422 | buildActionMask = 2147483647; 423 | files = ( 424 | 6BC8C4DD23DE53F10010A119 /* install-service.sh in Resources */, 425 | 6BC8C4D623DE505E0010A119 /* com.samiyuru.findermenu-service.plist in Resources */, 426 | 6B8F97B323D828CB00BDB90D /* Assets.xcassets in Resources */, 427 | 6BC8C4DA23DE532B0010A119 /* Open Terminal Here.sh in Resources */, 428 | 6BC8C4D923DE532B0010A119 /* Open Text File Here.sh in Resources */, 429 | 6BC8C4CE23DD7AAA0010A119 /* FinderMenuService.app in Resources */, 430 | ); 431 | runOnlyForDeploymentPostprocessing = 0; 432 | }; 433 | 6B8F97C523D82D2100BDB90D /* Resources */ = { 434 | isa = PBXResourcesBuildPhase; 435 | buildActionMask = 2147483647; 436 | files = ( 437 | ); 438 | runOnlyForDeploymentPostprocessing = 0; 439 | }; 440 | 6B8F988D23DD3B1C00BDB90D /* Resources */ = { 441 | isa = PBXResourcesBuildPhase; 442 | buildActionMask = 2147483647; 443 | files = ( 444 | ); 445 | runOnlyForDeploymentPostprocessing = 0; 446 | }; 447 | 6BF9385F23DD79880016EE36 /* Resources */ = { 448 | isa = PBXResourcesBuildPhase; 449 | buildActionMask = 2147483647; 450 | files = ( 451 | ); 452 | runOnlyForDeploymentPostprocessing = 0; 453 | }; 454 | /* End PBXResourcesBuildPhase section */ 455 | 456 | /* Begin PBXSourcesBuildPhase section */ 457 | 6B8F97A923D828CA00BDB90D /* Sources */ = { 458 | isa = PBXSourcesBuildPhase; 459 | buildActionMask = 2147483647; 460 | files = ( 461 | 6B8F97C123D82A1300BDB90D /* main.swift in Sources */, 462 | ); 463 | runOnlyForDeploymentPostprocessing = 0; 464 | }; 465 | 6B8F97C323D82D2100BDB90D /* Sources */ = { 466 | isa = PBXSourcesBuildPhase; 467 | buildActionMask = 2147483647; 468 | files = ( 469 | 6B8F97CA23D82D2100BDB90D /* RightClickActions.swift in Sources */, 470 | ); 471 | runOnlyForDeploymentPostprocessing = 0; 472 | }; 473 | 6B8F988B23DD3B1C00BDB90D /* Sources */ = { 474 | isa = PBXSourcesBuildPhase; 475 | buildActionMask = 2147483647; 476 | files = ( 477 | 6BF9384323DD71180016EE36 /* main.swift in Sources */, 478 | ); 479 | runOnlyForDeploymentPostprocessing = 0; 480 | }; 481 | 6BF9385D23DD79880016EE36 /* Sources */ = { 482 | isa = PBXSourcesBuildPhase; 483 | buildActionMask = 2147483647; 484 | files = ( 485 | 6BC8C4C523DD79C90010A119 /* Commons.swift in Sources */, 486 | ); 487 | runOnlyForDeploymentPostprocessing = 0; 488 | }; 489 | /* End PBXSourcesBuildPhase section */ 490 | 491 | /* Begin PBXTargetDependency section */ 492 | 6B8F97CE23D82D2100BDB90D /* PBXTargetDependency */ = { 493 | isa = PBXTargetDependency; 494 | target = 6B8F97C623D82D2100BDB90D /* FinderMenuItems */; 495 | targetProxy = 6B8F97CD23D82D2100BDB90D /* PBXContainerItemProxy */; 496 | }; 497 | 6BC8C4C923DD79F10010A119 /* PBXTargetDependency */ = { 498 | isa = PBXTargetDependency; 499 | target = 6BF9386023DD79880016EE36 /* Commons */; 500 | targetProxy = 6BC8C4C823DD79F10010A119 /* PBXContainerItemProxy */; 501 | }; 502 | 6BC8C4CD23DD79F70010A119 /* PBXTargetDependency */ = { 503 | isa = PBXTargetDependency; 504 | target = 6BF9386023DD79880016EE36 /* Commons */; 505 | targetProxy = 6BC8C4CC23DD79F70010A119 /* PBXContainerItemProxy */; 506 | }; 507 | 6BC8C4D023DD7AAA0010A119 /* PBXTargetDependency */ = { 508 | isa = PBXTargetDependency; 509 | target = 6B8F988E23DD3B1C00BDB90D /* FinderMenuService */; 510 | targetProxy = 6BC8C4CF23DD7AAA0010A119 /* PBXContainerItemProxy */; 511 | }; 512 | 6BC8C4E123DE72010010A119 /* PBXTargetDependency */ = { 513 | isa = PBXTargetDependency; 514 | target = 6BF9386023DD79880016EE36 /* Commons */; 515 | targetProxy = 6BC8C4E023DE72010010A119 /* PBXContainerItemProxy */; 516 | }; 517 | /* End PBXTargetDependency section */ 518 | 519 | /* Begin XCBuildConfiguration section */ 520 | 6B8F97B923D828CB00BDB90D /* Debug */ = { 521 | isa = XCBuildConfiguration; 522 | buildSettings = { 523 | ALWAYS_SEARCH_USER_PATHS = NO; 524 | CLANG_ANALYZER_NONNULL = YES; 525 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 526 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 527 | CLANG_CXX_LIBRARY = "libc++"; 528 | CLANG_ENABLE_MODULES = YES; 529 | CLANG_ENABLE_OBJC_ARC = YES; 530 | CLANG_ENABLE_OBJC_WEAK = YES; 531 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 532 | CLANG_WARN_BOOL_CONVERSION = YES; 533 | CLANG_WARN_COMMA = YES; 534 | CLANG_WARN_CONSTANT_CONVERSION = YES; 535 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 536 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 537 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 538 | CLANG_WARN_EMPTY_BODY = YES; 539 | CLANG_WARN_ENUM_CONVERSION = YES; 540 | CLANG_WARN_INFINITE_RECURSION = YES; 541 | CLANG_WARN_INT_CONVERSION = YES; 542 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 543 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 544 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 545 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 546 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 547 | CLANG_WARN_STRICT_PROTOTYPES = YES; 548 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 549 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 550 | CLANG_WARN_UNREACHABLE_CODE = YES; 551 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 552 | COPY_PHASE_STRIP = NO; 553 | DEBUG_INFORMATION_FORMAT = dwarf; 554 | ENABLE_STRICT_OBJC_MSGSEND = YES; 555 | ENABLE_TESTABILITY = YES; 556 | GCC_C_LANGUAGE_STANDARD = gnu11; 557 | GCC_DYNAMIC_NO_PIC = NO; 558 | GCC_NO_COMMON_BLOCKS = YES; 559 | GCC_OPTIMIZATION_LEVEL = 0; 560 | GCC_PREPROCESSOR_DEFINITIONS = ( 561 | "DEBUG=1", 562 | "$(inherited)", 563 | ); 564 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 565 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 566 | GCC_WARN_UNDECLARED_SELECTOR = YES; 567 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 568 | GCC_WARN_UNUSED_FUNCTION = YES; 569 | GCC_WARN_UNUSED_VARIABLE = YES; 570 | MACOSX_DEPLOYMENT_TARGET = 10.15; 571 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 572 | MTL_FAST_MATH = YES; 573 | ONLY_ACTIVE_ARCH = YES; 574 | SDKROOT = macosx; 575 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 576 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 577 | }; 578 | name = Debug; 579 | }; 580 | 6B8F97BA23D828CB00BDB90D /* Release */ = { 581 | isa = XCBuildConfiguration; 582 | buildSettings = { 583 | ALWAYS_SEARCH_USER_PATHS = NO; 584 | CLANG_ANALYZER_NONNULL = YES; 585 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 586 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 587 | CLANG_CXX_LIBRARY = "libc++"; 588 | CLANG_ENABLE_MODULES = YES; 589 | CLANG_ENABLE_OBJC_ARC = YES; 590 | CLANG_ENABLE_OBJC_WEAK = YES; 591 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 592 | CLANG_WARN_BOOL_CONVERSION = YES; 593 | CLANG_WARN_COMMA = YES; 594 | CLANG_WARN_CONSTANT_CONVERSION = YES; 595 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 596 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 597 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 598 | CLANG_WARN_EMPTY_BODY = YES; 599 | CLANG_WARN_ENUM_CONVERSION = YES; 600 | CLANG_WARN_INFINITE_RECURSION = YES; 601 | CLANG_WARN_INT_CONVERSION = YES; 602 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 603 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 604 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 605 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 606 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 607 | CLANG_WARN_STRICT_PROTOTYPES = YES; 608 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 609 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 610 | CLANG_WARN_UNREACHABLE_CODE = YES; 611 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 612 | COPY_PHASE_STRIP = NO; 613 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 614 | ENABLE_NS_ASSERTIONS = NO; 615 | ENABLE_STRICT_OBJC_MSGSEND = YES; 616 | GCC_C_LANGUAGE_STANDARD = gnu11; 617 | GCC_NO_COMMON_BLOCKS = YES; 618 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 619 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 620 | GCC_WARN_UNDECLARED_SELECTOR = YES; 621 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 622 | GCC_WARN_UNUSED_FUNCTION = YES; 623 | GCC_WARN_UNUSED_VARIABLE = YES; 624 | MACOSX_DEPLOYMENT_TARGET = 10.15; 625 | MTL_ENABLE_DEBUG_INFO = NO; 626 | MTL_FAST_MATH = YES; 627 | SDKROOT = macosx; 628 | SWIFT_COMPILATION_MODE = wholemodule; 629 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 630 | }; 631 | name = Release; 632 | }; 633 | 6B8F97BC23D828CB00BDB90D /* Debug */ = { 634 | isa = XCBuildConfiguration; 635 | buildSettings = { 636 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 637 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 638 | CODE_SIGN_ENTITLEMENTS = FinderMenu/FinderMenu.entitlements; 639 | CODE_SIGN_IDENTITY = "-"; 640 | CODE_SIGN_STYLE = Automatic; 641 | COMBINE_HIDPI_IMAGES = YES; 642 | INFOPLIST_FILE = FinderMenu/Info.plist; 643 | LD_RUNPATH_SEARCH_PATHS = ( 644 | "$(inherited)", 645 | "@executable_path/../Frameworks", 646 | ); 647 | PRODUCT_BUNDLE_IDENTIFIER = com.samiyuru.FinderMenu; 648 | PRODUCT_NAME = "$(TARGET_NAME)"; 649 | SWIFT_VERSION = 5.0; 650 | }; 651 | name = Debug; 652 | }; 653 | 6B8F97BD23D828CB00BDB90D /* Release */ = { 654 | isa = XCBuildConfiguration; 655 | buildSettings = { 656 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 657 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 658 | CODE_SIGN_ENTITLEMENTS = FinderMenu/FinderMenu.entitlements; 659 | CODE_SIGN_IDENTITY = "-"; 660 | CODE_SIGN_STYLE = Automatic; 661 | COMBINE_HIDPI_IMAGES = YES; 662 | INFOPLIST_FILE = FinderMenu/Info.plist; 663 | LD_RUNPATH_SEARCH_PATHS = ( 664 | "$(inherited)", 665 | "@executable_path/../Frameworks", 666 | ); 667 | PRODUCT_BUNDLE_IDENTIFIER = com.samiyuru.FinderMenu; 668 | PRODUCT_NAME = "$(TARGET_NAME)"; 669 | SWIFT_VERSION = 5.0; 670 | }; 671 | name = Release; 672 | }; 673 | 6B8F97D123D82D2100BDB90D /* Debug */ = { 674 | isa = XCBuildConfiguration; 675 | buildSettings = { 676 | CODE_SIGN_ENTITLEMENTS = FinderMenuItems/FinderMenuItems.entitlements; 677 | CODE_SIGN_IDENTITY = "-"; 678 | CODE_SIGN_STYLE = Automatic; 679 | COMBINE_HIDPI_IMAGES = YES; 680 | DEVELOPMENT_TEAM = ""; 681 | INFOPLIST_FILE = FinderMenuItems/Info.plist; 682 | LD_RUNPATH_SEARCH_PATHS = ( 683 | "$(inherited)", 684 | "@executable_path/../Frameworks", 685 | "@executable_path/../../../../Frameworks", 686 | ); 687 | PRODUCT_BUNDLE_IDENTIFIER = com.samiyuru.FinderMenu.FinderMenuItems; 688 | PRODUCT_NAME = "$(TARGET_NAME)"; 689 | SKIP_INSTALL = YES; 690 | SWIFT_VERSION = 5.0; 691 | }; 692 | name = Debug; 693 | }; 694 | 6B8F97D223D82D2100BDB90D /* Release */ = { 695 | isa = XCBuildConfiguration; 696 | buildSettings = { 697 | CODE_SIGN_ENTITLEMENTS = FinderMenuItems/FinderMenuItems.entitlements; 698 | CODE_SIGN_IDENTITY = "-"; 699 | CODE_SIGN_STYLE = Automatic; 700 | COMBINE_HIDPI_IMAGES = YES; 701 | DEVELOPMENT_TEAM = ""; 702 | INFOPLIST_FILE = FinderMenuItems/Info.plist; 703 | LD_RUNPATH_SEARCH_PATHS = ( 704 | "$(inherited)", 705 | "@executable_path/../Frameworks", 706 | "@executable_path/../../../../Frameworks", 707 | ); 708 | PRODUCT_BUNDLE_IDENTIFIER = com.samiyuru.FinderMenu.FinderMenuItems; 709 | PRODUCT_NAME = "$(TARGET_NAME)"; 710 | SKIP_INSTALL = YES; 711 | SWIFT_VERSION = 5.0; 712 | }; 713 | name = Release; 714 | }; 715 | 6B8F989B23DD3B1D00BDB90D /* Debug */ = { 716 | isa = XCBuildConfiguration; 717 | buildSettings = { 718 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 719 | CLANG_ENABLE_MODULES = YES; 720 | CODE_SIGN_ENTITLEMENTS = FinderMenuService/FinderMenuService.entitlements; 721 | CODE_SIGN_IDENTITY = "-"; 722 | CODE_SIGN_STYLE = Automatic; 723 | COMBINE_HIDPI_IMAGES = YES; 724 | INFOPLIST_FILE = FinderMenuService/Info.plist; 725 | LD_RUNPATH_SEARCH_PATHS = ( 726 | "$(inherited)", 727 | "@executable_path/../Frameworks", 728 | ); 729 | PRODUCT_BUNDLE_IDENTIFIER = com.samiyuru.FinderMenuService; 730 | PRODUCT_NAME = "$(TARGET_NAME)"; 731 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 732 | SWIFT_VERSION = 5.0; 733 | }; 734 | name = Debug; 735 | }; 736 | 6B8F989C23DD3B1D00BDB90D /* Release */ = { 737 | isa = XCBuildConfiguration; 738 | buildSettings = { 739 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 740 | CLANG_ENABLE_MODULES = YES; 741 | CODE_SIGN_ENTITLEMENTS = FinderMenuService/FinderMenuService.entitlements; 742 | CODE_SIGN_IDENTITY = "-"; 743 | CODE_SIGN_STYLE = Automatic; 744 | COMBINE_HIDPI_IMAGES = YES; 745 | INFOPLIST_FILE = FinderMenuService/Info.plist; 746 | LD_RUNPATH_SEARCH_PATHS = ( 747 | "$(inherited)", 748 | "@executable_path/../Frameworks", 749 | ); 750 | PRODUCT_BUNDLE_IDENTIFIER = com.samiyuru.FinderMenuService; 751 | PRODUCT_NAME = "$(TARGET_NAME)"; 752 | SWIFT_VERSION = 5.0; 753 | }; 754 | name = Release; 755 | }; 756 | 6BF9386B23DD79890016EE36 /* Debug */ = { 757 | isa = XCBuildConfiguration; 758 | buildSettings = { 759 | CLANG_ENABLE_MODULES = YES; 760 | CODE_SIGN_STYLE = Automatic; 761 | COMBINE_HIDPI_IMAGES = YES; 762 | CURRENT_PROJECT_VERSION = 1; 763 | DEFINES_MODULE = YES; 764 | DYLIB_COMPATIBILITY_VERSION = 1; 765 | DYLIB_CURRENT_VERSION = 1; 766 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 767 | INFOPLIST_FILE = Commons/Info.plist; 768 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 769 | LD_RUNPATH_SEARCH_PATHS = ( 770 | "$(inherited)", 771 | "@executable_path/../Frameworks", 772 | "@loader_path/Frameworks", 773 | ); 774 | PRODUCT_BUNDLE_IDENTIFIER = com.samiyuru.Commons; 775 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 776 | SKIP_INSTALL = YES; 777 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 778 | SWIFT_VERSION = 5.0; 779 | VERSIONING_SYSTEM = "apple-generic"; 780 | VERSION_INFO_PREFIX = ""; 781 | }; 782 | name = Debug; 783 | }; 784 | 6BF9386C23DD79890016EE36 /* Release */ = { 785 | isa = XCBuildConfiguration; 786 | buildSettings = { 787 | CLANG_ENABLE_MODULES = YES; 788 | CODE_SIGN_STYLE = Automatic; 789 | COMBINE_HIDPI_IMAGES = YES; 790 | CURRENT_PROJECT_VERSION = 1; 791 | DEFINES_MODULE = YES; 792 | DYLIB_COMPATIBILITY_VERSION = 1; 793 | DYLIB_CURRENT_VERSION = 1; 794 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 795 | INFOPLIST_FILE = Commons/Info.plist; 796 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 797 | LD_RUNPATH_SEARCH_PATHS = ( 798 | "$(inherited)", 799 | "@executable_path/../Frameworks", 800 | "@loader_path/Frameworks", 801 | ); 802 | PRODUCT_BUNDLE_IDENTIFIER = com.samiyuru.Commons; 803 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 804 | SKIP_INSTALL = YES; 805 | SWIFT_VERSION = 5.0; 806 | VERSIONING_SYSTEM = "apple-generic"; 807 | VERSION_INFO_PREFIX = ""; 808 | }; 809 | name = Release; 810 | }; 811 | /* End XCBuildConfiguration section */ 812 | 813 | /* Begin XCConfigurationList section */ 814 | 6B8F97A823D828CA00BDB90D /* Build configuration list for PBXProject "FinderMenu" */ = { 815 | isa = XCConfigurationList; 816 | buildConfigurations = ( 817 | 6B8F97B923D828CB00BDB90D /* Debug */, 818 | 6B8F97BA23D828CB00BDB90D /* Release */, 819 | ); 820 | defaultConfigurationIsVisible = 0; 821 | defaultConfigurationName = Release; 822 | }; 823 | 6B8F97BB23D828CB00BDB90D /* Build configuration list for PBXNativeTarget "FinderMenu" */ = { 824 | isa = XCConfigurationList; 825 | buildConfigurations = ( 826 | 6B8F97BC23D828CB00BDB90D /* Debug */, 827 | 6B8F97BD23D828CB00BDB90D /* Release */, 828 | ); 829 | defaultConfigurationIsVisible = 0; 830 | defaultConfigurationName = Release; 831 | }; 832 | 6B8F97D023D82D2100BDB90D /* Build configuration list for PBXNativeTarget "FinderMenuItems" */ = { 833 | isa = XCConfigurationList; 834 | buildConfigurations = ( 835 | 6B8F97D123D82D2100BDB90D /* Debug */, 836 | 6B8F97D223D82D2100BDB90D /* Release */, 837 | ); 838 | defaultConfigurationIsVisible = 0; 839 | defaultConfigurationName = Release; 840 | }; 841 | 6B8F989A23DD3B1D00BDB90D /* Build configuration list for PBXNativeTarget "FinderMenuService" */ = { 842 | isa = XCConfigurationList; 843 | buildConfigurations = ( 844 | 6B8F989B23DD3B1D00BDB90D /* Debug */, 845 | 6B8F989C23DD3B1D00BDB90D /* Release */, 846 | ); 847 | defaultConfigurationIsVisible = 0; 848 | defaultConfigurationName = Release; 849 | }; 850 | 6BF9386A23DD79890016EE36 /* Build configuration list for PBXNativeTarget "Commons" */ = { 851 | isa = XCConfigurationList; 852 | buildConfigurations = ( 853 | 6BF9386B23DD79890016EE36 /* Debug */, 854 | 6BF9386C23DD79890016EE36 /* Release */, 855 | ); 856 | defaultConfigurationIsVisible = 0; 857 | defaultConfigurationName = Release; 858 | }; 859 | /* End XCConfigurationList section */ 860 | }; 861 | rootObject = 6B8F97A523D828CA00BDB90D /* Project object */; 862 | } 863 | --------------------------------------------------------------------------------