23

Is there a way to edit Xcode's built-in snippets? There is an edit button, but pressing it doesn't seem to allow changing the snippet's text.

Any insight is appreciated.

WrightsCS
  • 50,551
  • 22
  • 134
  • 186
Martin Cote
  • 28,864
  • 15
  • 75
  • 99

6 Answers6

18

You still can't edit the built-in system snippets. You can, however, edit "user" snippets.

The simplest solution in my mind was to create copies of all the default snippets, but modify them so that they are "user" snippets and override the default versions. I wrote a little Python script to do the job. It's very simple, and after running it all of Xcode's snippets will be magically editable via the Xcode GUI. No need to go mucking around in the plist by hand:

import plistlib
import os.path

# Create user snippet directory if needed.
user_snippet_path = os.path.expanduser("~/Library/Developer/Xcode/UserData/CodeSnippets")
try: 
    os.makedirs(user_snippet_path)
except OSError, err:
    if err.errno != errno.EEXIST or not os.path.isdir(user_snippet_path): 
        raise

# Important, you'll need to quit and restart Xcode to notice the effects.
# Important, change this if you're on a Developer Preview of Xcode.
system_snippet_path = "/Applications/Xcode.app/Contents/PlugIns/IDECodeSnippetLibrary.ideplugin/Contents/Resources/SystemCodeSnippets.codesnippets"

print("Reading snippets from " + system_snippet_path)
plist = plistlib.readPlist(system_snippet_path)
for entry in plist:

    # Create a new user snippet file with modified
    # contents of the original snippet. Ignore paths that
    # already contain a user snippet to prevent overwriting
    # previously generated snippets.
    snippet_id = entry["IDECodeSnippetIdentifier"]
    snippet_path = user_snippet_path + "/" + snippet_id + ".codesnippet"
    if os.path.exists(snippet_path):
        print(snippet_path + " already exitsts: Skipping.")
        continue

    print("Writing " + snippet_path)

    # Marks the snippet as a user snippet. Xcode will
    # crash if a user snippet and a system snippet share
    # the same identifier.
    entry["IDECodeSnippetUserSnippet"] = True

    # Given two snippets with the same identifier,
    # Xcode will only show the snippet with the higher
    # "version number". This effectively hides the
    # default version of the snippet.
    entry["IDECodeSnippetVersion"] += 1

    plistlib.writePlist(entry, snippet_path)

print("Done writing snippets.")

You'll notice that it doesn't actually change any of Xcode's internal files. It just adds files, and Xcode is smart enough to use the added files instead of the original snippets. You can roll back to the originals at any time by simply deleting the user version of the snippet. You can also run the script as many times as you want without worrying about overwriting any user snippets generated by previous runs of the script.

Matt Wilding
  • 20,115
  • 3
  • 67
  • 95
  • +1, but there is a bug in your script. I'm not a python guru but I received an error as I run your script under terminal. Python reports that path for file or directory (of output plist) not found. I think you've forgotten to create and open writable plist prior attempting to write into it on `plistlib.writePlist(entry, snippet_path)`. By the way thanks for your code – anonim Nov 26 '12 at 21:38
  • 2
    @anonim.developer, thanks for the tip. I tried it on a clean machine and there was indeed a problem. It actually occurred if the user's snippets directory didn't already exist. The plist lib will automatically create the file if needed, but not the intermediate directories. I've updated the script. – Matt Wilding Nov 26 '12 at 22:05
  • Note: If you have already created custom snippets `os.makedirs(user_snippet_path)` will raise an exception since the directory already exists. – memmons Nov 11 '13 at 18:14
  • Also, this script seems to affect Xcode's auto-indentation. After running it Xcode will no longer auto-indent nested items anymore, e.g. the line under an if-statement or those in {} brackets. If I remove the custom snippets the script creates indentation works again. – memmons Nov 13 '13 at 18:25
  • The script catches and swallows exceptions if the snippet path already exists. Did you actually see that behavior? As for auto-indenting, that's a new one for me. I wrote this for Xcode 4, and we've had a major release since then, so it's possible things have changed... – Matt Wilding Nov 13 '13 at 18:53
12

There's a great little tool called "Snippet Edit". I just tried it, and highly recommend it. Apparently it used to be a for-pay app, but the author is now giving it away for free.

http://cocoaholic.com/snippet_edit/

software evolved
  • 4,314
  • 35
  • 45
6

You can edit system code snippets manually:

  1. Go to this directory: "/Developer/Library/Xcode/PrivatePlugIns".
  2. Show package contents of "IDECodeSnippetLibrary.ideplugin"
  3. Open "Contents/Resources/SystemCodeSnippets.codesnippets" as text file
  4. Edit it

.codesnippets file is a .plist but some strings entered with CR/LF and cannot be edited by standard plist editor.

sjngm
  • 12,423
  • 14
  • 84
  • 114
Oleg Uryutin
  • 413
  • 5
  • 15
  • 3
    In Xcode 4.3.2 this is in "/Applications/Xcode.app/Contents/PlugIns/IDECodeSnippetLibrary.ideplugin/Contents/Resources". – Mundi Apr 23 '12 at 06:03
  • 1
    For Xcode's self contained app. This is the exact file path of the default snippets: "/Applications/Xcode4.3.3.app/Contents/PlugIns/IDECodeSnippetLibrary.ideplugin/Contents/Resources/SystemCodeSnippets.codesnippets" – LightMan Jul 30 '12 at 10:42
4

You can edit the Xcode system snippets using a text editor and knowing the location of the system code snippets file. In Xcode 5.1.1 the location of the system code snippets file has changed once again to:

/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/SystemCodeSnippets.codesnippets

and you must have root privileges to edit the plist file in place because its owner and permissions are as follows:

$ ls -l /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/SystemCodeSnippets.codesnippets
-rw-r--r--  1 root  wheel  190 May 16 18:23 /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/SystemCodeSnippets.codesnippets

The plist dictionary keys are pretty self-explanatory and for the IDECodeSnippetIdentifier key, you can generate UUIDs yourself using for example the command:

$ uuidgen
42F6B133-5DA3-41DB-8874-4E10E447F723

Once you've edited the file using for instance sudo and your editor of choice, you have to restart Xcode in order to pick up your changes.

Happy hacking!

The Dude
  • 325
  • 1
  • 15
2

Either this is a bug, or it's a feature. I believe it's the latter. You can add your own snippets, but you can't edit the built-in ones. I'd just make a new snippet and customize it to how you want it.

sudo rm -rf
  • 29,408
  • 19
  • 102
  • 161
1

I wrote a script today that uses python and uncrustify to pull the snippets out of those provided by Xcode, reformat them to my liking, and dump them into a directory where I can then import them into ~/Library/Developer/Xcode/UserData/CodeSnippets. It's on github here: Xcode4Customization

Jonathan Saggau
  • 406
  • 4
  • 5