property snippetsPlistPath : "~/Documents/snippets.plist" -- (* Copyright (c) 2006, Grayson Hansard All rights reserved. This software is provided “as is” without any expressed or implied warranties. Neither the original author nor any contributors are liable for any damage caused by the use of this program. You are free to use, distribute, and create derivative works for commercial and noncommercial use. Derivative works of this software must be made publicly available. *) property EndOfWordSet : {" ", " ", return, " ", ";", ","} -- Entry point to application. Basically gets the frontmost app and calls another function. on run set n to name of getFrontmostApp() if n is "Xcode" then xcode() if n is "TextWrangler" then textwrangler() textwrangler() end run -- Simple function to get the frontmost application. on getFrontmostApp() tell application "System Events" repeat with p in processes if p is frontmost then return p end repeat end tell end getFrontmostApp -- Convenience method to grab an item from the snippets property list on fetchSnippet(k) if class of k is not equal to list then set k to {k} tell application "System Events" try set plistFile to property list file snippetsPlistPath set plItem to contents of plistFile repeat with t in k set plItem to property list item named t of plItem end repeat return value of plItem on error e log e end try end tell return "" end fetchSnippet -- Convenience function to get the path extension of a file path on pathExtension(p) set buffer to "" repeat with c in (reverse of characters of p) set buffer to c & buffer if c contains "." then return buffer end repeat return "" end pathExtension -- Convenience method to try for possible variations in storage in plist file. -- For most editors, this first tries to locate the item under appname, then filetype, then key. If that fails, it tries appname and key. If that fails, it tries for filetype and key. Finally, if all else fails, it looks simply for the key. This allows the same keys to be used in different contexts. on tryForSnippets(l) set a to item 1 of l set b to item 2 of l set c to item 3 of l set ret to my fetchSnippet({a, b, c}) if ret is "" then set ret to fetchSnippet({a, c}) if ret is "" then set ret to fetchSnippet({b, c}) if ret is "" then set ret to fetchSnippet(c) return ret end tryForSnippets -- Convenience method to trim whitespace characters from the beginning and ends of words. on trim(s) if length of s is 1 and EndOfWordSet contains s then return "" set i to 1 repeat with c in s if EndOfWordSet contains c then set s to (characters (i + 1) thru (length of s)) of s as string set i to i + 1 end repeat set i to length of s repeat with c in reverse of characters of s if EndOfWordSet contains c then set s to characters 1 thru (i - 1) of s as string set i to i - 1 end repeat return s end trim -- Implementation for Xcode. Basic code format is followed for the TextWrangler implementation so only this is commented. on xcode() tell application "Xcode" -- Initialize the basic variables necessary to get the insertion point in a document set x to front text document set s to selection of x set a to insertion points of x -- I couldn't figure out a way to get meaningful information from an insertion point in Xcode so this steps through all the insertion points until it matches the current one. This provides the character index of the current insertion point. set i to 1 repeat with t in a if item i of a is equal to s then exit repeat set i to i + 1 end repeat set i to i - 1 if i < 1 then return set j to i -- Step backwards until the beginning of the key is found, creating a buffer that contains the key and a variable (j) that indicates the character index of the start of the key. set buffer to character i of x set stopSet to EndOfWordSet set c to character j of x repeat until stopSet contains c set j to j - 1 set c to character j of x set buffer to (c as string) & buffer if j ≤ 1 then exit repeat end repeat set buffer to my trim(buffer) -- Trim whitespace out of the key. if buffer is equal to "" then return -- Punt if only whitespace was found. -- Search the snippets property list for any possible values. See comments on tryForSnippets() for more information. set repl to tryForSnippets({"Xcode", pathExtension(path of x), buffer}) if repl is "" then return -- Punt if not value was found. -- Get all the characters before and after the key and then replace the key with the value found in the property list. set txt to text of x as string set temp1 to (characters 1 thru j of txt) as string set temp2 to (characters (i + 1) thru (length of txt) of txt) as string set text of x to temp1 & repl & temp2 -- Reset the insertion point (note this is a bit of a kludge and the insertion point may be a bit off). It's just a bit annoying that Xcode will set the insertion point to the end of the document. set selection of x to (insertion point (i + (length of repl) - 2) of x) end tell end xcode -- Implementation for TextWrangler. on textwrangler() tell application "TextWrangler" set doc to front document set i to (characterOffset of selection) - 1 if i < 1 then return set buffer to character i of doc as string set j to i set c to character j of doc as string repeat until EndOfWordSet contains c set j to j - 1 set c to character j of doc as string set buffer to c & buffer if j ≤ 1 then exit repeat end repeat set buffer to my trim(buffer) if buffer is equal to "" then return try set ext to my pathExtension(URL of doc) on error set ext to null end try set repl to my tryForSnippets({"TextWrangler", ext, buffer}) if repl is "" then return if j is equal to 1 then set j to 0 set characters (j + 1) thru i of doc to repl end tell end textwrangler