Ben Clark's

Website

Xcode's Indentation Failures and Fixes

The Problem

Proper indentation in coding is important. It makes the code much more pleasant to look at and easier to read. That is why I constantly use Xcode's Re-indent command, Editor > Structure > Re-indent (or ctrl I). However, this command adds an indent to HTML tags that do not have a closing tag. Therefore, the <link> and <meta> tags that are common at the top of an HTML document will cause the rest of the document to indent more than necessary.

Xcode makes a similar mistake in JavaScript. When defining a function as the parameter of another function, it will indent much more than is useful. For example, the following code:

    
    $('#myButton').click(function () {
        alert("Hello, World ^_^");
    });
    

Will be automatically indented to this:

    
    $('#myButton').click(function () {
                         alert("Hello, World ^_^");
                         });
    

I could indent each line manually but that is a bit of a pain. A better solution is to edit the .xclangspec files for each language to perform the indentation desired.

The Fix

To fix this, for each language we wish to change, we must edit a few lines its .xclangspec file. I will point out the changes for html.xclangspec and JavaScript.xclangspec. The .xclangspec file for each language is at /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Resources. You will not have permission to edit these files, but we can copy them to a different folder and edit the copy, then move the edited version back to the Resources folder and overwrite the original.

html.xclangspec

Under the section MARK: Entities, below the line Identifier = "xcode.lang.html.entity.start";, within Syntax, and within EntityNameMap add these two lines:

    
    "meta" = "xcode.lang.html.entity.ignore";
    "link" = "xcode.lang.html.entity.ignore";
    "img" = "xcode.lang.html.entity.ignore";
    

This will stop Xcode from adding additional indents after the <link> and <meta> tags.

"meta" = "xcode.lang.html.entity.ignore"; and "link" = "xcode.lang.html.entity.ignore"; are directly below "style" = "xcode.lang.html.entity.style.start";
A screenshot of a correctly edited html.xclangspec file.
JavasScript.xclangspec

For JavaScript we will have to edit a few more lines to force Xcode to indent functions as parameters properly. First below MARK: JavaScript Syntax Coloring, below Identifier = "xcode.lang.javascript.function.closure.declarator";, within Syntax, and within Rules comment out these two lines:

    
    "xcode.lang.javascript.function.name",
    "=",
    

Then, a few lines down, beneath the line Identifier = "xcode.lang.javascript.parenexpr";, within Syntax, and within IncludeRules add the following line:

    
    "xcode.lang.javascript.function.closure",
    

Conclusion

With each edit, I recommend adding a comment stating where you added or commented out a line and why. Also, each Xcode update will overwrite your changes, but if you save a copy of these files, you easily overwrite the updated version with your edited version.