XCode provides several ways to make your work easier by cutting down on repetitive typing. The simplest (from a usage standpoint) is text macros. You simply type an abbreviation and hit Escape to substitute it. A text macro can have variable substitutions where you can add text.
I’ve seen a few contradictory articles telling how to add your own text macros, which don’t work in XCode 3.1, but here’s how I was able to get it to work.
First, open /Developer/Applications/Xcode.app/Contents/PlugIns/ and look for TextMacros.xctxtmacro. Make a copy of TextMacros.xctxtmacro and place it in ~/Library/Application Support/Developer/Shared/XCode/Specifications. You may need to create the Specifications folder if it doesn’t exist.
In the copy of TextMacros.xctxtmacro, go to Contents/Resources and edit any of the .xctxtmacro files such as C.xctxtmacro (anything defined there also works in C++ and Objective-C). Any changes here will override the version in XCode. If you only modify one of the macro files, you can delete the others from the copy.
My development team is supposed to add a standard copyright header to each source file. I created a macro that allows me to type ‘stdcopy’ and have it expand to the entire header, with highlighted items that I can tab to and add text. I also added a ‘history’ macro which adds a history comment below the standard copyright block.
For those two macros, I added the following definitions to C.xctxtmacro:
{
Identifier = c.stdcopy;
BasedOn = c;
IsMenuItem = YES;
Name = "Standard Copyright Header";
TextString = "//---------------------------------------------------------------------\n// Copyright (c) $(YEAR) $(ORGANIZATIONNAME). All rights reserved.\n// Reproduction or transmission in whole or in part, in any form or\n// by any means, electronic, mechanical or otherwise, is prohibited\n// without the prior written consent of the copyright owner.\n//\n// < #summary#>\n//\n// < #remarks#>\n//\n// Date\t\t\tRelease\t\t\tTask\t\tWho\t\tSummary\n// =====================================================================\n// < #date#>\t\t< #release#>\t\t< #task#>\t\t< #who#>\t\t< #summary#>\n//---------------------------------------------------------------------\n";
CompletionPrefix = stdcopy;
IncludeContexts = ( "xcode.lang.c", "xcode.lang.java" ); // this works in Java too
},
{
Identifier = c.history;
BasedOn = c;
IsMenuItem = YES;
Name = "History Comment";
TextString="// < #date#>\t\t< #release#>\t\t< #task#>\t\t< #who#>\t\t< #summary#>\n";
CompletionPrefix = history;
IncludeContents = ( "xcode.lang.c", "xcode.lang.java" );
},
Scripts, which are listed in the script menu, are more powerful & flexible since they can use shell scripts, AppleScript, Perl, Ruby, or any other scripting language.
Since I’m working with CFPlugin bundles, I need to deal with UUIDs. In most cases, you would use CFUUIDGetConstantUUIDWithBytes to specify a UUID, which requires a list of byte values. The shell command ‘uuidgen’ returns a string, so converting it for use with CFUUIDGetConstantUUIDWithBytes involves some tedious editing. With a script, you can simply insert the properly formatted UUID byte values.
Here’s my ‘Insert UUID as bytes’ script:
#! /usr/bin/perl -w
my $re = "\(..\)\(..\)\(..\)\(..\)-\(..\)\(..\)-\(..\)\(..\)-\(..\)\(..\)-\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\n";
my $uuid = `uuidgen`;
my $bytes = $uuid;
$bytes =~ s/$re/0x$1, 0x$2, 0x$3, 0x$4, 0x$5, 0x$6, 0x$7, 0x$8, 0x$9, 0x$10, 0x$11, 0x$13, 0x$14, 0x$15, 0x$16/;
print "// UUID: ".$uuid;
print "CFUUIDGetConstantUUIDWithBytes(NULL, ".$bytes.")";
I’m sure there’s a more elegant way to do it in a single line of Perl 🙂