├── .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 | 
37 |
38 | The next gif shows how the provided "Open Terminal Here" menu item works.
39 |
40 | 
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 |
--------------------------------------------------------------------------------