├── .gitignore
├── Assets
├── App.png
├── Banner.png
├── Multiliner-1.0.mp4
├── Multiliner-1.1.mp4
├── Preferences.png
├── Social Preview.jpg
├── UsageCode.png
├── UsageMenu.png
├── UsageResult.png
└── UsageShortcut.png
├── LICENSE
├── Multiliner.zip
├── README.md
└── Sources
├── Multiliner.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── xcshareddata
│ └── xcschemes
│ │ ├── Multiliner.xcscheme
│ │ └── MultilinerExtension.xcscheme
└── xcuserdata
│ └── aheze.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ └── xcschememanagement.plist
├── Multiliner
├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ ├── AppIcon-1024.png
│ │ ├── AppIcon-128.png
│ │ ├── AppIcon-16.png
│ │ ├── AppIcon-256.png
│ │ ├── AppIcon-32.png
│ │ ├── AppIcon-512.png
│ │ ├── AppIcon-64.png
│ │ └── Contents.json
│ ├── Banner.imageset
│ │ ├── Banner.png
│ │ └── Contents.json
│ ├── Contents.json
│ ├── Preferences.imageset
│ │ ├── Contents.json
│ │ └── Preferences.png
│ ├── UsageCode.imageset
│ │ ├── Contents.json
│ │ └── UsageCode.png
│ ├── UsageMenu.imageset
│ │ ├── Contents.json
│ │ └── UsageMenu.png
│ ├── UsageResult.imageset
│ │ ├── Contents.json
│ │ └── UsageResult.png
│ └── UsageShortcut.imageset
│ │ ├── Contents.json
│ │ └── UsageShortcut.png
├── ContentView.swift
├── Multiliner.entitlements
└── MultilinerApp.swift
└── MultilinerExtension
├── Extensions.swift
├── FormatError.swift
├── FormatSelectedCodeCommand.swift
├── Info.plist
├── MultilinerExtension.entitlements
├── SelectionKind.swift
└── SourceEditorExtension.swift
/.gitignore:
--------------------------------------------------------------------------------
1 | # macOS
2 | .DS_Store
3 |
4 | ## Xcode-related
5 | xcuserdata/
6 | .build/
7 | build/
8 | DerivedData/
--------------------------------------------------------------------------------
/Assets/App.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Assets/App.png
--------------------------------------------------------------------------------
/Assets/Banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Assets/Banner.png
--------------------------------------------------------------------------------
/Assets/Multiliner-1.0.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Assets/Multiliner-1.0.mp4
--------------------------------------------------------------------------------
/Assets/Multiliner-1.1.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Assets/Multiliner-1.1.mp4
--------------------------------------------------------------------------------
/Assets/Preferences.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Assets/Preferences.png
--------------------------------------------------------------------------------
/Assets/Social Preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Assets/Social Preview.jpg
--------------------------------------------------------------------------------
/Assets/UsageCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Assets/UsageCode.png
--------------------------------------------------------------------------------
/Assets/UsageMenu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Assets/UsageMenu.png
--------------------------------------------------------------------------------
/Assets/UsageResult.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Assets/UsageResult.png
--------------------------------------------------------------------------------
/Assets/UsageShortcut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Assets/UsageShortcut.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 A. Zheng
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 |
--------------------------------------------------------------------------------
/Multiliner.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Multiliner.zip
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Multiliner
4 |
5 | An Xcode source extension to expand lengthy lines.
6 |
7 | - Super lightweight, it's like a script.
8 | - It expands long lines. That's it!
9 | - Works with:
10 | - Initializers
11 | - Function calls
12 | - Array literals
13 | - SwiftUI modifiers
14 |
15 | ### Showcase
16 |
17 | https://user-images.githubusercontent.com/49819455/176060861-4bab03cc-a953-4839-b04e-cf05864f879e.mp4
18 |
19 | ### Installation
20 |
21 | 1. Download the app [directly](https://github.com/aheze/Multiliner/raw/main/Multiliner.zip) or through Homebrew
22 |
23 | ```bash
24 | brew install hkamran80/things/multiliner
25 | ```
26 |
27 | **Note:** Multiliner requires macOS Monterey (12.3) or higher.
28 |
29 | 2. Open the app
30 | 3. Go to System Preferences → Extensions and check `Multiliner`
31 |
32 |
33 |
34 | ### Usage
35 |
36 | It's simple, just highlight the code that you want to format, then press Editor → Multiliner → Format Selected Code. More details in the app.
37 |
38 |
39 |
40 | ### Shortcut
41 |
42 | If you'd like to access Multiliner quicker, try adding a key binding. Go to Xcode → Preferences → Key Bindings, then search for "Multiliner":
43 |
44 |
45 |
46 |
47 | ### Author
48 |
49 | Multiliner is made by [aheze](https://github.com/aheze).
50 |
51 | ### Contributing
52 |
53 | All contributions are welcome. Just [fork](https://github.com/aheze/Multiliner/fork) the repo, then make a pull request.
54 |
55 | ### Need Help?
56 |
57 | Open an [issue](https://github.com/aheze/Multiliner/issues) or join the [Discord server](https://discord.com/invite/Pmq8fYcus2). You can also ping me on [Twitter](https://twitter.com/aheze0). Or read the source code, I added a bunch of comments.
58 |
59 | ### License
60 |
61 | ```text
62 | MIT License
63 |
64 | Copyright (c) 2022 A. Zheng
65 |
66 | Permission is hereby granted, free of charge, to any person obtaining a copy
67 | of this software and associated documentation files (the "Software"), to deal
68 | in the Software without restriction, including without limitation the rights
69 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
70 | copies of the Software, and to permit persons to whom the Software is
71 | furnished to do so, subject to the following conditions:
72 |
73 | The above copyright notice and this permission notice shall be included in all
74 | copies or substantial portions of the Software.
75 |
76 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
77 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
78 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
79 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
80 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
81 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
82 | SOFTWARE.
83 | ```
84 |
--------------------------------------------------------------------------------
/Sources/Multiliner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 55;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 3C08D42E286A3F160068FA83 /* MultilinerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C08D42D286A3F160068FA83 /* MultilinerApp.swift */; };
11 | 3C08D430286A3F160068FA83 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C08D42F286A3F160068FA83 /* ContentView.swift */; };
12 | 3C08D432286A3F190068FA83 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3C08D431286A3F190068FA83 /* Assets.xcassets */; };
13 | 3C08D443286A3F3D0068FA83 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C08D442286A3F3D0068FA83 /* Cocoa.framework */; };
14 | 3C08D448286A3F3D0068FA83 /* SourceEditorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C08D447286A3F3D0068FA83 /* SourceEditorExtension.swift */; };
15 | 3C08D44A286A3F3D0068FA83 /* FormatSelectedCodeCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C08D449286A3F3D0068FA83 /* FormatSelectedCodeCommand.swift */; };
16 | 3C08D44F286A3F3D0068FA83 /* Multiliner.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 3C08D440286A3F3D0068FA83 /* Multiliner.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
17 | 3C3D5B63286A40E900B92FEA /* XcodeKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C08D444286A3F3D0068FA83 /* XcodeKit.framework */; };
18 | 3C3D5B64286A40E900B92FEA /* XcodeKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3C08D444286A3F3D0068FA83 /* XcodeKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
19 | 3CFEC80428753F6C0069D8C6 /* FormatError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CFEC80328753F6C0069D8C6 /* FormatError.swift */; };
20 | 3CFEC80628753F7B0069D8C6 /* SelectionKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CFEC80528753F7B0069D8C6 /* SelectionKind.swift */; };
21 | 3CFEC80A287540390069D8C6 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CFEC809287540390069D8C6 /* Extensions.swift */; };
22 | /* End PBXBuildFile section */
23 |
24 | /* Begin PBXContainerItemProxy section */
25 | 3C08D44D286A3F3D0068FA83 /* PBXContainerItemProxy */ = {
26 | isa = PBXContainerItemProxy;
27 | containerPortal = 3C08D422286A3F160068FA83 /* Project object */;
28 | proxyType = 1;
29 | remoteGlobalIDString = 3C08D43F286A3F3D0068FA83;
30 | remoteInfo = MultilinerExtension;
31 | };
32 | /* End PBXContainerItemProxy section */
33 |
34 | /* Begin PBXCopyFilesBuildPhase section */
35 | 3C08D453286A3F3D0068FA83 /* Embed App Extensions */ = {
36 | isa = PBXCopyFilesBuildPhase;
37 | buildActionMask = 2147483647;
38 | dstPath = "";
39 | dstSubfolderSpec = 13;
40 | files = (
41 | 3C08D44F286A3F3D0068FA83 /* Multiliner.appex in Embed App Extensions */,
42 | );
43 | name = "Embed App Extensions";
44 | runOnlyForDeploymentPostprocessing = 0;
45 | };
46 | 3C3D5B65286A40E900B92FEA /* Embed Frameworks */ = {
47 | isa = PBXCopyFilesBuildPhase;
48 | buildActionMask = 2147483647;
49 | dstPath = "";
50 | dstSubfolderSpec = 10;
51 | files = (
52 | 3C3D5B64286A40E900B92FEA /* XcodeKit.framework in Embed Frameworks */,
53 | );
54 | name = "Embed Frameworks";
55 | runOnlyForDeploymentPostprocessing = 0;
56 | };
57 | /* End PBXCopyFilesBuildPhase section */
58 |
59 | /* Begin PBXFileReference section */
60 | 3C08D42A286A3F160068FA83 /* Multiliner App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Multiliner App.app"; sourceTree = BUILT_PRODUCTS_DIR; };
61 | 3C08D42D286A3F160068FA83 /* MultilinerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultilinerApp.swift; sourceTree = ""; };
62 | 3C08D42F286A3F160068FA83 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
63 | 3C08D431286A3F190068FA83 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
64 | 3C08D436286A3F190068FA83 /* Multiliner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Multiliner.entitlements; sourceTree = ""; };
65 | 3C08D440286A3F3D0068FA83 /* Multiliner.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Multiliner.appex; sourceTree = BUILT_PRODUCTS_DIR; };
66 | 3C08D442286A3F3D0068FA83 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
67 | 3C08D444286A3F3D0068FA83 /* XcodeKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XcodeKit.framework; path = Library/Frameworks/XcodeKit.framework; sourceTree = DEVELOPER_DIR; };
68 | 3C08D447286A3F3D0068FA83 /* SourceEditorExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceEditorExtension.swift; sourceTree = ""; };
69 | 3C08D449286A3F3D0068FA83 /* FormatSelectedCodeCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormatSelectedCodeCommand.swift; sourceTree = ""; };
70 | 3C08D44B286A3F3D0068FA83 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
71 | 3C08D44C286A3F3D0068FA83 /* MultilinerExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MultilinerExtension.entitlements; sourceTree = ""; };
72 | 3CFEC80328753F6C0069D8C6 /* FormatError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormatError.swift; sourceTree = ""; };
73 | 3CFEC80528753F7B0069D8C6 /* SelectionKind.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectionKind.swift; sourceTree = ""; };
74 | 3CFEC809287540390069D8C6 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; };
75 | /* End PBXFileReference section */
76 |
77 | /* Begin PBXFrameworksBuildPhase section */
78 | 3C08D427286A3F160068FA83 /* Frameworks */ = {
79 | isa = PBXFrameworksBuildPhase;
80 | buildActionMask = 2147483647;
81 | files = (
82 | );
83 | runOnlyForDeploymentPostprocessing = 0;
84 | };
85 | 3C08D43D286A3F3D0068FA83 /* Frameworks */ = {
86 | isa = PBXFrameworksBuildPhase;
87 | buildActionMask = 2147483647;
88 | files = (
89 | 3C08D443286A3F3D0068FA83 /* Cocoa.framework in Frameworks */,
90 | 3C3D5B63286A40E900B92FEA /* XcodeKit.framework in Frameworks */,
91 | );
92 | runOnlyForDeploymentPostprocessing = 0;
93 | };
94 | /* End PBXFrameworksBuildPhase section */
95 |
96 | /* Begin PBXGroup section */
97 | 3C08D421286A3F160068FA83 = {
98 | isa = PBXGroup;
99 | children = (
100 | 3C08D42C286A3F160068FA83 /* Multiliner */,
101 | 3C08D446286A3F3D0068FA83 /* MultilinerExtension */,
102 | 3C08D441286A3F3D0068FA83 /* Frameworks */,
103 | 3C08D42B286A3F160068FA83 /* Products */,
104 | );
105 | sourceTree = "";
106 | };
107 | 3C08D42B286A3F160068FA83 /* Products */ = {
108 | isa = PBXGroup;
109 | children = (
110 | 3C08D42A286A3F160068FA83 /* Multiliner App.app */,
111 | 3C08D440286A3F3D0068FA83 /* Multiliner.appex */,
112 | );
113 | name = Products;
114 | sourceTree = "";
115 | };
116 | 3C08D42C286A3F160068FA83 /* Multiliner */ = {
117 | isa = PBXGroup;
118 | children = (
119 | 3C08D42D286A3F160068FA83 /* MultilinerApp.swift */,
120 | 3C08D42F286A3F160068FA83 /* ContentView.swift */,
121 | 3C08D431286A3F190068FA83 /* Assets.xcassets */,
122 | 3C08D436286A3F190068FA83 /* Multiliner.entitlements */,
123 | );
124 | path = Multiliner;
125 | sourceTree = "";
126 | };
127 | 3C08D441286A3F3D0068FA83 /* Frameworks */ = {
128 | isa = PBXGroup;
129 | children = (
130 | 3C08D442286A3F3D0068FA83 /* Cocoa.framework */,
131 | 3C08D444286A3F3D0068FA83 /* XcodeKit.framework */,
132 | );
133 | name = Frameworks;
134 | sourceTree = "";
135 | };
136 | 3C08D446286A3F3D0068FA83 /* MultilinerExtension */ = {
137 | isa = PBXGroup;
138 | children = (
139 | 3CFEC80328753F6C0069D8C6 /* FormatError.swift */,
140 | 3CFEC80528753F7B0069D8C6 /* SelectionKind.swift */,
141 | 3CFEC809287540390069D8C6 /* Extensions.swift */,
142 | 3C08D447286A3F3D0068FA83 /* SourceEditorExtension.swift */,
143 | 3C08D449286A3F3D0068FA83 /* FormatSelectedCodeCommand.swift */,
144 | 3C08D44B286A3F3D0068FA83 /* Info.plist */,
145 | 3C08D44C286A3F3D0068FA83 /* MultilinerExtension.entitlements */,
146 | );
147 | path = MultilinerExtension;
148 | sourceTree = "";
149 | };
150 | /* End PBXGroup section */
151 |
152 | /* Begin PBXNativeTarget section */
153 | 3C08D429286A3F160068FA83 /* Multiliner */ = {
154 | isa = PBXNativeTarget;
155 | buildConfigurationList = 3C08D439286A3F190068FA83 /* Build configuration list for PBXNativeTarget "Multiliner" */;
156 | buildPhases = (
157 | 3C08D426286A3F160068FA83 /* Sources */,
158 | 3C08D427286A3F160068FA83 /* Frameworks */,
159 | 3C08D428286A3F160068FA83 /* Resources */,
160 | 3C08D453286A3F3D0068FA83 /* Embed App Extensions */,
161 | );
162 | buildRules = (
163 | );
164 | dependencies = (
165 | 3C08D44E286A3F3D0068FA83 /* PBXTargetDependency */,
166 | );
167 | name = Multiliner;
168 | productName = Multiliner;
169 | productReference = 3C08D42A286A3F160068FA83 /* Multiliner App.app */;
170 | productType = "com.apple.product-type.application";
171 | };
172 | 3C08D43F286A3F3D0068FA83 /* MultilinerExtension */ = {
173 | isa = PBXNativeTarget;
174 | buildConfigurationList = 3C08D450286A3F3D0068FA83 /* Build configuration list for PBXNativeTarget "MultilinerExtension" */;
175 | buildPhases = (
176 | 3C08D43C286A3F3D0068FA83 /* Sources */,
177 | 3C08D43D286A3F3D0068FA83 /* Frameworks */,
178 | 3C08D43E286A3F3D0068FA83 /* Resources */,
179 | 3C3D5B65286A40E900B92FEA /* Embed Frameworks */,
180 | );
181 | buildRules = (
182 | );
183 | dependencies = (
184 | );
185 | name = MultilinerExtension;
186 | productName = MultilinerExtension;
187 | productReference = 3C08D440286A3F3D0068FA83 /* Multiliner.appex */;
188 | productType = "com.apple.product-type.xcode-extension";
189 | };
190 | /* End PBXNativeTarget section */
191 |
192 | /* Begin PBXProject section */
193 | 3C08D422286A3F160068FA83 /* Project object */ = {
194 | isa = PBXProject;
195 | attributes = {
196 | BuildIndependentTargetsInParallel = 1;
197 | LastSwiftUpdateCheck = 1330;
198 | LastUpgradeCheck = 1330;
199 | TargetAttributes = {
200 | 3C08D429286A3F160068FA83 = {
201 | CreatedOnToolsVersion = 13.3;
202 | };
203 | 3C08D43F286A3F3D0068FA83 = {
204 | CreatedOnToolsVersion = 13.3;
205 | };
206 | };
207 | };
208 | buildConfigurationList = 3C08D425286A3F160068FA83 /* Build configuration list for PBXProject "Multiliner" */;
209 | compatibilityVersion = "Xcode 13.0";
210 | developmentRegion = en;
211 | hasScannedForEncodings = 0;
212 | knownRegions = (
213 | en,
214 | Base,
215 | );
216 | mainGroup = 3C08D421286A3F160068FA83;
217 | productRefGroup = 3C08D42B286A3F160068FA83 /* Products */;
218 | projectDirPath = "";
219 | projectRoot = "";
220 | targets = (
221 | 3C08D429286A3F160068FA83 /* Multiliner */,
222 | 3C08D43F286A3F3D0068FA83 /* MultilinerExtension */,
223 | );
224 | };
225 | /* End PBXProject section */
226 |
227 | /* Begin PBXResourcesBuildPhase section */
228 | 3C08D428286A3F160068FA83 /* Resources */ = {
229 | isa = PBXResourcesBuildPhase;
230 | buildActionMask = 2147483647;
231 | files = (
232 | 3C08D432286A3F190068FA83 /* Assets.xcassets in Resources */,
233 | );
234 | runOnlyForDeploymentPostprocessing = 0;
235 | };
236 | 3C08D43E286A3F3D0068FA83 /* Resources */ = {
237 | isa = PBXResourcesBuildPhase;
238 | buildActionMask = 2147483647;
239 | files = (
240 | );
241 | runOnlyForDeploymentPostprocessing = 0;
242 | };
243 | /* End PBXResourcesBuildPhase section */
244 |
245 | /* Begin PBXSourcesBuildPhase section */
246 | 3C08D426286A3F160068FA83 /* Sources */ = {
247 | isa = PBXSourcesBuildPhase;
248 | buildActionMask = 2147483647;
249 | files = (
250 | 3C08D430286A3F160068FA83 /* ContentView.swift in Sources */,
251 | 3C08D42E286A3F160068FA83 /* MultilinerApp.swift in Sources */,
252 | );
253 | runOnlyForDeploymentPostprocessing = 0;
254 | };
255 | 3C08D43C286A3F3D0068FA83 /* Sources */ = {
256 | isa = PBXSourcesBuildPhase;
257 | buildActionMask = 2147483647;
258 | files = (
259 | 3CFEC80428753F6C0069D8C6 /* FormatError.swift in Sources */,
260 | 3CFEC80A287540390069D8C6 /* Extensions.swift in Sources */,
261 | 3C08D448286A3F3D0068FA83 /* SourceEditorExtension.swift in Sources */,
262 | 3CFEC80628753F7B0069D8C6 /* SelectionKind.swift in Sources */,
263 | 3C08D44A286A3F3D0068FA83 /* FormatSelectedCodeCommand.swift in Sources */,
264 | );
265 | runOnlyForDeploymentPostprocessing = 0;
266 | };
267 | /* End PBXSourcesBuildPhase section */
268 |
269 | /* Begin PBXTargetDependency section */
270 | 3C08D44E286A3F3D0068FA83 /* PBXTargetDependency */ = {
271 | isa = PBXTargetDependency;
272 | target = 3C08D43F286A3F3D0068FA83 /* MultilinerExtension */;
273 | targetProxy = 3C08D44D286A3F3D0068FA83 /* PBXContainerItemProxy */;
274 | };
275 | /* End PBXTargetDependency section */
276 |
277 | /* Begin XCBuildConfiguration section */
278 | 3C08D437286A3F190068FA83 /* Debug */ = {
279 | isa = XCBuildConfiguration;
280 | buildSettings = {
281 | ALWAYS_SEARCH_USER_PATHS = NO;
282 | CLANG_ANALYZER_NONNULL = YES;
283 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
284 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
285 | CLANG_ENABLE_MODULES = YES;
286 | CLANG_ENABLE_OBJC_ARC = YES;
287 | CLANG_ENABLE_OBJC_WEAK = YES;
288 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
289 | CLANG_WARN_BOOL_CONVERSION = YES;
290 | CLANG_WARN_COMMA = YES;
291 | CLANG_WARN_CONSTANT_CONVERSION = YES;
292 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
293 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
294 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
295 | CLANG_WARN_EMPTY_BODY = YES;
296 | CLANG_WARN_ENUM_CONVERSION = YES;
297 | CLANG_WARN_INFINITE_RECURSION = YES;
298 | CLANG_WARN_INT_CONVERSION = YES;
299 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
300 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
301 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
302 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
303 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
304 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
305 | CLANG_WARN_STRICT_PROTOTYPES = YES;
306 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
307 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
308 | CLANG_WARN_UNREACHABLE_CODE = YES;
309 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
310 | COPY_PHASE_STRIP = NO;
311 | DEBUG_INFORMATION_FORMAT = dwarf;
312 | ENABLE_STRICT_OBJC_MSGSEND = YES;
313 | ENABLE_TESTABILITY = YES;
314 | GCC_C_LANGUAGE_STANDARD = gnu11;
315 | GCC_DYNAMIC_NO_PIC = NO;
316 | GCC_NO_COMMON_BLOCKS = YES;
317 | GCC_OPTIMIZATION_LEVEL = 0;
318 | GCC_PREPROCESSOR_DEFINITIONS = (
319 | "DEBUG=1",
320 | "$(inherited)",
321 | );
322 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
323 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
324 | GCC_WARN_UNDECLARED_SELECTOR = YES;
325 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
326 | GCC_WARN_UNUSED_FUNCTION = YES;
327 | GCC_WARN_UNUSED_VARIABLE = YES;
328 | MACOSX_DEPLOYMENT_TARGET = 12.3;
329 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
330 | MTL_FAST_MATH = YES;
331 | ONLY_ACTIVE_ARCH = YES;
332 | SDKROOT = macosx;
333 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
334 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
335 | };
336 | name = Debug;
337 | };
338 | 3C08D438286A3F190068FA83 /* Release */ = {
339 | isa = XCBuildConfiguration;
340 | buildSettings = {
341 | ALWAYS_SEARCH_USER_PATHS = NO;
342 | CLANG_ANALYZER_NONNULL = YES;
343 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
344 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
345 | CLANG_ENABLE_MODULES = YES;
346 | CLANG_ENABLE_OBJC_ARC = YES;
347 | CLANG_ENABLE_OBJC_WEAK = YES;
348 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
349 | CLANG_WARN_BOOL_CONVERSION = YES;
350 | CLANG_WARN_COMMA = YES;
351 | CLANG_WARN_CONSTANT_CONVERSION = YES;
352 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
353 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
354 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
355 | CLANG_WARN_EMPTY_BODY = YES;
356 | CLANG_WARN_ENUM_CONVERSION = YES;
357 | CLANG_WARN_INFINITE_RECURSION = YES;
358 | CLANG_WARN_INT_CONVERSION = YES;
359 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
360 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
361 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
362 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
363 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
364 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
365 | CLANG_WARN_STRICT_PROTOTYPES = YES;
366 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
367 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
368 | CLANG_WARN_UNREACHABLE_CODE = YES;
369 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
370 | COPY_PHASE_STRIP = NO;
371 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
372 | ENABLE_NS_ASSERTIONS = NO;
373 | ENABLE_STRICT_OBJC_MSGSEND = YES;
374 | GCC_C_LANGUAGE_STANDARD = gnu11;
375 | GCC_NO_COMMON_BLOCKS = YES;
376 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
377 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
378 | GCC_WARN_UNDECLARED_SELECTOR = YES;
379 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
380 | GCC_WARN_UNUSED_FUNCTION = YES;
381 | GCC_WARN_UNUSED_VARIABLE = YES;
382 | MACOSX_DEPLOYMENT_TARGET = 12.3;
383 | MTL_ENABLE_DEBUG_INFO = NO;
384 | MTL_FAST_MATH = YES;
385 | SDKROOT = macosx;
386 | SWIFT_COMPILATION_MODE = wholemodule;
387 | SWIFT_OPTIMIZATION_LEVEL = "-O";
388 | };
389 | name = Release;
390 | };
391 | 3C08D43A286A3F190068FA83 /* Debug */ = {
392 | isa = XCBuildConfiguration;
393 | buildSettings = {
394 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
395 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
396 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
397 | CODE_SIGN_ENTITLEMENTS = Multiliner/Multiliner.entitlements;
398 | CODE_SIGN_IDENTITY = "Apple Development";
399 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
400 | CODE_SIGN_STYLE = Automatic;
401 | COMBINE_HIDPI_IMAGES = YES;
402 | CURRENT_PROJECT_VERSION = 1;
403 | DEVELOPMENT_TEAM = YA533DMD5J;
404 | ENABLE_HARDENED_RUNTIME = YES;
405 | ENABLE_PREVIEWS = YES;
406 | GENERATE_INFOPLIST_FILE = YES;
407 | INFOPLIST_KEY_CFBundleDisplayName = Multiliner;
408 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
409 | LD_RUNPATH_SEARCH_PATHS = (
410 | "$(inherited)",
411 | "@executable_path/../Frameworks",
412 | );
413 | MARKETING_VERSION = 1.2;
414 | PRODUCT_BUNDLE_IDENTIFIER = com.aheze.Multiliner;
415 | PRODUCT_NAME = "Multiliner App";
416 | PROVISIONING_PROFILE_SPECIFIER = "";
417 | SWIFT_EMIT_LOC_STRINGS = YES;
418 | SWIFT_VERSION = 5.0;
419 | };
420 | name = Debug;
421 | };
422 | 3C08D43B286A3F190068FA83 /* Release */ = {
423 | isa = XCBuildConfiguration;
424 | buildSettings = {
425 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
426 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
427 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
428 | CODE_SIGN_ENTITLEMENTS = Multiliner/Multiliner.entitlements;
429 | CODE_SIGN_IDENTITY = "Apple Development";
430 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
431 | CODE_SIGN_STYLE = Automatic;
432 | COMBINE_HIDPI_IMAGES = YES;
433 | CURRENT_PROJECT_VERSION = 1;
434 | DEVELOPMENT_TEAM = YA533DMD5J;
435 | ENABLE_HARDENED_RUNTIME = YES;
436 | ENABLE_PREVIEWS = YES;
437 | GENERATE_INFOPLIST_FILE = YES;
438 | INFOPLIST_KEY_CFBundleDisplayName = Multiliner;
439 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
440 | LD_RUNPATH_SEARCH_PATHS = (
441 | "$(inherited)",
442 | "@executable_path/../Frameworks",
443 | );
444 | MARKETING_VERSION = 1.2;
445 | PRODUCT_BUNDLE_IDENTIFIER = com.aheze.Multiliner;
446 | PRODUCT_NAME = "Multiliner App";
447 | SWIFT_EMIT_LOC_STRINGS = YES;
448 | SWIFT_VERSION = 5.0;
449 | };
450 | name = Release;
451 | };
452 | 3C08D451286A3F3D0068FA83 /* Debug */ = {
453 | isa = XCBuildConfiguration;
454 | buildSettings = {
455 | CODE_SIGN_ENTITLEMENTS = MultilinerExtension/MultilinerExtension.entitlements;
456 | CODE_SIGN_IDENTITY = "Apple Development";
457 | CODE_SIGN_STYLE = Automatic;
458 | COMBINE_HIDPI_IMAGES = YES;
459 | CURRENT_PROJECT_VERSION = 1;
460 | DEVELOPMENT_TEAM = YA533DMD5J;
461 | ENABLE_HARDENED_RUNTIME = YES;
462 | GENERATE_INFOPLIST_FILE = YES;
463 | INFOPLIST_FILE = MultilinerExtension/Info.plist;
464 | INFOPLIST_KEY_CFBundleDisplayName = Multiliner;
465 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
466 | LD_RUNPATH_SEARCH_PATHS = (
467 | "$(inherited)",
468 | "@executable_path/../Frameworks",
469 | "@executable_path/../../../../Frameworks",
470 | );
471 | MARKETING_VERSION = 1.2;
472 | PRODUCT_BUNDLE_IDENTIFIER = com.aheze.Multiliner.MultilinerExtension;
473 | PRODUCT_NAME = Multiliner;
474 | SKIP_INSTALL = YES;
475 | SWIFT_EMIT_LOC_STRINGS = YES;
476 | SWIFT_VERSION = 5.0;
477 | };
478 | name = Debug;
479 | };
480 | 3C08D452286A3F3D0068FA83 /* Release */ = {
481 | isa = XCBuildConfiguration;
482 | buildSettings = {
483 | CODE_SIGN_ENTITLEMENTS = MultilinerExtension/MultilinerExtension.entitlements;
484 | CODE_SIGN_IDENTITY = "-";
485 | CODE_SIGN_STYLE = Automatic;
486 | COMBINE_HIDPI_IMAGES = YES;
487 | CURRENT_PROJECT_VERSION = 1;
488 | DEVELOPMENT_TEAM = YA533DMD5J;
489 | ENABLE_HARDENED_RUNTIME = YES;
490 | GENERATE_INFOPLIST_FILE = YES;
491 | INFOPLIST_FILE = MultilinerExtension/Info.plist;
492 | INFOPLIST_KEY_CFBundleDisplayName = Multiliner;
493 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
494 | LD_RUNPATH_SEARCH_PATHS = (
495 | "$(inherited)",
496 | "@executable_path/../Frameworks",
497 | "@executable_path/../../../../Frameworks",
498 | );
499 | MARKETING_VERSION = 1.2;
500 | PRODUCT_BUNDLE_IDENTIFIER = com.aheze.Multiliner.MultilinerExtension;
501 | PRODUCT_NAME = Multiliner;
502 | SKIP_INSTALL = YES;
503 | SWIFT_EMIT_LOC_STRINGS = YES;
504 | SWIFT_VERSION = 5.0;
505 | };
506 | name = Release;
507 | };
508 | /* End XCBuildConfiguration section */
509 |
510 | /* Begin XCConfigurationList section */
511 | 3C08D425286A3F160068FA83 /* Build configuration list for PBXProject "Multiliner" */ = {
512 | isa = XCConfigurationList;
513 | buildConfigurations = (
514 | 3C08D437286A3F190068FA83 /* Debug */,
515 | 3C08D438286A3F190068FA83 /* Release */,
516 | );
517 | defaultConfigurationIsVisible = 0;
518 | defaultConfigurationName = Release;
519 | };
520 | 3C08D439286A3F190068FA83 /* Build configuration list for PBXNativeTarget "Multiliner" */ = {
521 | isa = XCConfigurationList;
522 | buildConfigurations = (
523 | 3C08D43A286A3F190068FA83 /* Debug */,
524 | 3C08D43B286A3F190068FA83 /* Release */,
525 | );
526 | defaultConfigurationIsVisible = 0;
527 | defaultConfigurationName = Release;
528 | };
529 | 3C08D450286A3F3D0068FA83 /* Build configuration list for PBXNativeTarget "MultilinerExtension" */ = {
530 | isa = XCConfigurationList;
531 | buildConfigurations = (
532 | 3C08D451286A3F3D0068FA83 /* Debug */,
533 | 3C08D452286A3F3D0068FA83 /* Release */,
534 | );
535 | defaultConfigurationIsVisible = 0;
536 | defaultConfigurationName = Release;
537 | };
538 | /* End XCConfigurationList section */
539 | };
540 | rootObject = 3C08D422286A3F160068FA83 /* Project object */;
541 | }
542 |
--------------------------------------------------------------------------------
/Sources/Multiliner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Sources/Multiliner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Sources/Multiliner.xcodeproj/xcshareddata/xcschemes/Multiliner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/Sources/Multiliner.xcodeproj/xcshareddata/xcschemes/MultilinerExtension.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
6 |
9 |
10 |
16 |
22 |
23 |
24 |
30 |
36 |
37 |
38 |
39 |
40 |
45 |
46 |
47 |
48 |
60 |
62 |
68 |
69 |
70 |
71 |
79 |
81 |
87 |
88 |
89 |
90 |
92 |
93 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/Sources/Multiliner.xcodeproj/xcuserdata/aheze.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/Sources/Multiliner.xcodeproj/xcuserdata/aheze.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Multiliner.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 1
11 |
12 | MultilinerExtension.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 0
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | 3C08D429286A3F160068FA83
21 |
22 | primary
23 |
24 |
25 | 3C08D43F286A3F3D0068FA83
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-128.png
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-16.png
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-256.png
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-32.png
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-512.png
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/AppIcon-64.png
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "AppIcon-16.png",
5 | "idiom" : "mac",
6 | "scale" : "1x",
7 | "size" : "16x16"
8 | },
9 | {
10 | "filename" : "AppIcon-32.png",
11 | "idiom" : "mac",
12 | "scale" : "2x",
13 | "size" : "16x16"
14 | },
15 | {
16 | "filename" : "AppIcon-32.png",
17 | "idiom" : "mac",
18 | "scale" : "1x",
19 | "size" : "32x32"
20 | },
21 | {
22 | "filename" : "AppIcon-64.png",
23 | "idiom" : "mac",
24 | "scale" : "2x",
25 | "size" : "32x32"
26 | },
27 | {
28 | "filename" : "AppIcon-128.png",
29 | "idiom" : "mac",
30 | "scale" : "1x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "filename" : "AppIcon-256.png",
35 | "idiom" : "mac",
36 | "scale" : "2x",
37 | "size" : "128x128"
38 | },
39 | {
40 | "filename" : "AppIcon-256.png",
41 | "idiom" : "mac",
42 | "scale" : "1x",
43 | "size" : "256x256"
44 | },
45 | {
46 | "filename" : "AppIcon-512.png",
47 | "idiom" : "mac",
48 | "scale" : "2x",
49 | "size" : "256x256"
50 | },
51 | {
52 | "filename" : "AppIcon-512.png",
53 | "idiom" : "mac",
54 | "scale" : "1x",
55 | "size" : "512x512"
56 | },
57 | {
58 | "filename" : "AppIcon-1024.png",
59 | "idiom" : "mac",
60 | "scale" : "2x",
61 | "size" : "512x512"
62 | }
63 | ],
64 | "info" : {
65 | "author" : "xcode",
66 | "version" : 1
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/Banner.imageset/Banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Sources/Multiliner/Assets.xcassets/Banner.imageset/Banner.png
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/Banner.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Banner.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/Preferences.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Preferences.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/Preferences.imageset/Preferences.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Sources/Multiliner/Assets.xcassets/Preferences.imageset/Preferences.png
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/UsageCode.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "UsageCode.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/UsageCode.imageset/UsageCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Sources/Multiliner/Assets.xcassets/UsageCode.imageset/UsageCode.png
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/UsageMenu.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "UsageMenu.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/UsageMenu.imageset/UsageMenu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Sources/Multiliner/Assets.xcassets/UsageMenu.imageset/UsageMenu.png
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/UsageResult.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "UsageResult.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/UsageResult.imageset/UsageResult.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Sources/Multiliner/Assets.xcassets/UsageResult.imageset/UsageResult.png
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/UsageShortcut.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "UsageShortcut.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Sources/Multiliner/Assets.xcassets/UsageShortcut.imageset/UsageShortcut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aheze/Multiliner/650a646308d9c1c9355b55fe29c609c1d3237511/Sources/Multiliner/Assets.xcassets/UsageShortcut.imageset/UsageShortcut.png
--------------------------------------------------------------------------------
/Sources/Multiliner/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // Multiliner
4 | //
5 | // Created by A. Zheng (github.com/aheze) on 6/27/22.
6 | // Copyright © 2022 A. Zheng. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 | var body: some View {
13 | ScrollView {
14 | VStack(alignment: .leading, spacing: 20) {
15 | Image("Banner")
16 | .resizable()
17 | .aspectRatio(contentMode: .fit)
18 |
19 | VStack(alignment: .leading, spacing: 6) {
20 | Text("Multiliner")
21 | .font(.largeTitle)
22 | .bold()
23 |
24 | Text("An Xcode source extension to expand lengthy lines.")
25 | .font(.title)
26 | .fontWeight(.medium)
27 | .foregroundColor(.secondary)
28 | }
29 |
30 | Divider()
31 |
32 | VStack(alignment: .leading) {
33 | VStack(alignment: .leading) {
34 | Text("Installation")
35 | .font(.title2)
36 | .bold()
37 |
38 | Text("Now that you have the app installed, just head over to System Preferences and check `Multiliner`.")
39 | .font(.title3)
40 |
41 | Screenshot(image: "Preferences")
42 |
43 | Text("System Preferences → Extensions → Xcode Source Editor")
44 | .font(.caption)
45 | .textCase(.uppercase)
46 | }
47 |
48 | VStack(alignment: .leading, spacing: 20) {
49 | VStack(alignment: .leading) {
50 | Text("Usage")
51 | .font(.title2)
52 | .bold()
53 |
54 | Text("1. Select some code in Xcode. Make sure to include the opening and closing braces.")
55 | .font(.title3)
56 |
57 | Image("UsageCode")
58 | .resizable()
59 | .aspectRatio(contentMode: .fit)
60 | }
61 |
62 | VStack(alignment: .leading) {
63 | Text("2. Then, go to Editor → Multiliner → Format Selected Code. Your code will get reformatted!")
64 | .font(.title3)
65 |
66 | HStack(alignment: .top) {
67 | Image("UsageMenu")
68 | .resizable()
69 | .aspectRatio(contentMode: .fit)
70 | .cornerRadius(8)
71 | .shadow(
72 | color: .black.opacity(0.25),
73 | radius: 16,
74 | x: 0,
75 | y: 2
76 | )
77 |
78 | Image("UsageResult")
79 | .resizable()
80 | .aspectRatio(contentMode: .fit)
81 | .cornerRadius(8)
82 | .shadow(
83 | color: .black.opacity(0.25),
84 | radius: 16,
85 | x: 0,
86 | y: 2
87 | )
88 | }
89 | }
90 |
91 | VStack(alignment: .leading) {
92 | Text("3. To make this extension easier to reach, consider adding a shortcut in Xcode's Key Bindings.")
93 | .font(.title3)
94 |
95 | Screenshot(image: "UsageShortcut")
96 |
97 | Text("Xcode → Preferences → Key Bindings")
98 | .font(.caption)
99 | .textCase(.uppercase)
100 | }
101 | }
102 | }
103 |
104 | Divider()
105 |
106 | Text("That's it! If you have any questions or suggestions, feel free to ping me on Twitter ([@aheze0](https://twitter.com/aheze0)), join the [Discord](https://discord.gg/Pmq8fYcus2), or [open an issue](https://github.com/aheze/Multiliner/issues).")
107 | }
108 | .frame(maxWidth: 800)
109 | .padding(.horizontal, 64)
110 | .padding(.vertical, 32)
111 | .frame(maxWidth: .infinity)
112 | }
113 | .frame(
114 | minWidth: 400,
115 | idealWidth: 500,
116 | maxWidth: .infinity,
117 | minHeight: 300,
118 | idealHeight: 700,
119 | maxHeight: .infinity,
120 | alignment: .leading
121 | )
122 | .navigationTitle("Multiliner")
123 | .toolbar {
124 | ToolbarItemGroup(placement: .primaryAction) {
125 | Button {
126 | if let url = URL(string: "https://github.com/aheze/Multiliner") {
127 | NSWorkspace.shared.open(url)
128 | }
129 | } label: {
130 | Text("View on GitHub")
131 | }
132 |
133 | Button {
134 | if let url = URL(string: "https://github.com/aheze/Multiliner/issues") {
135 | NSWorkspace.shared.open(url)
136 | }
137 | } label: {
138 | Text("Help")
139 | }
140 | }
141 | }
142 | }
143 | }
144 |
145 | struct Screenshot: View {
146 | var image: String
147 | var body: some View {
148 | Image(image)
149 | .resizable()
150 | .aspectRatio(contentMode: .fit)
151 | .frame(maxWidth: 600)
152 | .padding(.horizontal, -42)
153 | .padding(.top, -20)
154 | .padding(.bottom, -40)
155 | }
156 | }
157 |
158 | struct ContentView_Previews: PreviewProvider {
159 | static var previews: some View {
160 | ContentView()
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/Sources/Multiliner/Multiliner.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Sources/Multiliner/MultilinerApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MultilinerApp.swift
3 | // Multiliner
4 | //
5 | // Created by A. Zheng (github.com/aheze) on 6/27/22.
6 | // Copyright © 2022 A. Zheng. All rights reserved.
7 | //
8 |
9 |
10 | import SwiftUI
11 |
12 | @main
13 | struct MultilinerApp: App {
14 | var body: some Scene {
15 | WindowGroup {
16 | ContentView()
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Sources/MultilinerExtension/Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Extensions.swift
3 | // Multiliner
4 | //
5 | // Created by A. Zheng (github.com/aheze) on 7/5/22.
6 | // Copyright © 2022 A. Zheng. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | extension XCSourceEditorCommand {
13 | /// Get the lines of an entire files as an array of `String`s.
14 | func getLines(from buffer: XCSourceTextBuffer) -> [String] {
15 | guard let lines = buffer.lines as? [String] else { return [] }
16 | return lines
17 | }
18 |
19 | /// Get a single string from a range.
20 | func getText(from range: XCSourceTextRange, buffer: XCSourceTextBuffer) -> String {
21 | let allLines = getLines(from: buffer)
22 | let lines = allLines[range.start.line ... range.end.line]
23 | let text = lines.map { String($0) }.joined()
24 | return text
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Sources/MultilinerExtension/FormatError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FormatError.swift
3 | // Multiliner
4 | //
5 | // Created by A. Zheng (github.com/aheze) on 7/5/22.
6 | // Copyright © 2022 A. Zheng. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | enum FormatError: Error, CustomStringConvertible, LocalizedError, CustomNSError {
12 | case noSelection
13 | case invalidSelection
14 |
15 | var description: String {
16 | switch self {
17 | case .noSelection:
18 | return "No selection."
19 | case .invalidSelection:
20 | return "Selection must be bounded by `()` or `[]`."
21 | }
22 | }
23 |
24 | var localizedDescription: String {
25 | return "Error: \(description)."
26 | }
27 |
28 | var errorUserInfo: [String: Any] {
29 | return [NSLocalizedDescriptionKey: localizedDescription]
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Sources/MultilinerExtension/FormatSelectedCodeCommand.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SourceEditorCommand.swift
3 | // Multiliner
4 | //
5 | // Created by A. Zheng (github.com/aheze) on 6/27/22.
6 | // Copyright © 2022 A. Zheng. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | class FormatSelectedCodeCommand: NSObject, XCSourceEditorCommand {
13 | /// The `Format Selected Code` command.
14 | func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void) {
15 | /// Get the selection first.
16 | guard
17 | let selection = invocation.buffer.selections.firstObject,
18 | let range = selection as? XCSourceTextRange
19 | else {
20 | completionHandler(FormatError.noSelection)
21 | return
22 | }
23 |
24 | /// It's possible that the user selected the last "extra" line too.
25 | if range.start.line > invocation.buffer.lines.count - 1 { range.start.line -= 1 }
26 | if range.end.line > invocation.buffer.lines.count - 1 { range.end.line -= 1 }
27 |
28 | /// Store the current lines of the entire file.
29 | let oldLines = getLines(from: invocation.buffer)
30 |
31 | /// The width of a single tab, usually ` `.
32 | let tab: String
33 |
34 | /// The selection's starting tab.
35 | /// Example:
36 | // **input** ` init()`
37 | // **output** ` `
38 | let startTab: Substring
39 |
40 | let startColumn: Int
41 |
42 | if invocation.buffer.usesTabsForIndentation {
43 | tab = "\u{0009}" /// Tab character.
44 |
45 | startTab = oldLines[range.start.line]
46 | .prefix { $0 == "\u{0009}" }
47 |
48 | startColumn = startTab.count
49 |
50 | } else {
51 | startTab = oldLines[range.start.line]
52 | .prefix { $0 == " " }
53 |
54 | tab = String(repeating: " ", count: invocation.buffer.indentationWidth)
55 |
56 | startColumn = startTab.count / invocation.buffer.indentationWidth
57 | }
58 |
59 | /// The tab that prefixes each parameter/array element.
60 | let contentTab = startTab + tab
61 |
62 | /// The entire text of the file.
63 | let text = getText(from: range, buffer: invocation.buffer)
64 |
65 | /// Get the opening and closing indices if the selected text contains parameters.
66 | let openingParenthesisIndex = text.firstIndex(of: "(")
67 | let closingParenthesisIndex = text.lastIndex(of: ")")
68 |
69 | /// Get the opening and closing array element if the selected text is an array.
70 | let openingArrayIndex = text.firstIndex(of: "[")
71 | let closingArrayIndex = text.lastIndex(of: "]")
72 |
73 | /// Determine if the selection was an array or a set of parameters.
74 | /// Only use the opening brace for comparison.
75 | var selectionKind: SelectionKind
76 | switch (openingParenthesisIndex, openingArrayIndex) {
77 | case let (.some(openingParenthesisIndex), .some(openingArrayIndex)):
78 | if openingParenthesisIndex < openingArrayIndex {
79 | selectionKind = .parameters
80 | } else {
81 | selectionKind = .array
82 | }
83 | case (.some, .none):
84 | selectionKind = .parameters
85 | case (.none, .some):
86 | selectionKind = .array
87 | default:
88 | completionHandler(FormatError.noSelection)
89 | return
90 | }
91 |
92 | /// Determine if the selection was an array or a set of parameters.
93 | let openingBracesIndex: String.Index? = selectionKind == .parameters
94 | ? openingParenthesisIndex
95 | : openingArrayIndex
96 |
97 | let closingBracesIndex: String.Index? = selectionKind == .parameters
98 | ? closingParenthesisIndex
99 | : closingArrayIndex
100 |
101 | /// Make sure there's an opening and closing index.
102 | guard let openingBracesIndex = openingBracesIndex, let closingBracesIndex = closingBracesIndex else {
103 | completionHandler(FormatError.invalidSelection)
104 | return
105 | }
106 |
107 | /// Skip the opening `(` or `[`.
108 | let openingContentIndex = text.index(after: openingBracesIndex)
109 | let closingContentIndex = closingBracesIndex
110 |
111 | /// The text inside the braces.
112 | let contentsString = text[openingContentIndex ..< closingContentIndex]
113 | let contents = contentsString
114 | .components(separatedBy: ",")
115 |
116 | /// Format the content by adding spaces and commas.
117 | let contentsFormatted: [String] = contents.enumerated()
118 | .map { index, element in
119 | let line = element.trimmingCharacters(in: .whitespacesAndNewlines)
120 | if index == contents.indices.last {
121 | return contentTab + line
122 | } else {
123 | return contentTab + line + ","
124 | }
125 | }
126 |
127 | /// The string that comes before the selection.
128 | let openingString = text[..
2 |
3 |
4 |
5 | NSExtension
6 |
7 | NSExtensionAttributes
8 |
9 | XCSourceEditorCommandDefinitions
10 |
11 |
12 | XCSourceEditorCommandClassName
13 | $(PRODUCT_MODULE_NAME).FormatSelectedCodeCommand
14 | XCSourceEditorCommandIdentifier
15 | $(PRODUCT_BUNDLE_IDENTIFIER).FormatSelectedCodeCommand
16 | XCSourceEditorCommandName
17 | Format Selected Code
18 |
19 |
20 | XCSourceEditorExtensionPrincipalClass
21 | $(PRODUCT_MODULE_NAME).SourceEditorExtension
22 |
23 | NSExtensionPointIdentifier
24 | com.apple.dt.Xcode.extension.source-editor
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Sources/MultilinerExtension/MultilinerExtension.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Sources/MultilinerExtension/SelectionKind.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SelectionKind.swift
3 | // Multiliner
4 | //
5 | // Created by A. Zheng (github.com/aheze) on 7/5/22.
6 | // Copyright © 2022 A. Zheng. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | enum SelectionKind {
12 | case parameters
13 | case array
14 | }
15 |
--------------------------------------------------------------------------------
/Sources/MultilinerExtension/SourceEditorExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SourceEditorExtension.swift
3 | // Multiliner
4 | //
5 | // Created by A. Zheng (github.com/aheze) on 6/27/22.
6 | // Copyright © 2022 A. Zheng. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | /// Boilerplate code.
13 | class SourceEditorExtension: NSObject, XCSourceEditorExtension {}
14 |
--------------------------------------------------------------------------------