├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── XcodeClangFormat.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── XcodeClangFormat.xcscheme │ └── clang-format.xcscheme ├── XcodeClangFormat ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Base.lproj │ └── MainMenu.xib ├── Info.plist ├── XcodeClangFormat.entitlements └── main.m ├── clang-format ├── ClangFormat.h ├── ClangFormatCommand.h ├── ClangFormatCommand.mm ├── ClangFormatExtension.h ├── ClangFormatExtension.m ├── Info.plist └── clang_format.entitlements ├── configure ├── screenshot-config.png ├── screenshot-extensions.png ├── screenshot-format.png └── screenshot-shortcut.png /.gitignore: -------------------------------------------------------------------------------- 1 | xcuserdata 2 | /config.xcconfig 3 | /deps -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.1 2 | 3 | Released on May 19, 2020. 4 | 5 | - Upgraded Clang to 10.0.0 6 | - Fixed configure script to work in directories that contain spaces 7 | - Added detection of source code type: clang-format can now apply different formatting to C/C++, Objective-C/C++, Java and JavaScript 8 | - Changed patch application to individual lines rather than replacing the whole buffer. This preserves selections and breakpoints much better. Note that they are still removed in situations, e.g. when the code around the breakpoint is changed. 9 | - Added command to format the entire file, rather than just the selection 10 | - Renamed the existing command to "Format Selection". **This means you'll have to change your shortcut definitions** 11 | 12 | ## 1.0 13 | 14 | Released on Sep 13, 2016. 15 | 16 | - Initial version 17 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | XcodeClangFormat copyright (c) 2020 Mapbox. 2 | 3 | Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met: 4 | 5 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XcodeClangFormat 2 | 3 | ### [⚙ Download Latest Release](https://github.com/mapbox/XcodeClangFormat/releases/latest) 4 | Uses `clang-format` from [Clang 10](https://releases.llvm.org/10.0.0/tools/clang/docs/ClangFormat.html) 5 | 6 | ...or install with Homebrew: `brew install --cask xcodeclangformat` 7 | 8 | This plugin is written for Xcode 8's new plugin infrastructure and compatible through at least Xcode 11.4 It uses Clang's `libclangFormat` library to format code according to a `.clang-format` file. 9 | 10 | Open the app, select a predefined style, or open the `.clang-format` file from your project: 11 | 12 | ![](screenshot-config.png) 13 | 14 | Then, use the Format Source Code command in Xcode's Editor menu: 15 | 16 | ![](screenshot-format.png) 17 | 18 | Due to macOS sandboxing restrictions, this plugin behaves slightly differently compared to the command line `clang-format` command: It always uses the style selected in the configuration app, and will not use the nearest `.clang-format` file on disk. 19 | 20 | 21 | ## Installing 22 | 23 | Download the precompiled app or [build it yourself](#building), then open the app. You might have to right click on the app bundle, and choose Open to run non-codesigned applications. Then, 24 | 25 | * On OS X 10.11, you'll need to run `sudo /usr/libexec/xpccachectl`, then **reboot** to enable app extensions. 26 | * On macOS Sierra and later, extensions should be loaded by default. 27 | 28 | Then, go to *System Preferences* → *Extensions*, and make sure that **clang-format** in the *Xcode Source Editor* section is checked: 29 | 30 | ![](screenshot-extensions.png) 31 | 32 | 33 | ## Keyboard shortcut 34 | 35 | To define a keyboard shortcut, open Xcode's preferences, and switch to the *Key Bindings* tab. Duplicate the default key binding set if you don't have your own set already. Search for `clang-format`, then add your preferred key bindings for `Format Selection` or `Format Entire File`. 36 | 37 | ![](screenshot-shortcut.png) 38 | 39 | 40 | ## Building 41 | 42 | To build XcodeClangFormat, run `./configure` on the command line, then build the XcodeClangFormat scheme in the included Xcode project. 43 | 44 | 45 | ## FAQ 46 | 47 | ##### Why aren't you just using the `.clang-format` file in the file's parent folder? 48 | Xcode code formatting extensions are severely limited and don't have access to the file system. They also don't get to know the file name of the file to be changed, so there's no way for this extension to load the correct file. 49 | 50 | ##### Could you please add “Format on Save”? 51 | The Xcode extension mechanism doesn't allow that; the only thing you can do is return the altered source code. 52 | 53 | ##### Why doesn't the menu item show up? 54 | If you're using macOS Sierra, please follow the [installing](#installing) guide. on OS X 10.11, I haven't found a way to make this extension work besides [manually building it](#building). 55 | 56 | If the menu items randomly disappears, quit Xcode. In Finder, [rename `Xcode.app` to something else, then rename it back to `Xcode.app`](https://stackoverflow.com/a/48893833). 🤯 57 | 58 | ##### When compiling, I'm getting `'clang/Format/Format.h' file not found`. 59 | Make sure that you're running `./configure` in the root folder. This downloads and unpacks the precompiled libraries and headers from the llvm.org that are required for compiling. 60 | -------------------------------------------------------------------------------- /XcodeClangFormat.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 559B23E31D7EBDA300937AB3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 559B23E21D7EBDA300937AB3 /* AppDelegate.m */; }; 11 | 559B23E61D7EBDA300937AB3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 559B23E51D7EBDA300937AB3 /* main.m */; }; 12 | 559B23E81D7EBDA300937AB3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 559B23E71D7EBDA300937AB3 /* Assets.xcassets */; }; 13 | 559B23EB1D7EBDA300937AB3 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 559B23E91D7EBDA300937AB3 /* MainMenu.xib */; }; 14 | 559B24101D7EBDC400937AB3 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 559B23F81D7EBDB700937AB3 /* Cocoa.framework */; }; 15 | 559B24161D7EBDC400937AB3 /* ClangFormatExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 559B24151D7EBDC400937AB3 /* ClangFormatExtension.m */; }; 16 | 559B24191D7EBDC400937AB3 /* ClangFormatCommand.mm in Sources */ = {isa = PBXBuildFile; fileRef = 559B24181D7EBDC400937AB3 /* ClangFormatCommand.mm */; }; 17 | 559B241D1D7EBDC400937AB3 /* clang-format.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 559B240F1D7EBDC400937AB3 /* clang-format.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 18 | 55BCFFFA1D80170F000EDB05 /* libcurses.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 557D38B71D7F270E00708269 /* libcurses.tbd */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 559B241B1D7EBDC400937AB3 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 559B23D61D7EBDA300937AB3 /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = 559B240E1D7EBDC400937AB3; 27 | remoteInfo = "clang-format"; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXCopyFilesBuildPhase section */ 32 | 559B240A1D7EBDB700937AB3 /* Embed App Extensions */ = { 33 | isa = PBXCopyFilesBuildPhase; 34 | buildActionMask = 2147483647; 35 | dstPath = ""; 36 | dstSubfolderSpec = 13; 37 | files = ( 38 | 559B241D1D7EBDC400937AB3 /* clang-format.appex in Embed App Extensions */, 39 | ); 40 | name = "Embed App Extensions"; 41 | runOnlyForDeploymentPostprocessing = 0; 42 | }; 43 | /* End PBXCopyFilesBuildPhase section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 552396A22473BCCB002F4098 /* ClangFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClangFormat.h; sourceTree = ""; }; 47 | 556DCDEF1D7EF694005956C8 /* XcodeClangFormat.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = XcodeClangFormat.entitlements; sourceTree = ""; }; 48 | 557D38B71D7F270E00708269 /* libcurses.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurses.tbd; path = usr/lib/libcurses.tbd; sourceTree = SDKROOT; }; 49 | 559B23DE1D7EBDA300937AB3 /* XcodeClangFormat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XcodeClangFormat.app; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 559B23E11D7EBDA300937AB3 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 51 | 559B23E21D7EBDA300937AB3 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 52 | 559B23E51D7EBDA300937AB3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 53 | 559B23E71D7EBDA300937AB3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 54 | 559B23EA1D7EBDA300937AB3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 55 | 559B23EC1D7EBDA300937AB3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 56 | 559B23F81D7EBDB700937AB3 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 57 | 559B240F1D7EBDC400937AB3 /* clang-format.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "clang-format.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 559B24131D7EBDC400937AB3 /* clang_format.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = clang_format.entitlements; sourceTree = ""; }; 59 | 559B24141D7EBDC400937AB3 /* ClangFormatExtension.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ClangFormatExtension.h; sourceTree = ""; }; 60 | 559B24151D7EBDC400937AB3 /* ClangFormatExtension.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ClangFormatExtension.m; sourceTree = ""; }; 61 | 559B24171D7EBDC400937AB3 /* ClangFormatCommand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ClangFormatCommand.h; sourceTree = ""; }; 62 | 559B24181D7EBDC400937AB3 /* ClangFormatCommand.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ClangFormatCommand.mm; sourceTree = ""; }; 63 | 559B241A1D7EBDC400937AB3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 64 | 55BCFFF71D801362000EDB05 /* config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = config.xcconfig; sourceTree = ""; }; 65 | 55C8203F1D87F81300006D07 /* LICENSE.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = LICENSE.md; sourceTree = ""; }; 66 | /* End PBXFileReference section */ 67 | 68 | /* Begin PBXFrameworksBuildPhase section */ 69 | 559B23DB1D7EBDA300937AB3 /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | 559B240C1D7EBDC400937AB3 /* Frameworks */ = { 77 | isa = PBXFrameworksBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | 55BCFFFA1D80170F000EDB05 /* libcurses.tbd in Frameworks */, 81 | 559B24101D7EBDC400937AB3 /* Cocoa.framework in Frameworks */, 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | /* End PBXFrameworksBuildPhase section */ 86 | 87 | /* Begin PBXGroup section */ 88 | 559B23D51D7EBDA300937AB3 = { 89 | isa = PBXGroup; 90 | children = ( 91 | 55BCFFF71D801362000EDB05 /* config.xcconfig */, 92 | 55C8203F1D87F81300006D07 /* LICENSE.md */, 93 | 559B23E01D7EBDA300937AB3 /* XcodeClangFormat */, 94 | 559B24111D7EBDC400937AB3 /* clang-format */, 95 | 559B23F71D7EBDB700937AB3 /* Frameworks */, 96 | 559B23DF1D7EBDA300937AB3 /* Products */, 97 | ); 98 | sourceTree = ""; 99 | }; 100 | 559B23DF1D7EBDA300937AB3 /* Products */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 559B23DE1D7EBDA300937AB3 /* XcodeClangFormat.app */, 104 | 559B240F1D7EBDC400937AB3 /* clang-format.appex */, 105 | ); 106 | name = Products; 107 | sourceTree = ""; 108 | }; 109 | 559B23E01D7EBDA300937AB3 /* XcodeClangFormat */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 556DCDEF1D7EF694005956C8 /* XcodeClangFormat.entitlements */, 113 | 559B23E11D7EBDA300937AB3 /* AppDelegate.h */, 114 | 559B23E21D7EBDA300937AB3 /* AppDelegate.m */, 115 | 559B23E71D7EBDA300937AB3 /* Assets.xcassets */, 116 | 559B23E91D7EBDA300937AB3 /* MainMenu.xib */, 117 | 559B23EC1D7EBDA300937AB3 /* Info.plist */, 118 | 559B23E41D7EBDA300937AB3 /* Supporting Files */, 119 | ); 120 | path = XcodeClangFormat; 121 | sourceTree = ""; 122 | }; 123 | 559B23E41D7EBDA300937AB3 /* Supporting Files */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 559B23E51D7EBDA300937AB3 /* main.m */, 127 | ); 128 | name = "Supporting Files"; 129 | sourceTree = ""; 130 | }; 131 | 559B23F71D7EBDB700937AB3 /* Frameworks */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 557D38B71D7F270E00708269 /* libcurses.tbd */, 135 | 559B23F81D7EBDB700937AB3 /* Cocoa.framework */, 136 | ); 137 | name = Frameworks; 138 | sourceTree = ""; 139 | }; 140 | 559B24111D7EBDC400937AB3 /* clang-format */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 552396A22473BCCB002F4098 /* ClangFormat.h */, 144 | 559B24141D7EBDC400937AB3 /* ClangFormatExtension.h */, 145 | 559B24181D7EBDC400937AB3 /* ClangFormatCommand.mm */, 146 | 559B24151D7EBDC400937AB3 /* ClangFormatExtension.m */, 147 | 559B24171D7EBDC400937AB3 /* ClangFormatCommand.h */, 148 | 559B241A1D7EBDC400937AB3 /* Info.plist */, 149 | 559B24121D7EBDC400937AB3 /* Supporting Files */, 150 | ); 151 | path = "clang-format"; 152 | sourceTree = ""; 153 | }; 154 | 559B24121D7EBDC400937AB3 /* Supporting Files */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | 559B24131D7EBDC400937AB3 /* clang_format.entitlements */, 158 | ); 159 | name = "Supporting Files"; 160 | sourceTree = ""; 161 | }; 162 | /* End PBXGroup section */ 163 | 164 | /* Begin PBXNativeTarget section */ 165 | 559B23DD1D7EBDA300937AB3 /* XcodeClangFormat */ = { 166 | isa = PBXNativeTarget; 167 | buildConfigurationList = 559B23EF1D7EBDA300937AB3 /* Build configuration list for PBXNativeTarget "XcodeClangFormat" */; 168 | buildPhases = ( 169 | 559B23DA1D7EBDA300937AB3 /* Sources */, 170 | 559B23DB1D7EBDA300937AB3 /* Frameworks */, 171 | 559B23DC1D7EBDA300937AB3 /* Resources */, 172 | 559B240A1D7EBDB700937AB3 /* Embed App Extensions */, 173 | ); 174 | buildRules = ( 175 | ); 176 | dependencies = ( 177 | 559B241C1D7EBDC400937AB3 /* PBXTargetDependency */, 178 | ); 179 | name = XcodeClangFormat; 180 | productName = XcodeClangFormat; 181 | productReference = 559B23DE1D7EBDA300937AB3 /* XcodeClangFormat.app */; 182 | productType = "com.apple.product-type.application"; 183 | }; 184 | 559B240E1D7EBDC400937AB3 /* clang-format */ = { 185 | isa = PBXNativeTarget; 186 | buildConfigurationList = 559B241E1D7EBDC400937AB3 /* Build configuration list for PBXNativeTarget "clang-format" */; 187 | buildPhases = ( 188 | 559B240B1D7EBDC400937AB3 /* Sources */, 189 | 559B240C1D7EBDC400937AB3 /* Frameworks */, 190 | 559B240D1D7EBDC400937AB3 /* Resources */, 191 | ); 192 | buildRules = ( 193 | ); 194 | dependencies = ( 195 | ); 196 | name = "clang-format"; 197 | productName = "clang-format"; 198 | productReference = 559B240F1D7EBDC400937AB3 /* clang-format.appex */; 199 | productType = "com.apple.product-type.xcode-extension"; 200 | }; 201 | /* End PBXNativeTarget section */ 202 | 203 | /* Begin PBXProject section */ 204 | 559B23D61D7EBDA300937AB3 /* Project object */ = { 205 | isa = PBXProject; 206 | attributes = { 207 | LastUpgradeCheck = 1140; 208 | ORGANIZATIONNAME = Mapbox; 209 | TargetAttributes = { 210 | 559B23DD1D7EBDA300937AB3 = { 211 | CreatedOnToolsVersion = 8.0; 212 | ProvisioningStyle = Automatic; 213 | SystemCapabilities = { 214 | com.apple.ApplicationGroups.Mac = { 215 | enabled = 1; 216 | }; 217 | com.apple.Sandbox = { 218 | enabled = 1; 219 | }; 220 | }; 221 | }; 222 | 559B240E1D7EBDC400937AB3 = { 223 | CreatedOnToolsVersion = 8.0; 224 | ProvisioningStyle = Automatic; 225 | SystemCapabilities = { 226 | com.apple.ApplicationGroups.Mac = { 227 | enabled = 1; 228 | }; 229 | }; 230 | }; 231 | }; 232 | }; 233 | buildConfigurationList = 559B23D91D7EBDA300937AB3 /* Build configuration list for PBXProject "XcodeClangFormat" */; 234 | compatibilityVersion = "Xcode 3.2"; 235 | developmentRegion = en; 236 | hasScannedForEncodings = 0; 237 | knownRegions = ( 238 | en, 239 | Base, 240 | ); 241 | mainGroup = 559B23D51D7EBDA300937AB3; 242 | productRefGroup = 559B23DF1D7EBDA300937AB3 /* Products */; 243 | projectDirPath = ""; 244 | projectRoot = ""; 245 | targets = ( 246 | 559B23DD1D7EBDA300937AB3 /* XcodeClangFormat */, 247 | 559B240E1D7EBDC400937AB3 /* clang-format */, 248 | ); 249 | }; 250 | /* End PBXProject section */ 251 | 252 | /* Begin PBXResourcesBuildPhase section */ 253 | 559B23DC1D7EBDA300937AB3 /* Resources */ = { 254 | isa = PBXResourcesBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | 559B23E81D7EBDA300937AB3 /* Assets.xcassets in Resources */, 258 | 559B23EB1D7EBDA300937AB3 /* MainMenu.xib in Resources */, 259 | ); 260 | runOnlyForDeploymentPostprocessing = 0; 261 | }; 262 | 559B240D1D7EBDC400937AB3 /* Resources */ = { 263 | isa = PBXResourcesBuildPhase; 264 | buildActionMask = 2147483647; 265 | files = ( 266 | ); 267 | runOnlyForDeploymentPostprocessing = 0; 268 | }; 269 | /* End PBXResourcesBuildPhase section */ 270 | 271 | /* Begin PBXSourcesBuildPhase section */ 272 | 559B23DA1D7EBDA300937AB3 /* Sources */ = { 273 | isa = PBXSourcesBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | 559B23E61D7EBDA300937AB3 /* main.m in Sources */, 277 | 559B23E31D7EBDA300937AB3 /* AppDelegate.m in Sources */, 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | }; 281 | 559B240B1D7EBDC400937AB3 /* Sources */ = { 282 | isa = PBXSourcesBuildPhase; 283 | buildActionMask = 2147483647; 284 | files = ( 285 | 559B24161D7EBDC400937AB3 /* ClangFormatExtension.m in Sources */, 286 | 559B24191D7EBDC400937AB3 /* ClangFormatCommand.mm in Sources */, 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | }; 290 | /* End PBXSourcesBuildPhase section */ 291 | 292 | /* Begin PBXTargetDependency section */ 293 | 559B241C1D7EBDC400937AB3 /* PBXTargetDependency */ = { 294 | isa = PBXTargetDependency; 295 | target = 559B240E1D7EBDC400937AB3 /* clang-format */; 296 | targetProxy = 559B241B1D7EBDC400937AB3 /* PBXContainerItemProxy */; 297 | }; 298 | /* End PBXTargetDependency section */ 299 | 300 | /* Begin PBXVariantGroup section */ 301 | 559B23E91D7EBDA300937AB3 /* MainMenu.xib */ = { 302 | isa = PBXVariantGroup; 303 | children = ( 304 | 559B23EA1D7EBDA300937AB3 /* Base */, 305 | ); 306 | name = MainMenu.xib; 307 | sourceTree = ""; 308 | }; 309 | /* End PBXVariantGroup section */ 310 | 311 | /* Begin XCBuildConfiguration section */ 312 | 559B23ED1D7EBDA300937AB3 /* Debug */ = { 313 | isa = XCBuildConfiguration; 314 | buildSettings = { 315 | ALWAYS_SEARCH_USER_PATHS = NO; 316 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 317 | CLANG_ANALYZER_NONNULL = YES; 318 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 319 | CLANG_CXX_LIBRARY = "libc++"; 320 | CLANG_ENABLE_MODULES = YES; 321 | CLANG_ENABLE_OBJC_ARC = YES; 322 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 323 | CLANG_WARN_BOOL_CONVERSION = YES; 324 | CLANG_WARN_COMMA = YES; 325 | CLANG_WARN_CONSTANT_CONVERSION = YES; 326 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 327 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 328 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 329 | CLANG_WARN_EMPTY_BODY = YES; 330 | CLANG_WARN_ENUM_CONVERSION = YES; 331 | CLANG_WARN_INFINITE_RECURSION = YES; 332 | CLANG_WARN_INT_CONVERSION = YES; 333 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 334 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 335 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 336 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 337 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 338 | CLANG_WARN_STRICT_PROTOTYPES = YES; 339 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 340 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 341 | CLANG_WARN_UNREACHABLE_CODE = YES; 342 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 343 | CODE_SIGN_IDENTITY = "-"; 344 | COPY_PHASE_STRIP = NO; 345 | DEBUG_INFORMATION_FORMAT = dwarf; 346 | ENABLE_STRICT_OBJC_MSGSEND = YES; 347 | ENABLE_TESTABILITY = YES; 348 | GCC_C_LANGUAGE_STANDARD = gnu99; 349 | GCC_DYNAMIC_NO_PIC = NO; 350 | GCC_NO_COMMON_BLOCKS = YES; 351 | GCC_OPTIMIZATION_LEVEL = 0; 352 | GCC_PREPROCESSOR_DEFINITIONS = ( 353 | "DEBUG=1", 354 | "$(inherited)", 355 | ); 356 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 357 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 358 | GCC_WARN_UNDECLARED_SELECTOR = YES; 359 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 360 | GCC_WARN_UNUSED_FUNCTION = YES; 361 | GCC_WARN_UNUSED_VARIABLE = YES; 362 | MACOSX_DEPLOYMENT_TARGET = 10.11; 363 | MTL_ENABLE_DEBUG_INFO = YES; 364 | ONLY_ACTIVE_ARCH = YES; 365 | SDKROOT = macosx; 366 | }; 367 | name = Debug; 368 | }; 369 | 559B23EE1D7EBDA300937AB3 /* Release */ = { 370 | isa = XCBuildConfiguration; 371 | buildSettings = { 372 | ALWAYS_SEARCH_USER_PATHS = NO; 373 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 374 | CLANG_ANALYZER_NONNULL = YES; 375 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 376 | CLANG_CXX_LIBRARY = "libc++"; 377 | CLANG_ENABLE_MODULES = YES; 378 | CLANG_ENABLE_OBJC_ARC = YES; 379 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 380 | CLANG_WARN_BOOL_CONVERSION = YES; 381 | CLANG_WARN_COMMA = YES; 382 | CLANG_WARN_CONSTANT_CONVERSION = YES; 383 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 384 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 385 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 386 | CLANG_WARN_EMPTY_BODY = YES; 387 | CLANG_WARN_ENUM_CONVERSION = YES; 388 | CLANG_WARN_INFINITE_RECURSION = YES; 389 | CLANG_WARN_INT_CONVERSION = YES; 390 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 391 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 392 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 393 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 394 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 395 | CLANG_WARN_STRICT_PROTOTYPES = YES; 396 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 397 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 398 | CLANG_WARN_UNREACHABLE_CODE = YES; 399 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 400 | CODE_SIGN_IDENTITY = "-"; 401 | COPY_PHASE_STRIP = NO; 402 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 403 | ENABLE_NS_ASSERTIONS = NO; 404 | ENABLE_STRICT_OBJC_MSGSEND = YES; 405 | GCC_C_LANGUAGE_STANDARD = gnu99; 406 | GCC_NO_COMMON_BLOCKS = YES; 407 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 408 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 409 | GCC_WARN_UNDECLARED_SELECTOR = YES; 410 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 411 | GCC_WARN_UNUSED_FUNCTION = YES; 412 | GCC_WARN_UNUSED_VARIABLE = YES; 413 | MACOSX_DEPLOYMENT_TARGET = 10.11; 414 | MTL_ENABLE_DEBUG_INFO = NO; 415 | SDKROOT = macosx; 416 | }; 417 | name = Release; 418 | }; 419 | 559B23F01D7EBDA300937AB3 /* Debug */ = { 420 | isa = XCBuildConfiguration; 421 | baseConfigurationReference = 55BCFFF71D801362000EDB05 /* config.xcconfig */; 422 | buildSettings = { 423 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 424 | CODE_SIGN_ENTITLEMENTS = XcodeClangFormat/XcodeClangFormat.entitlements; 425 | CODE_SIGN_IDENTITY = "Mac Developer"; 426 | COMBINE_HIDPI_IMAGES = YES; 427 | DEVELOPMENT_TEAM = ""; 428 | ENABLE_HARDENED_RUNTIME = YES; 429 | INFOPLIST_FILE = XcodeClangFormat/Info.plist; 430 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 431 | MARKETING_VERSION = 1.2.1; 432 | PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.XcodeClangFormat; 433 | PRODUCT_NAME = "$(TARGET_NAME)"; 434 | }; 435 | name = Debug; 436 | }; 437 | 559B23F11D7EBDA300937AB3 /* Release */ = { 438 | isa = XCBuildConfiguration; 439 | baseConfigurationReference = 55BCFFF71D801362000EDB05 /* config.xcconfig */; 440 | buildSettings = { 441 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 442 | CODE_SIGN_ENTITLEMENTS = XcodeClangFormat/XcodeClangFormat.entitlements; 443 | CODE_SIGN_IDENTITY = "Mac Developer"; 444 | COMBINE_HIDPI_IMAGES = YES; 445 | DEVELOPMENT_TEAM = ""; 446 | ENABLE_HARDENED_RUNTIME = YES; 447 | INFOPLIST_FILE = XcodeClangFormat/Info.plist; 448 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 449 | MARKETING_VERSION = 1.2.1; 450 | PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.XcodeClangFormat; 451 | PRODUCT_NAME = "$(TARGET_NAME)"; 452 | }; 453 | name = Release; 454 | }; 455 | 559B241F1D7EBDC400937AB3 /* Debug */ = { 456 | isa = XCBuildConfiguration; 457 | baseConfigurationReference = 55BCFFF71D801362000EDB05 /* config.xcconfig */; 458 | buildSettings = { 459 | CODE_SIGN_ENTITLEMENTS = "clang-format/clang_format.entitlements"; 460 | CODE_SIGN_IDENTITY = "Mac Developer"; 461 | COMBINE_HIDPI_IMAGES = YES; 462 | DEAD_CODE_STRIPPING = YES; 463 | DEVELOPMENT_TEAM = ""; 464 | ENABLE_HARDENED_RUNTIME = YES; 465 | GCC_ENABLE_CPP_EXCEPTIONS = NO; 466 | GCC_ENABLE_CPP_RTTI = NO; 467 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 468 | GCC_OPTIMIZATION_LEVEL = 3; 469 | GCC_SYMBOLS_PRIVATE_EXTERN = YES; 470 | INFOPLIST_FILE = "clang-format/Info.plist"; 471 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks"; 472 | MACOSX_DEPLOYMENT_TARGET = 10.11; 473 | MARKETING_VERSION = 1.2.1; 474 | OTHER_CPLUSPLUSFLAGS = ( 475 | "--system-header-prefix=$(LLVM_INCLUDE_DIR)", 476 | "$(LLVM_CXXFLAGS)", 477 | "$(OTHER_CFLAGS)", 478 | ); 479 | OTHER_LDFLAGS = ( 480 | "$(LLVM_LIBDIR)/libclangFormat.a", 481 | "$(LLVM_LIBDIR)/libclangToolingCore.a", 482 | "$(LLVM_LIBDIR)/libclangToolingInclusions.a", 483 | "$(LLVM_LIBDIR)/libclangLex.a", 484 | "$(LLVM_LIBDIR)/libclangBasic.a", 485 | "$(LLVM_LIBDIR)/libclangRewrite.a", 486 | "$(LLVM_LIBDIR)/libLLVMCore.a", 487 | "$(LLVM_LIBDIR)/libLLVMBinaryFormat.a", 488 | "$(LLVM_LIBDIR)/libLLVMSupport.a", 489 | "$(LLVM_LIBDIR)/libLLVMDemangle.a", 490 | "$(LLVM_LIBDIR)/libLLVMRemarks.a", 491 | "$(LLVM_LIBDIR)/libLLVMBitstreamReader.a", 492 | ); 493 | PRODUCT_BUNDLE_IDENTIFIER = "com.mapbox.XcodeClangFormat.clang-format"; 494 | PRODUCT_NAME = "$(TARGET_NAME)"; 495 | SKIP_INSTALL = YES; 496 | STRIP_STYLE = all; 497 | }; 498 | name = Debug; 499 | }; 500 | 559B24201D7EBDC400937AB3 /* Release */ = { 501 | isa = XCBuildConfiguration; 502 | baseConfigurationReference = 55BCFFF71D801362000EDB05 /* config.xcconfig */; 503 | buildSettings = { 504 | CODE_SIGN_ENTITLEMENTS = "clang-format/clang_format.entitlements"; 505 | CODE_SIGN_IDENTITY = "Mac Developer"; 506 | COMBINE_HIDPI_IMAGES = YES; 507 | DEAD_CODE_STRIPPING = YES; 508 | DEVELOPMENT_TEAM = ""; 509 | ENABLE_HARDENED_RUNTIME = YES; 510 | GCC_ENABLE_CPP_EXCEPTIONS = NO; 511 | GCC_ENABLE_CPP_RTTI = NO; 512 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 513 | GCC_OPTIMIZATION_LEVEL = 3; 514 | GCC_SYMBOLS_PRIVATE_EXTERN = YES; 515 | INFOPLIST_FILE = "clang-format/Info.plist"; 516 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks"; 517 | MACOSX_DEPLOYMENT_TARGET = 10.11; 518 | MARKETING_VERSION = 1.2.1; 519 | OTHER_CPLUSPLUSFLAGS = ( 520 | "--system-header-prefix=$(LLVM_INCLUDE_DIR)", 521 | "$(LLVM_CXXFLAGS)", 522 | "$(OTHER_CFLAGS)", 523 | ); 524 | OTHER_LDFLAGS = ( 525 | "$(LLVM_LIBDIR)/libclangFormat.a", 526 | "$(LLVM_LIBDIR)/libclangToolingCore.a", 527 | "$(LLVM_LIBDIR)/libclangToolingInclusions.a", 528 | "$(LLVM_LIBDIR)/libclangLex.a", 529 | "$(LLVM_LIBDIR)/libclangBasic.a", 530 | "$(LLVM_LIBDIR)/libclangRewrite.a", 531 | "$(LLVM_LIBDIR)/libLLVMCore.a", 532 | "$(LLVM_LIBDIR)/libLLVMBinaryFormat.a", 533 | "$(LLVM_LIBDIR)/libLLVMSupport.a", 534 | "$(LLVM_LIBDIR)/libLLVMDemangle.a", 535 | "$(LLVM_LIBDIR)/libLLVMRemarks.a", 536 | "$(LLVM_LIBDIR)/libLLVMBitstreamReader.a", 537 | ); 538 | PRODUCT_BUNDLE_IDENTIFIER = "com.mapbox.XcodeClangFormat.clang-format"; 539 | PRODUCT_NAME = "$(TARGET_NAME)"; 540 | SKIP_INSTALL = YES; 541 | STRIP_STYLE = all; 542 | }; 543 | name = Release; 544 | }; 545 | /* End XCBuildConfiguration section */ 546 | 547 | /* Begin XCConfigurationList section */ 548 | 559B23D91D7EBDA300937AB3 /* Build configuration list for PBXProject "XcodeClangFormat" */ = { 549 | isa = XCConfigurationList; 550 | buildConfigurations = ( 551 | 559B23ED1D7EBDA300937AB3 /* Debug */, 552 | 559B23EE1D7EBDA300937AB3 /* Release */, 553 | ); 554 | defaultConfigurationIsVisible = 0; 555 | defaultConfigurationName = Release; 556 | }; 557 | 559B23EF1D7EBDA300937AB3 /* Build configuration list for PBXNativeTarget "XcodeClangFormat" */ = { 558 | isa = XCConfigurationList; 559 | buildConfigurations = ( 560 | 559B23F01D7EBDA300937AB3 /* Debug */, 561 | 559B23F11D7EBDA300937AB3 /* Release */, 562 | ); 563 | defaultConfigurationIsVisible = 0; 564 | defaultConfigurationName = Release; 565 | }; 566 | 559B241E1D7EBDC400937AB3 /* Build configuration list for PBXNativeTarget "clang-format" */ = { 567 | isa = XCConfigurationList; 568 | buildConfigurations = ( 569 | 559B241F1D7EBDC400937AB3 /* Debug */, 570 | 559B24201D7EBDC400937AB3 /* Release */, 571 | ); 572 | defaultConfigurationIsVisible = 0; 573 | defaultConfigurationName = Release; 574 | }; 575 | /* End XCConfigurationList section */ 576 | }; 577 | rootObject = 559B23D61D7EBDA300937AB3 /* Project object */; 578 | } 579 | -------------------------------------------------------------------------------- /XcodeClangFormat.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /XcodeClangFormat.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /XcodeClangFormat.xcodeproj/xcshareddata/xcschemes/XcodeClangFormat.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /XcodeClangFormat.xcodeproj/xcshareddata/xcschemes/clang-format.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 16 | 22 | 23 | 24 | 30 | 36 | 37 | 38 | 39 | 40 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 70 | 74 | 75 | 76 | 82 | 83 | 84 | 85 | 92 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /XcodeClangFormat/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface AppDelegate : NSObject 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /XcodeClangFormat/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @interface AppDelegate () 4 | 5 | @property(weak) IBOutlet NSWindow* window; 6 | @property(weak) IBOutlet NSButton* llvmStyle; 7 | @property(weak) IBOutlet NSButton* googleStyle; 8 | @property(weak) IBOutlet NSButton* chromiumStyle; 9 | @property(weak) IBOutlet NSButton* mozillaStyle; 10 | @property(weak) IBOutlet NSButton* webkitStyle; 11 | @property(weak) IBOutlet NSButton* customStyle; 12 | @property(weak) IBOutlet NSPathControl* primaryPathControl; 13 | @property(weak) IBOutlet NSPathControl* secondaryPathControl; 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | NSUserDefaults* defaults = nil; 19 | 20 | - (void)applicationWillFinishLaunching:(NSNotification*)notification { 21 | defaults = [[NSUserDefaults alloc] initWithSuiteName:@"XcodeClangFormat"]; 22 | 23 | NSString* style = [defaults stringForKey:@"style"]; 24 | if (!style) { 25 | style = @"llvm"; 26 | } 27 | 28 | if ([style isEqualToString:@"custom"]) { 29 | self.customStyle.state = NSOnState; 30 | } else if ([style isEqualToString:@"google"]) { 31 | self.googleStyle.state = NSOnState; 32 | } else if ([style isEqualToString:@"chromium"]) { 33 | self.chromiumStyle.state = NSOnState; 34 | } else if ([style isEqualToString:@"mozilla"]) { 35 | self.mozillaStyle.state = NSOnState; 36 | } else if ([style isEqualToString:@"webkit"]) { 37 | self.webkitStyle.state = NSOnState; 38 | } else { 39 | self.llvmStyle.state = NSOnState; 40 | } 41 | 42 | NSData* bookmark = [defaults dataForKey:@"file"]; 43 | if (bookmark) { 44 | NSError* error = nil; 45 | BOOL stale = NO; 46 | NSURL* url = [NSURL URLByResolvingBookmarkData:bookmark 47 | options:NSURLBookmarkResolutionWithSecurityScope | 48 | NSURLBookmarkResolutionWithoutUI 49 | relativeToURL:nil 50 | bookmarkDataIsStale:&stale 51 | error:&error]; 52 | 53 | if (url) { 54 | // Regenerate the bookmark, so that the extension can read a valid bookmark after a 55 | // system restart. 56 | [url startAccessingSecurityScopedResource]; 57 | NSData* regularBookmark = [url bookmarkDataWithOptions:0 58 | includingResourceValuesForKeys:nil 59 | relativeToURL:nil 60 | error:nil]; 61 | [url stopAccessingSecurityScopedResource]; 62 | [defaults setObject:regularBookmark forKey:@"regularBookmark"]; 63 | 64 | self.primaryPathControl.URL = url; 65 | self.secondaryPathControl.URL = url; 66 | } else { 67 | // Remove the bookmark value from the storage 68 | [defaults setNilValueForKey:@"regularBookmark"]; 69 | } 70 | [defaults synchronize]; 71 | } 72 | } 73 | 74 | - (BOOL)application:(NSApplication*)application openFile:(NSString*)filename { 75 | NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@", filename]]; 76 | return [self selectURL:url]; 77 | } 78 | 79 | - (IBAction)chooseStyle:(id)sender { 80 | NSString* style = nil; 81 | if (sender == self.customStyle) { 82 | style = @"custom"; 83 | } else if (sender == self.googleStyle) { 84 | style = @"google"; 85 | } else if (sender == self.chromiumStyle) { 86 | style = @"chromium"; 87 | } else if (sender == self.mozillaStyle) { 88 | style = @"mozilla"; 89 | } else if (sender == self.webkitStyle) { 90 | style = @"webkit"; 91 | } else { 92 | style = @"llvm"; 93 | } 94 | 95 | [defaults setValue:style forKey:@"style"]; 96 | [defaults synchronize]; 97 | } 98 | 99 | - (void)pathControl:(NSPathControl*)pathControl willDisplayOpenPanel:(NSOpenPanel*)openPanel { 100 | openPanel.title = @"Choose custom .clang-format file"; 101 | openPanel.canChooseFiles = YES; 102 | openPanel.canChooseDirectories = YES; 103 | openPanel.showsHiddenFiles = YES; 104 | openPanel.treatsFilePackagesAsDirectories = YES; 105 | openPanel.allowsMultipleSelection = NO; 106 | } 107 | 108 | - (NSURL*)findClangFormatFileFromURL:(NSURL*)url { 109 | NSNumber* isDirectory; 110 | BOOL success = [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil]; 111 | if (success && [isDirectory boolValue]) { 112 | return [url URLByAppendingPathComponent:@".clang-format"]; 113 | } else { 114 | return url; 115 | } 116 | } 117 | 118 | - (NSData*)tryCreateBookmarkFromURL:(NSURL*)url { 119 | // Create a bookmark and store into defaults. 120 | NSError* error = nil; 121 | return [url bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope | 122 | NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess 123 | includingResourceValuesForKeys:nil 124 | relativeToURL:nil 125 | error:&error]; 126 | } 127 | 128 | - (NSDragOperation)pathControl:(NSPathControl*)pathControl validateDrop:(id)info { 129 | NSPasteboard* pastboard = [info draggingPasteboard]; 130 | NSURL* url = [self findClangFormatFileFromURL:[NSURL URLFromPasteboard:pastboard]]; 131 | NSData* bookmark = [self tryCreateBookmarkFromURL:url]; 132 | if (bookmark) { 133 | return NSDragOperationCopy; 134 | } else { 135 | return NSDragOperationNone; 136 | } 137 | } 138 | 139 | - (IBAction)selectFile:(id)sender { 140 | NSURL* url = [self findClangFormatFileFromURL:self.primaryPathControl.URL]; 141 | [self selectURL:url]; 142 | } 143 | 144 | - (BOOL)selectURL:(NSURL*)url { 145 | NSData* bookmark = [self tryCreateBookmarkFromURL:url]; 146 | 147 | if (bookmark == nil) { 148 | return NO; 149 | } else { 150 | self.primaryPathControl.URL = url; 151 | self.secondaryPathControl.URL = url; 152 | self.customStyle.state = NSOnState; 153 | 154 | [defaults setValue:@"custom" forKey:@"style"]; 155 | [defaults setObject:bookmark forKey:@"file"]; 156 | 157 | NSData* regularBookmark = [url bookmarkDataWithOptions:0 158 | includingResourceValuesForKeys:nil 159 | relativeToURL:nil 160 | error:nil]; 161 | [defaults setObject:regularBookmark forKey:@"regularBookmark"]; 162 | [defaults synchronize]; 163 | return YES; 164 | } 165 | } 166 | 167 | @end 168 | -------------------------------------------------------------------------------- /XcodeClangFormat/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 | } -------------------------------------------------------------------------------- /XcodeClangFormat/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /XcodeClangFormat/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 95 | 106 | 117 | 128 | 139 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /XcodeClangFormat/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDocumentTypes 8 | 9 | 10 | CFBundleTypeExtensions 11 | 12 | clang-format 13 | 14 | CFBundleTypeName 15 | clang-format Style 16 | CFBundleTypeRole 17 | Viewer 18 | 19 | 20 | CFBundleExecutable 21 | $(EXECUTABLE_NAME) 22 | CFBundleIconFile 23 | 24 | CFBundleIdentifier 25 | $(PRODUCT_BUNDLE_IDENTIFIER) 26 | CFBundleInfoDictionaryVersion 27 | 6.0 28 | CFBundleName 29 | $(PRODUCT_NAME) 30 | CFBundlePackageType 31 | APPL 32 | CFBundleShortVersionString 33 | $(MARKETING_VERSION) 34 | CFBundleVersion 35 | 1 36 | LSMinimumSystemVersion 37 | $(MACOSX_DEPLOYMENT_TARGET) 38 | NSHumanReadableCopyright 39 | Copyright © 2020 Mapbox. All rights reserved. 40 | NSMainNibFile 41 | MainMenu 42 | NSPrincipalClass 43 | NSApplication 44 | 45 | 46 | -------------------------------------------------------------------------------- /XcodeClangFormat/XcodeClangFormat.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.application-groups 8 | 9 | XcodeClangFormat 10 | 11 | com.apple.security.files.bookmarks.app-scope 12 | 13 | com.apple.security.files.user-selected.read-only 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /XcodeClangFormat/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // XcodeClangFormat 4 | // 5 | // Created by Konstantin Käfer on 06.09.2016. 6 | // Copyright © 2016 Mapbox. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | -------------------------------------------------------------------------------- /clang-format/ClangFormat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma clang system_header 4 | 5 | #include 6 | -------------------------------------------------------------------------------- /clang-format/ClangFormatCommand.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface ClangFormatCommand : NSObject 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /clang-format/ClangFormatCommand.mm: -------------------------------------------------------------------------------- 1 | #import "ClangFormatCommand.h" 2 | 3 | #import 4 | 5 | #include "ClangFormat.h" 6 | 7 | // Generates a list of offsets for ever line in the array. 8 | void updateOffsets(std::vector& offsets, NSMutableArray* lines) { 9 | offsets.clear(); 10 | offsets.reserve(lines.count + 2); 11 | offsets.push_back(0); 12 | size_t offset = 0; 13 | for (NSString* line in lines) { 14 | offsets.push_back(offset += [line lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); 15 | } 16 | offsets.push_back(offset); 17 | } 18 | 19 | clang::format::FormatStyle::LanguageKind getLanguageKind(XCSourceTextBuffer* buffer) { 20 | CFStringRef uti = (__bridge CFStringRef)buffer.contentUTI; 21 | if (UTTypeEqual(uti, kUTTypeCHeader)) { 22 | // C header files could also be Objective-C. We attempt to detect typical Objective-C keywords. 23 | for (NSString* line in buffer.lines) { 24 | if ([line hasPrefix:@"#import"] || [line hasPrefix:@"@interface"] || [line hasPrefix:@"@protocol"] || 25 | [line hasPrefix:@"@property"] || [line hasPrefix:@"@end"]) { 26 | return clang::format::FormatStyle::LK_ObjC; 27 | } 28 | } 29 | } 30 | if (UTTypeEqual(uti, kUTTypeCPlusPlusHeader) || UTTypeEqual(uti, kUTTypeCPlusPlusSource) || 31 | UTTypeEqual(uti, kUTTypeCHeader) || UTTypeEqual(uti, kUTTypeCSource)) { 32 | return clang::format::FormatStyle::LK_Cpp; 33 | } else if (UTTypeEqual(uti, kUTTypeObjectiveCSource) || 34 | UTTypeEqual(uti, kUTTypeObjectiveCPlusPlusSource)) { 35 | return clang::format::FormatStyle::LK_ObjC; 36 | } else if (UTTypeEqual(uti, kUTTypeJavaSource)) { 37 | return clang::format::FormatStyle::LK_Java; 38 | } else if (UTTypeEqual(uti, kUTTypeJavaScript)) { 39 | return clang::format::FormatStyle::LK_JavaScript; 40 | } 41 | 42 | return clang::format::FormatStyle::LK_None; 43 | } 44 | 45 | NSErrorDomain errorDomain = @"ClangFormatError"; 46 | 47 | @implementation ClangFormatCommand 48 | 49 | NSUserDefaults* defaults = nil; 50 | NSString* kFormatSelectionCommandIdentifier = [NSString stringWithFormat:@"%@.FormatSelection", [[NSBundle mainBundle] bundleIdentifier]]; 51 | NSString* kFormatFileCommandIdentifier = [NSString stringWithFormat:@"%@.FormatFile", [[NSBundle mainBundle] bundleIdentifier]]; 52 | 53 | - (NSData*)getCustomStyle { 54 | // First, read the regular bookmark because it could've been changed by the wrapper app. 55 | NSData* regularBookmark = [defaults dataForKey:@"regularBookmark"]; 56 | NSURL* regularURL = nil; 57 | BOOL regularStale = NO; 58 | if (regularBookmark) { 59 | regularURL = [NSURL URLByResolvingBookmarkData:regularBookmark 60 | options:NSURLBookmarkResolutionWithoutUI 61 | relativeToURL:nil 62 | bookmarkDataIsStale:®ularStale 63 | error:nil]; 64 | } 65 | 66 | if (!regularURL) { 67 | return nil; 68 | } 69 | 70 | // Then read the security URL, which is the URL we're actually going to use to access the file. 71 | NSData* securityBookmark = [defaults dataForKey:@"securityBookmark"]; 72 | NSURL* securityURL = nil; 73 | BOOL securityStale = NO; 74 | if (securityBookmark) { 75 | securityURL = [NSURL URLByResolvingBookmarkData:securityBookmark 76 | options:NSURLBookmarkResolutionWithSecurityScope | 77 | NSURLBookmarkResolutionWithoutUI 78 | relativeToURL:nil 79 | bookmarkDataIsStale:&securityStale 80 | error:nil]; 81 | } 82 | 83 | // Clear out the security URL if it's no longer matching the regular URL. 84 | if (securityStale == YES || 85 | (securityURL && ![[securityURL path] isEqualToString:[regularURL path]])) { 86 | securityURL = nil; 87 | } 88 | 89 | if (!securityURL && regularStale == NO) { 90 | // Attempt to create new security URL from the regular URL to persist across system reboots. 91 | NSError* error = nil; 92 | securityBookmark = [regularURL 93 | bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope | 94 | NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess 95 | includingResourceValuesForKeys:nil 96 | relativeToURL:nil 97 | error:&error]; 98 | [defaults setObject:securityBookmark forKey:@"securityBookmark"]; 99 | securityURL = regularURL; 100 | } 101 | 102 | if (securityURL) { 103 | // Finally, attempt to read the .clang-format file 104 | NSError* error = nil; 105 | [securityURL startAccessingSecurityScopedResource]; 106 | NSData* data = [NSData dataWithContentsOfURL:securityURL options:0 error:&error]; 107 | [securityURL stopAccessingSecurityScopedResource]; 108 | if (error) { 109 | NSLog(@"Error loading from security bookmark: %@", error); 110 | } else if (data) { 111 | return data; 112 | } 113 | } 114 | 115 | return nil; 116 | } 117 | 118 | - (void)performCommandWithInvocation:(XCSourceEditorCommandInvocation*)invocation 119 | completionHandler:(void (^)(NSError* _Nullable nilOrError))completionHandler { 120 | if (!defaults) { 121 | defaults = [[NSUserDefaults alloc] initWithSuiteName:@"XcodeClangFormat"]; 122 | } 123 | 124 | const auto language = getLanguageKind(invocation.buffer); 125 | 126 | NSString* style = [defaults stringForKey:@"style"]; 127 | if (!style) { 128 | style = @"llvm"; 129 | } 130 | 131 | clang::format::FormatStyle format = clang::format::getNoStyle(); 132 | if ([style isEqualToString:@"custom"]) { 133 | NSData* config = [self getCustomStyle]; 134 | if (!config) { 135 | completionHandler([NSError 136 | errorWithDomain:errorDomain 137 | code:0 138 | userInfo:@{ 139 | NSLocalizedDescriptionKey : 140 | @"Could not load custom style. Please open XcodeClangFormat.app" 141 | }]); 142 | } else { 143 | // parse style 144 | llvm::StringRef configString(reinterpret_cast(config.bytes), 145 | config.length); 146 | clang::format::getPredefinedStyle("LLVM", language, &format); 147 | auto error = clang::format::parseConfiguration(configString, &format); 148 | if (error) { 149 | completionHandler([NSError 150 | errorWithDomain:errorDomain 151 | code:0 152 | userInfo:@{ 153 | NSLocalizedDescriptionKey : 154 | [NSString stringWithFormat:@"Could not parse custom style: %s.", 155 | error.message().c_str()] 156 | }]); 157 | return; 158 | } 159 | } 160 | } else { 161 | auto success = clang::format::getPredefinedStyle( 162 | llvm::StringRef([style cStringUsingEncoding:NSUTF8StringEncoding]), language, &format); 163 | if (!success) { 164 | completionHandler([NSError 165 | errorWithDomain:errorDomain 166 | code:0 167 | userInfo:@{ 168 | NSLocalizedDescriptionKey : [NSString 169 | stringWithFormat:@"Could not parse default style %@", style] 170 | }]); 171 | return; 172 | } 173 | } 174 | 175 | NSData* buffer = [invocation.buffer.completeBuffer dataUsingEncoding:NSUTF8StringEncoding]; 176 | NSMutableArray* lines = invocation.buffer.lines; 177 | llvm::StringRef code(reinterpret_cast(buffer.bytes), buffer.length); 178 | 179 | std::vector offsets; 180 | updateOffsets(offsets, lines); 181 | 182 | std::vector ranges; 183 | 184 | if ([invocation.commandIdentifier isEqualToString:kFormatSelectionCommandIdentifier]) { 185 | for (XCSourceTextRange* range in invocation.buffer.selections) { 186 | const size_t start = offsets[range.start.line] + range.start.column; 187 | const size_t end = offsets[range.end.line] + range.end.column; 188 | ranges.emplace_back(start, end - start); 189 | } 190 | } else if ([invocation.commandIdentifier isEqualToString:kFormatFileCommandIdentifier]) { 191 | ranges.emplace_back(0, code.size()); 192 | } else { 193 | completionHandler([NSError 194 | errorWithDomain:errorDomain 195 | code:0 196 | userInfo:@{ 197 | NSLocalizedDescriptionKey : @"Unknown command" 198 | }]); 199 | return; 200 | } 201 | 202 | // Calculated replacements and apply them to the input buffer. 203 | const llvm::StringRef filename(""); 204 | clang::format::FormattingAttemptStatus status; 205 | auto replaces = clang::format::reformat(format.GetLanguageStyle(language).getValueOr(format), code, ranges, filename, &status); 206 | 207 | if (!status.FormatComplete) { 208 | // We could not apply the calculated replacements. 209 | completionHandler([NSError 210 | errorWithDomain:errorDomain 211 | code:0 212 | userInfo:@{ 213 | NSLocalizedDescriptionKey : [NSString 214 | stringWithFormat: 215 | @"Could not complete formatting due to a syntax error on line %u", 216 | status.Line] 217 | }]); 218 | return; 219 | } 220 | 221 | for (auto it = replaces.rbegin(), rend = replaces.rend(); it != rend; ++it) { 222 | const size_t start = it->getOffset(); 223 | const size_t end = start + it->getLength(); 224 | const auto replacement = it->getReplacementText(); 225 | 226 | // In offsets, find the value that is smaller than start. 227 | auto start_it = std::lower_bound(offsets.begin(), offsets.end(), start); 228 | auto end_it = std::lower_bound(offsets.begin(), offsets.end(), end); 229 | if (start_it == offsets.end() || end_it == offsets.end()) { 230 | continue; 231 | } 232 | 233 | // We're adding a final offset index that is the position beyond the last byte. 234 | assert(end_it + 1 != offsets.end()); 235 | 236 | // We need to go one line back unless we're at the beginning of the line. 237 | if (*start_it > start) { 238 | --start_it; 239 | } 240 | if (*end_it > end) { 241 | --end_it; 242 | } 243 | 244 | const size_t start_line = std::distance(offsets.begin(), start_it); 245 | const int64_t start_column = int64_t(start) - int64_t(*start_it); 246 | assert(start_column >= 0); 247 | 248 | const size_t end_line = std::distance(offsets.begin(), end_it); 249 | const int64_t end_column = int64_t(end) - int64_t(*end_it); 250 | assert(end_column >= 0); 251 | NSData* before_line = [[lines objectAtIndex:start_line] dataUsingEncoding:NSUTF8StringEncoding]; 252 | NSData* after_line = [[lines objectAtIndex:end_line] dataUsingEncoding:NSUTF8StringEncoding]; 253 | NSMutableData* replacement_data = [[NSMutableData alloc] initWithBytes:before_line.bytes length:start_column]; 254 | [replacement_data appendBytes:replacement.data() length:replacement.size()]; 255 | [replacement_data appendBytes:(reinterpret_cast(after_line.bytes) + end_column) length: (after_line.length - end_column)]; 256 | 257 | NSString* string = [[NSString alloc] initWithData:replacement_data encoding:NSUTF8StringEncoding]; 258 | NSMutableArray* replacements = [[NSMutableArray alloc] init]; 259 | [string 260 | enumerateSubstringsInRange:NSMakeRange(0, string.length) 261 | options:NSStringEnumerationByLines 262 | usingBlock:^(NSString* _Nullable, 263 | NSRange, 264 | NSRange enclosingRange, 265 | BOOL* _Nonnull) { 266 | [replacements addObject:[string substringWithRange:enclosingRange]]; 267 | }]; 268 | 269 | NSRange range = 270 | NSMakeRange(start_line, end_line - start_line + (end_line < lines.count ? 1 : 0)); 271 | [lines replaceObjectsInRange:range withObjectsFromArray:replacements]; 272 | } 273 | 274 | completionHandler(nil); 275 | } 276 | 277 | @end 278 | -------------------------------------------------------------------------------- /clang-format/ClangFormatExtension.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface ClangFormatExtension : NSObject 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /clang-format/ClangFormatExtension.m: -------------------------------------------------------------------------------- 1 | #import "ClangFormatExtension.h" 2 | 3 | @implementation ClangFormatExtension 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /clang-format/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | clang-format 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 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | XCSourceEditorCommandDefinitions 30 | 31 | 32 | XCSourceEditorCommandClassName 33 | ClangFormatCommand 34 | XCSourceEditorCommandIdentifier 35 | $(PRODUCT_BUNDLE_IDENTIFIER).FormatSelection 36 | XCSourceEditorCommandName 37 | Format Selection 38 | 39 | 40 | XCSourceEditorCommandClassName 41 | ClangFormatCommand 42 | XCSourceEditorCommandIdentifier 43 | $(PRODUCT_BUNDLE_IDENTIFIER).FormatFile 44 | XCSourceEditorCommandName 45 | Format Entire File 46 | 47 | 48 | XCSourceEditorExtensionPrincipalClass 49 | ClangFormatExtension 50 | 51 | NSExtensionPointIdentifier 52 | com.apple.dt.Xcode.extension.source-editor 53 | 54 | NSHumanReadableCopyright 55 | Copyright © 2020 Mapbox. All rights reserved. 56 | 57 | 58 | -------------------------------------------------------------------------------- /clang-format/clang_format.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.files.user-selected.read-only 6 | 7 | com.apple.security.files.bookmarks.app-scope 8 | 9 | com.apple.security.app-sandbox 10 | 11 | com.apple.security.application-groups 12 | 13 | XcodeClangFormat 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -o pipefail 5 | set -u 6 | 7 | LLVM_VERSION=10.0.0 8 | LLVM_HASH=70a7d5ed3bb16a5b5310ea4bfe95a74894022a43abb96d28ef8e30ab1f41d47a 9 | LLVM_CONFIG=${LLVM_CONFIG:-llvm-config} 10 | 11 | command -v "${LLVM_CONFIG}" >/dev/null 2>&1 || { 12 | PREFIX="deps/clang-${LLVM_VERSION}" 13 | if [ ! -f "${PREFIX}/bin/llvm-config" ]; then 14 | mkdir -p "deps" 15 | FILE="deps/clang-${LLVM_VERSION}.tar.xz" 16 | if [ ! -f "${FILE}" ]; then 17 | URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/clang+llvm-${LLVM_VERSION}-x86_64-apple-darwin.tar.xz" 18 | echo "Downloading ${URL}..." 19 | curl --retry 3 -# -S -L "${URL}" -o "${FILE}.tmp" && mv "${FILE}.tmp" "${FILE}" 20 | fi 21 | echo -n "Checking file... " 22 | echo "${LLVM_HASH} ${FILE}" | shasum -a 512256 -c 23 | rm -rf "${PREFIX}" 24 | mkdir -p "${PREFIX}" 25 | echo -n "Unpacking archive... " 26 | tar xf "${FILE}" -C "${PREFIX}" --strip-components 1 27 | echo "done." 28 | fi 29 | LLVM_CONFIG="${PREFIX}/bin/llvm-config" 30 | } 31 | 32 | PREFIX="$("${LLVM_CONFIG}" --prefix)" 33 | case "${PREFIX}" in 34 | *\ *) (>&2 echo "Error: Path to LLVM may not contain spaces: '${PREFIX}'"); exit 1 ;; 35 | esac 36 | 37 | echo "// Do not modify this file. Instead, rerun ./configure" > config.xcconfig 38 | echo "LLVM_LIBDIR=$(${LLVM_CONFIG} --libdir)" >> config.xcconfig 39 | echo "LLVM_INCLUDE_DIR=$(${LLVM_CONFIG} --includedir)" >> config.xcconfig 40 | echo "LLVM_CXXFLAGS=$(${LLVM_CONFIG} --cxxflags)" >> config.xcconfig 41 | 42 | echo "Wrote config.xcconfig." 43 | 44 | open XcodeClangFormat.xcodeproj 45 | -------------------------------------------------------------------------------- /screenshot-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/XcodeClangFormat/5eae1702f77a9e1c58640971e28a0f5f3795ba9c/screenshot-config.png -------------------------------------------------------------------------------- /screenshot-extensions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/XcodeClangFormat/5eae1702f77a9e1c58640971e28a0f5f3795ba9c/screenshot-extensions.png -------------------------------------------------------------------------------- /screenshot-format.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/XcodeClangFormat/5eae1702f77a9e1c58640971e28a0f5f3795ba9c/screenshot-format.png -------------------------------------------------------------------------------- /screenshot-shortcut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/XcodeClangFormat/5eae1702f77a9e1c58640971e28a0f5f3795ba9c/screenshot-shortcut.png --------------------------------------------------------------------------------