├── .gitignore
├── EditorPlusExtension
├── EditorPlusExtension.entitlements
├── Info.plist
├── SourceEditorCommand.swift
└── SourceEditorExtension.swift
├── LICENSE
├── README.md
├── XcodeEditorPlus.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ └── contents.xcworkspacedata
└── XcodeEditorPlus
├── AppDelegate.swift
├── Assets.xcassets
└── AppIcon.appiconset
│ └── Contents.json
├── Base.lproj
└── MainMenu.xib
└── Info.plist
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 |
4 | # Xcode
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata
15 | *.xccheckout
16 | *.xcscmblueprint
17 | profile
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 |
23 | # Bundler
24 | .bundle
25 |
26 | Carthage
27 | # We recommend against adding the Pods directory to your .gitignore. However
28 | # you should judge for yourself, the pros and cons are mentioned at:
29 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
30 | #
31 | # Note: if you ignore the Pods directory, make sure to uncomment
32 | # `pod install` in .travis.yml
33 | #
34 | # Pods/
35 |
--------------------------------------------------------------------------------
/EditorPlusExtension/EditorPlusExtension.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/EditorPlusExtension/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | EditorPlusExtension
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | XPC!
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSMinimumSystemVersion
26 | $(MACOSX_DEPLOYMENT_TARGET)
27 | NSExtension
28 |
29 | NSExtensionAttributes
30 |
31 | XCSourceEditorCommandDefinitions
32 |
33 |
34 | XCSourceEditorCommandClassName
35 | $(PRODUCT_MODULE_NAME).SourceEditorCommand
36 | XCSourceEditorCommandIdentifier
37 | delete_lines
38 | XCSourceEditorCommandName
39 | Delete Lines
40 |
41 |
42 | XCSourceEditorCommandClassName
43 | $(PRODUCT_MODULE_NAME).SourceEditorCommand
44 | XCSourceEditorCommandIdentifier
45 | duplicate_lines
46 | XCSourceEditorCommandName
47 | Duplicate Lines
48 |
49 |
50 | XCSourceEditorExtensionPrincipalClass
51 | $(PRODUCT_MODULE_NAME).SourceEditorExtension
52 |
53 | NSExtensionPointIdentifier
54 | com.apple.dt.Xcode.extension.source-editor
55 |
56 | NSHumanReadableCopyright
57 | Copyright © 2016 Victor Wang. All rights reserved.
58 |
59 |
60 |
--------------------------------------------------------------------------------
/EditorPlusExtension/SourceEditorCommand.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SourceEditorCommand.swift
3 | // EditorPlusExtension
4 | //
5 | // Created by Victor WANG on 02/07/2016.
6 | // Copyright © 2016 Victor Wang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | class SourceEditorCommand: NSObject, XCSourceEditorCommand {
13 |
14 | public func perform(with invocation: XCSourceEditorCommandInvocation,
15 | completionHandler: @escaping (Error?) -> Swift.Void) {
16 |
17 | /// Fail fast if there is no text selected at all or there is no text in the file
18 | guard let textRange = invocation.buffer.selections.firstObject as? XCSourceTextRange,
19 | invocation.buffer.lines.count > 0 else {
20 | /// Usually we may want to pass a concrete error into handler block.
21 | /// But in this case, it's fine to let it failed silencely.
22 | completionHandler(nil)
23 | return
24 | }
25 |
26 | /// Properly handle line selections
27 | let lineSelection = textRange.start.column == 0
28 | && textRange.end.column == 0
29 | && textRange.start.line != textRange.end.line
30 | let upperBound = lineSelection ? textRange.end.line : textRange.end.line + 1
31 |
32 | /// Build target range(Range) based on given text range(XCSourceTextRange)
33 | let targetRange = Range(uncheckedBounds: (lower: textRange.start.line, upper: min(upperBound, invocation.buffer.lines.count)))
34 |
35 | /// Switch all different commands id based which defined in Info.plist
36 | switch invocation.commandIdentifier {
37 | case "delete_lines":
38 | deleteLines(on: targetRange, with: invocation)
39 | resetSelection(to: targetRange.lowerBound, with: invocation)
40 | case "duplicate_lines":
41 | duplicateLines(on: targetRange, with: invocation)
42 | default:
43 | break
44 | }
45 |
46 | /// Call handler to tell the system we are done here.
47 | completionHandler(nil)
48 | }
49 | }
50 |
51 | extension SourceEditorCommand {
52 |
53 | /// The method which delete lines by manipulating
54 | /// the given mutable text buffer.
55 | ///
56 | /// - parameter range: range of lines should be deleted
57 | /// - parameter invocation: invocation which contains the text buffer invovled
58 | fileprivate func deleteLines(on range: Range, with invocation: XCSourceEditorCommandInvocation) {
59 |
60 | invocation.buffer.lines.removeObjects(at: IndexSet(integersIn: range))
61 | }
62 |
63 | /// The method which duplicate lines by manipulating
64 | /// the given mutable text buffer.
65 | ///
66 | /// - parameter range: range of lines should be duplicated
67 | /// - parameter invocation: invocation which contains the text buffer invovled
68 | fileprivate func duplicateLines(on range: Range, with invocation: XCSourceEditorCommandInvocation) {
69 |
70 | let indexSet = IndexSet(integersIn: range)
71 | let selectedLines = invocation.buffer.lines.objects(at: indexSet)
72 |
73 | invocation.buffer.lines.insert(selectedLines, at: indexSet)
74 | }
75 |
76 | /// The method will reset selection to the beginning of the given line.
77 | ///
78 | /// - parameter line: line to reset selection to
79 | /// - parameter invocation: invocation which contains the text buffer invovled
80 | fileprivate func resetSelection(to line: Int, with invocation: XCSourceEditorCommandInvocation) {
81 | invocation.buffer.selections.removeAllObjects()
82 | let position = XCSourceTextPosition(line: line, column: 0)
83 | let selection = XCSourceTextRange(start: position, end: position)
84 | invocation.buffer.selections.add(selection)
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/EditorPlusExtension/SourceEditorExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SourceEditorExtension.swift
3 | // EditorPlusExtension
4 | //
5 | // Created by Victor WANG on 02/07/2016.
6 | // Copyright © 2016 Victor Wang. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | class SourceEditorExtension: NSObject, XCSourceEditorExtension {
13 |
14 | /*
15 | func extensionDidFinishLaunching() {
16 | // If your extension needs to do any work at launch, implement this optional method.
17 | }
18 | */
19 |
20 | /*
21 | var commandDefinitions: [[XCSourceEditorCommandDefinitionKey: AnyObject]] {
22 | // If your extension needs to return a collection of command definitions that differs from those in its Info.plist, implement this optional property getter.
23 | return []
24 | }
25 | */
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 WANG Shengjia
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Xcode Editor Plus
2 | Bring some convenient editor shortcuts to Xcode using Xcode Source Editor Extension, inspired from AppCode.
3 |
4 | Here is a [blog post](http://allblue.me/xcode/2016/06/28/Build-your-own-Xcode-8-source-editor-extension/) which explains more details about why & how, please check it out.
5 |
6 | ## Features
7 |
8 | - [x] Delete Lines
9 | - [x] Duplicate Lines
10 | - [ ] Auto format line-split string
11 | - [ ] Toggle string cases
12 | - [ ] Block commenter
13 |
14 | Any idea for the new feature? Please file an issue and tell me more.
15 |
16 | ## Usage
17 | Clone & Run project with Xcode 8
18 |
19 | ## Enjoy
20 | If you have any questions or feedbacks, feel free to file the issues or ping me on Twitter by @wangshengjia.
21 |
22 |
23 |
--------------------------------------------------------------------------------
/XcodeEditorPlus.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 3534EED91D27B73E00CFF7BA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3534EED81D27B73E00CFF7BA /* AppDelegate.swift */; };
11 | 3534EEDB1D27B73E00CFF7BA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3534EEDA1D27B73E00CFF7BA /* Assets.xcassets */; };
12 | 3534EEDE1D27B73E00CFF7BA /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3534EEDC1D27B73E00CFF7BA /* MainMenu.xib */; };
13 | 3534EEEC1D27B7C600CFF7BA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3534EEEB1D27B7C600CFF7BA /* Cocoa.framework */; };
14 | 3534EEF11D27B7C600CFF7BA /* SourceEditorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3534EEF01D27B7C600CFF7BA /* SourceEditorExtension.swift */; };
15 | 3534EEF31D27B7C600CFF7BA /* SourceEditorCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3534EEF21D27B7C600CFF7BA /* SourceEditorCommand.swift */; };
16 | 3534EEF71D27B7C600CFF7BA /* EditorPlusExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 3534EEE91D27B7C600CFF7BA /* EditorPlusExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXContainerItemProxy section */
20 | 3534EEF51D27B7C600CFF7BA /* PBXContainerItemProxy */ = {
21 | isa = PBXContainerItemProxy;
22 | containerPortal = 3534EECD1D27B73E00CFF7BA /* Project object */;
23 | proxyType = 1;
24 | remoteGlobalIDString = 3534EEE81D27B7C600CFF7BA;
25 | remoteInfo = EditorPlusExtension;
26 | };
27 | /* End PBXContainerItemProxy section */
28 |
29 | /* Begin PBXCopyFilesBuildPhase section */
30 | 3534EEFB1D27B7C600CFF7BA /* Embed App Extensions */ = {
31 | isa = PBXCopyFilesBuildPhase;
32 | buildActionMask = 2147483647;
33 | dstPath = "";
34 | dstSubfolderSpec = 13;
35 | files = (
36 | 3534EEF71D27B7C600CFF7BA /* EditorPlusExtension.appex in Embed App Extensions */,
37 | );
38 | name = "Embed App Extensions";
39 | runOnlyForDeploymentPostprocessing = 0;
40 | };
41 | /* End PBXCopyFilesBuildPhase section */
42 |
43 | /* Begin PBXFileReference section */
44 | 3534EED51D27B73E00CFF7BA /* XcodeEditorPlus.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XcodeEditorPlus.app; sourceTree = BUILT_PRODUCTS_DIR; };
45 | 3534EED81D27B73E00CFF7BA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
46 | 3534EEDA1D27B73E00CFF7BA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
47 | 3534EEDD1D27B73E00CFF7BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
48 | 3534EEDF1D27B73E00CFF7BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
49 | 3534EEE91D27B7C600CFF7BA /* EditorPlusExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = EditorPlusExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
50 | 3534EEEB1D27B7C600CFF7BA /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
51 | 3534EEEF1D27B7C600CFF7BA /* EditorPlusExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = EditorPlusExtension.entitlements; sourceTree = ""; };
52 | 3534EEF01D27B7C600CFF7BA /* SourceEditorExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceEditorExtension.swift; sourceTree = ""; };
53 | 3534EEF21D27B7C600CFF7BA /* SourceEditorCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceEditorCommand.swift; sourceTree = ""; };
54 | 3534EEF41D27B7C600CFF7BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
55 | /* End PBXFileReference section */
56 |
57 | /* Begin PBXFrameworksBuildPhase section */
58 | 3534EED21D27B73E00CFF7BA /* Frameworks */ = {
59 | isa = PBXFrameworksBuildPhase;
60 | buildActionMask = 2147483647;
61 | files = (
62 | );
63 | runOnlyForDeploymentPostprocessing = 0;
64 | };
65 | 3534EEE61D27B7C600CFF7BA /* Frameworks */ = {
66 | isa = PBXFrameworksBuildPhase;
67 | buildActionMask = 2147483647;
68 | files = (
69 | 3534EEEC1D27B7C600CFF7BA /* Cocoa.framework in Frameworks */,
70 | );
71 | runOnlyForDeploymentPostprocessing = 0;
72 | };
73 | /* End PBXFrameworksBuildPhase section */
74 |
75 | /* Begin PBXGroup section */
76 | 3534EECC1D27B73E00CFF7BA = {
77 | isa = PBXGroup;
78 | children = (
79 | 3534EED71D27B73E00CFF7BA /* XcodeEditorPlus */,
80 | 3534EEED1D27B7C600CFF7BA /* EditorPlusExtension */,
81 | 3534EEEA1D27B7C600CFF7BA /* Frameworks */,
82 | 3534EED61D27B73E00CFF7BA /* Products */,
83 | );
84 | sourceTree = "";
85 | };
86 | 3534EED61D27B73E00CFF7BA /* Products */ = {
87 | isa = PBXGroup;
88 | children = (
89 | 3534EED51D27B73E00CFF7BA /* XcodeEditorPlus.app */,
90 | 3534EEE91D27B7C600CFF7BA /* EditorPlusExtension.appex */,
91 | );
92 | name = Products;
93 | sourceTree = "";
94 | };
95 | 3534EED71D27B73E00CFF7BA /* XcodeEditorPlus */ = {
96 | isa = PBXGroup;
97 | children = (
98 | 3534EED81D27B73E00CFF7BA /* AppDelegate.swift */,
99 | 3534EEDA1D27B73E00CFF7BA /* Assets.xcassets */,
100 | 3534EEDC1D27B73E00CFF7BA /* MainMenu.xib */,
101 | 3534EEDF1D27B73E00CFF7BA /* Info.plist */,
102 | );
103 | path = XcodeEditorPlus;
104 | sourceTree = "";
105 | };
106 | 3534EEEA1D27B7C600CFF7BA /* Frameworks */ = {
107 | isa = PBXGroup;
108 | children = (
109 | 3534EEEB1D27B7C600CFF7BA /* Cocoa.framework */,
110 | );
111 | name = Frameworks;
112 | sourceTree = "";
113 | };
114 | 3534EEED1D27B7C600CFF7BA /* EditorPlusExtension */ = {
115 | isa = PBXGroup;
116 | children = (
117 | 3534EEF01D27B7C600CFF7BA /* SourceEditorExtension.swift */,
118 | 3534EEF21D27B7C600CFF7BA /* SourceEditorCommand.swift */,
119 | 3534EEF41D27B7C600CFF7BA /* Info.plist */,
120 | 3534EEEE1D27B7C600CFF7BA /* Supporting Files */,
121 | );
122 | path = EditorPlusExtension;
123 | sourceTree = "";
124 | };
125 | 3534EEEE1D27B7C600CFF7BA /* Supporting Files */ = {
126 | isa = PBXGroup;
127 | children = (
128 | 3534EEEF1D27B7C600CFF7BA /* EditorPlusExtension.entitlements */,
129 | );
130 | name = "Supporting Files";
131 | sourceTree = "";
132 | };
133 | /* End PBXGroup section */
134 |
135 | /* Begin PBXNativeTarget section */
136 | 3534EED41D27B73E00CFF7BA /* XcodeEditorPlus */ = {
137 | isa = PBXNativeTarget;
138 | buildConfigurationList = 3534EEE21D27B73E00CFF7BA /* Build configuration list for PBXNativeTarget "XcodeEditorPlus" */;
139 | buildPhases = (
140 | 3534EED11D27B73E00CFF7BA /* Sources */,
141 | 3534EED21D27B73E00CFF7BA /* Frameworks */,
142 | 3534EED31D27B73E00CFF7BA /* Resources */,
143 | 3534EEFB1D27B7C600CFF7BA /* Embed App Extensions */,
144 | );
145 | buildRules = (
146 | );
147 | dependencies = (
148 | 3534EEF61D27B7C600CFF7BA /* PBXTargetDependency */,
149 | );
150 | name = XcodeEditorPlus;
151 | productName = XcodeEditorPlus;
152 | productReference = 3534EED51D27B73E00CFF7BA /* XcodeEditorPlus.app */;
153 | productType = "com.apple.product-type.application";
154 | };
155 | 3534EEE81D27B7C600CFF7BA /* EditorPlusExtension */ = {
156 | isa = PBXNativeTarget;
157 | buildConfigurationList = 3534EEFA1D27B7C600CFF7BA /* Build configuration list for PBXNativeTarget "EditorPlusExtension" */;
158 | buildPhases = (
159 | 3534EEE51D27B7C600CFF7BA /* Sources */,
160 | 3534EEE61D27B7C600CFF7BA /* Frameworks */,
161 | 3534EEE71D27B7C600CFF7BA /* Resources */,
162 | );
163 | buildRules = (
164 | );
165 | dependencies = (
166 | );
167 | name = EditorPlusExtension;
168 | productName = EditorPlusExtension;
169 | productReference = 3534EEE91D27B7C600CFF7BA /* EditorPlusExtension.appex */;
170 | productType = "com.apple.product-type.xcode-extension";
171 | };
172 | /* End PBXNativeTarget section */
173 |
174 | /* Begin PBXProject section */
175 | 3534EECD1D27B73E00CFF7BA /* Project object */ = {
176 | isa = PBXProject;
177 | attributes = {
178 | LastSwiftUpdateCheck = 0800;
179 | LastUpgradeCheck = 0800;
180 | ORGANIZATIONNAME = "Victor Wang";
181 | TargetAttributes = {
182 | 3534EED41D27B73E00CFF7BA = {
183 | CreatedOnToolsVersion = 8.0;
184 | DevelopmentTeam = MH3P7R7924;
185 | DevelopmentTeamName = "ShengJia WANG (Personal Team)";
186 | ProvisioningStyle = Automatic;
187 | };
188 | 3534EEE81D27B7C600CFF7BA = {
189 | CreatedOnToolsVersion = 8.0;
190 | DevelopmentTeam = MH3P7R7924;
191 | DevelopmentTeamName = "ShengJia WANG (Personal Team)";
192 | ProvisioningStyle = Automatic;
193 | };
194 | };
195 | };
196 | buildConfigurationList = 3534EED01D27B73E00CFF7BA /* Build configuration list for PBXProject "XcodeEditorPlus" */;
197 | compatibilityVersion = "Xcode 3.2";
198 | developmentRegion = English;
199 | hasScannedForEncodings = 0;
200 | knownRegions = (
201 | en,
202 | Base,
203 | );
204 | mainGroup = 3534EECC1D27B73E00CFF7BA;
205 | productRefGroup = 3534EED61D27B73E00CFF7BA /* Products */;
206 | projectDirPath = "";
207 | projectRoot = "";
208 | targets = (
209 | 3534EED41D27B73E00CFF7BA /* XcodeEditorPlus */,
210 | 3534EEE81D27B7C600CFF7BA /* EditorPlusExtension */,
211 | );
212 | };
213 | /* End PBXProject section */
214 |
215 | /* Begin PBXResourcesBuildPhase section */
216 | 3534EED31D27B73E00CFF7BA /* Resources */ = {
217 | isa = PBXResourcesBuildPhase;
218 | buildActionMask = 2147483647;
219 | files = (
220 | 3534EEDB1D27B73E00CFF7BA /* Assets.xcassets in Resources */,
221 | 3534EEDE1D27B73E00CFF7BA /* MainMenu.xib in Resources */,
222 | );
223 | runOnlyForDeploymentPostprocessing = 0;
224 | };
225 | 3534EEE71D27B7C600CFF7BA /* Resources */ = {
226 | isa = PBXResourcesBuildPhase;
227 | buildActionMask = 2147483647;
228 | files = (
229 | );
230 | runOnlyForDeploymentPostprocessing = 0;
231 | };
232 | /* End PBXResourcesBuildPhase section */
233 |
234 | /* Begin PBXSourcesBuildPhase section */
235 | 3534EED11D27B73E00CFF7BA /* Sources */ = {
236 | isa = PBXSourcesBuildPhase;
237 | buildActionMask = 2147483647;
238 | files = (
239 | 3534EED91D27B73E00CFF7BA /* AppDelegate.swift in Sources */,
240 | );
241 | runOnlyForDeploymentPostprocessing = 0;
242 | };
243 | 3534EEE51D27B7C600CFF7BA /* Sources */ = {
244 | isa = PBXSourcesBuildPhase;
245 | buildActionMask = 2147483647;
246 | files = (
247 | 3534EEF11D27B7C600CFF7BA /* SourceEditorExtension.swift in Sources */,
248 | 3534EEF31D27B7C600CFF7BA /* SourceEditorCommand.swift in Sources */,
249 | );
250 | runOnlyForDeploymentPostprocessing = 0;
251 | };
252 | /* End PBXSourcesBuildPhase section */
253 |
254 | /* Begin PBXTargetDependency section */
255 | 3534EEF61D27B7C600CFF7BA /* PBXTargetDependency */ = {
256 | isa = PBXTargetDependency;
257 | target = 3534EEE81D27B7C600CFF7BA /* EditorPlusExtension */;
258 | targetProxy = 3534EEF51D27B7C600CFF7BA /* PBXContainerItemProxy */;
259 | };
260 | /* End PBXTargetDependency section */
261 |
262 | /* Begin PBXVariantGroup section */
263 | 3534EEDC1D27B73E00CFF7BA /* MainMenu.xib */ = {
264 | isa = PBXVariantGroup;
265 | children = (
266 | 3534EEDD1D27B73E00CFF7BA /* Base */,
267 | );
268 | name = MainMenu.xib;
269 | sourceTree = "";
270 | };
271 | /* End PBXVariantGroup section */
272 |
273 | /* Begin XCBuildConfiguration section */
274 | 3534EEE01D27B73E00CFF7BA /* Debug */ = {
275 | isa = XCBuildConfiguration;
276 | buildSettings = {
277 | ALWAYS_SEARCH_USER_PATHS = NO;
278 | CLANG_ANALYZER_NONNULL = YES;
279 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
280 | CLANG_CXX_LIBRARY = "libc++";
281 | CLANG_ENABLE_MODULES = YES;
282 | CLANG_ENABLE_OBJC_ARC = YES;
283 | CLANG_WARN_BOOL_CONVERSION = YES;
284 | CLANG_WARN_CONSTANT_CONVERSION = YES;
285 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
286 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
287 | CLANG_WARN_EMPTY_BODY = YES;
288 | CLANG_WARN_ENUM_CONVERSION = YES;
289 | CLANG_WARN_INT_CONVERSION = YES;
290 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
291 | CLANG_WARN_UNREACHABLE_CODE = YES;
292 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
293 | CODE_SIGN_IDENTITY = "-";
294 | COPY_PHASE_STRIP = NO;
295 | DEBUG_INFORMATION_FORMAT = dwarf;
296 | ENABLE_STRICT_OBJC_MSGSEND = YES;
297 | ENABLE_TESTABILITY = YES;
298 | GCC_C_LANGUAGE_STANDARD = gnu99;
299 | GCC_DYNAMIC_NO_PIC = NO;
300 | GCC_NO_COMMON_BLOCKS = YES;
301 | GCC_OPTIMIZATION_LEVEL = 0;
302 | GCC_PREPROCESSOR_DEFINITIONS = (
303 | "DEBUG=1",
304 | "$(inherited)",
305 | );
306 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
307 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
308 | GCC_WARN_UNDECLARED_SELECTOR = YES;
309 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
310 | GCC_WARN_UNUSED_FUNCTION = YES;
311 | GCC_WARN_UNUSED_VARIABLE = YES;
312 | MACOSX_DEPLOYMENT_TARGET = 10.12;
313 | MTL_ENABLE_DEBUG_INFO = YES;
314 | ONLY_ACTIVE_ARCH = YES;
315 | SDKROOT = macosx;
316 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
317 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
318 | };
319 | name = Debug;
320 | };
321 | 3534EEE11D27B73E00CFF7BA /* Release */ = {
322 | isa = XCBuildConfiguration;
323 | buildSettings = {
324 | ALWAYS_SEARCH_USER_PATHS = NO;
325 | CLANG_ANALYZER_NONNULL = YES;
326 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
327 | CLANG_CXX_LIBRARY = "libc++";
328 | CLANG_ENABLE_MODULES = YES;
329 | CLANG_ENABLE_OBJC_ARC = YES;
330 | CLANG_WARN_BOOL_CONVERSION = YES;
331 | CLANG_WARN_CONSTANT_CONVERSION = YES;
332 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
333 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
334 | CLANG_WARN_EMPTY_BODY = YES;
335 | CLANG_WARN_ENUM_CONVERSION = YES;
336 | CLANG_WARN_INT_CONVERSION = YES;
337 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
338 | CLANG_WARN_UNREACHABLE_CODE = YES;
339 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
340 | CODE_SIGN_IDENTITY = "-";
341 | COPY_PHASE_STRIP = NO;
342 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
343 | ENABLE_NS_ASSERTIONS = NO;
344 | ENABLE_STRICT_OBJC_MSGSEND = YES;
345 | GCC_C_LANGUAGE_STANDARD = gnu99;
346 | GCC_NO_COMMON_BLOCKS = YES;
347 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
348 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
349 | GCC_WARN_UNDECLARED_SELECTOR = YES;
350 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
351 | GCC_WARN_UNUSED_FUNCTION = YES;
352 | GCC_WARN_UNUSED_VARIABLE = YES;
353 | MACOSX_DEPLOYMENT_TARGET = 10.12;
354 | MTL_ENABLE_DEBUG_INFO = NO;
355 | SDKROOT = macosx;
356 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
357 | };
358 | name = Release;
359 | };
360 | 3534EEE31D27B73E00CFF7BA /* Debug */ = {
361 | isa = XCBuildConfiguration;
362 | buildSettings = {
363 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
364 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
365 | COMBINE_HIDPI_IMAGES = YES;
366 | INFOPLIST_FILE = XcodeEditorPlus/Info.plist;
367 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
368 | PRODUCT_BUNDLE_IDENTIFIER = me.allblue.XcodeEditorPlus;
369 | PRODUCT_NAME = "$(TARGET_NAME)";
370 | SWIFT_VERSION = 3.0;
371 | };
372 | name = Debug;
373 | };
374 | 3534EEE41D27B73E00CFF7BA /* Release */ = {
375 | isa = XCBuildConfiguration;
376 | buildSettings = {
377 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
378 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
379 | COMBINE_HIDPI_IMAGES = YES;
380 | INFOPLIST_FILE = XcodeEditorPlus/Info.plist;
381 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
382 | PRODUCT_BUNDLE_IDENTIFIER = me.allblue.XcodeEditorPlus;
383 | PRODUCT_NAME = "$(TARGET_NAME)";
384 | SWIFT_VERSION = 3.0;
385 | };
386 | name = Release;
387 | };
388 | 3534EEF81D27B7C600CFF7BA /* Debug */ = {
389 | isa = XCBuildConfiguration;
390 | buildSettings = {
391 | CODE_SIGN_ENTITLEMENTS = EditorPlusExtension/EditorPlusExtension.entitlements;
392 | COMBINE_HIDPI_IMAGES = YES;
393 | INFOPLIST_FILE = EditorPlusExtension/Info.plist;
394 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks";
395 | MACOSX_DEPLOYMENT_TARGET = 10.11;
396 | PRODUCT_BUNDLE_IDENTIFIER = me.allblue.XcodeEditorPlus.EditorPlusExtension;
397 | PRODUCT_NAME = "$(TARGET_NAME)";
398 | SKIP_INSTALL = YES;
399 | SWIFT_VERSION = 3.0;
400 | };
401 | name = Debug;
402 | };
403 | 3534EEF91D27B7C600CFF7BA /* Release */ = {
404 | isa = XCBuildConfiguration;
405 | buildSettings = {
406 | CODE_SIGN_ENTITLEMENTS = EditorPlusExtension/EditorPlusExtension.entitlements;
407 | COMBINE_HIDPI_IMAGES = YES;
408 | INFOPLIST_FILE = EditorPlusExtension/Info.plist;
409 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks";
410 | MACOSX_DEPLOYMENT_TARGET = 10.11;
411 | PRODUCT_BUNDLE_IDENTIFIER = me.allblue.XcodeEditorPlus.EditorPlusExtension;
412 | PRODUCT_NAME = "$(TARGET_NAME)";
413 | SKIP_INSTALL = YES;
414 | SWIFT_VERSION = 3.0;
415 | };
416 | name = Release;
417 | };
418 | /* End XCBuildConfiguration section */
419 |
420 | /* Begin XCConfigurationList section */
421 | 3534EED01D27B73E00CFF7BA /* Build configuration list for PBXProject "XcodeEditorPlus" */ = {
422 | isa = XCConfigurationList;
423 | buildConfigurations = (
424 | 3534EEE01D27B73E00CFF7BA /* Debug */,
425 | 3534EEE11D27B73E00CFF7BA /* Release */,
426 | );
427 | defaultConfigurationIsVisible = 0;
428 | defaultConfigurationName = Release;
429 | };
430 | 3534EEE21D27B73E00CFF7BA /* Build configuration list for PBXNativeTarget "XcodeEditorPlus" */ = {
431 | isa = XCConfigurationList;
432 | buildConfigurations = (
433 | 3534EEE31D27B73E00CFF7BA /* Debug */,
434 | 3534EEE41D27B73E00CFF7BA /* Release */,
435 | );
436 | defaultConfigurationIsVisible = 0;
437 | defaultConfigurationName = Release;
438 | };
439 | 3534EEFA1D27B7C600CFF7BA /* Build configuration list for PBXNativeTarget "EditorPlusExtension" */ = {
440 | isa = XCConfigurationList;
441 | buildConfigurations = (
442 | 3534EEF81D27B7C600CFF7BA /* Debug */,
443 | 3534EEF91D27B7C600CFF7BA /* Release */,
444 | );
445 | defaultConfigurationIsVisible = 0;
446 | };
447 | /* End XCConfigurationList section */
448 | };
449 | rootObject = 3534EECD1D27B73E00CFF7BA /* Project object */;
450 | }
451 |
--------------------------------------------------------------------------------
/XcodeEditorPlus.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/XcodeEditorPlus/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // XcodeEditorPlus
4 | //
5 | // Created by Victor WANG on 02/07/2016.
6 | // Copyright © 2016 Victor Wang. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | @NSApplicationMain
12 | class AppDelegate: NSObject, NSApplicationDelegate {
13 |
14 | @IBOutlet weak var window: NSWindow!
15 |
16 |
17 | func applicationDidFinishLaunching(_ aNotification: Notification) {
18 | // Insert code here to initialize your application
19 | }
20 |
21 | func applicationWillTerminate(_ aNotification: Notification) {
22 | // Insert code here to tear down your application
23 | }
24 |
25 |
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/XcodeEditorPlus/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/XcodeEditorPlus/Base.lproj/MainMenu.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
--------------------------------------------------------------------------------
/XcodeEditorPlus/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSMinimumSystemVersion
26 | $(MACOSX_DEPLOYMENT_TARGET)
27 | NSHumanReadableCopyright
28 | Copyright © 2016 Victor Wang. All rights reserved.
29 | NSMainNibFile
30 | MainMenu
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------