So, here's a small one for you. No one's claiming it's pretty, but hell if it's not useful. If you've been following Plugin A Week, they're pushing a lovely piece of crack by the name of domains. I won't attempt to sell you on it (and neither do they, in truth), but I'm in love. I've tried to do the same with engines, without much success.
I've gotten to the point where I want any and everything I might even think about reusing in the future is a plugin. It's a bit beautiful. I write an "Image" plugin that handles everything I ever worry about with images. I write an "identity" plugin that takes care of everyting with users. It uses the image plugin. I build a "store" plugin that encapsulates an entire online store. Next next I get a client, I just svn propedit svn:externals vendor/plugins -- a quick migrate, and I'm done. Well, I guess I am selling now.
Ahem. So. I have a lot of plugins. Here's what I want to happen in TextMate:

And, I plop this in lib/tasks/textmate.rake (yes, the irony of not making a plugin does not escape me):
namespace 'mate' do
desc "Create a TextMate Project File"
task :project => [:environment] do
include Builder
plugin_directories = Dir["#{File.dirname(__FILE__)}/../../vendor/plugins/*"]
base_directory = File.expand_path("#{File.dirname(__FILE__)}/../../")
directory_filter = "!.*/(\\.[^/]*|CVS|_darcs|_MTN|\\{arch\\}|blib|.*~\\.nib|.*\\.(framework|app|pbproj|pbxproj|xcode(proj)?|bundle))$"
project_name = File.basename( base_directory )
out = File.open( "#{base_directory}/#{project_name}.tmproj", 'w')
xml = XmlMarkup.new(:target => out, :indent => 2)
xml.instruct! :xml, :version => '1.0', :encoding => 'UTF-8'
xml.declare! :DOCTYPE, :plist, :PUBLIC, "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"
xml.plist :version => '1.0' do
xml.dict do
xml.key('documents')
xml.array do
#
# Base Document
#
xml.dict do
xml.key('name')
xml.string( File.basename(base_directory) )
xml.key('regexFolderFilter')
xml.string( directory_filter )
xml.key('sourceDirectory')
xml.key( base_directory )
end
#
# Plugins
#
plugin_directories.each do |plugin|
full_path = File.expand_path( plugin )
plugin_name = File.basename( full_path )
xml.dict do
xml.key('children')
xml.array do
Dir["#{full_path}/*"].each do |plugin_file|
plugin_file_name = File.basename( plugin_file )
plugin_file_path = File.expand_path( plugin_file )
xml.dict do
if File.directory?( plugin_file_path )
xml.key('name')
xml.string( plugin_file_name )
xml.key('regexFolderFilter')
xml.string( directory_filter )
xml.key('sourceDirectory')
xml.string( plugin_file_path )
else
xml.key('filename')
xml.string( plugin_file_path )
xml.key('saveAsAbsolutePath')
xml.true
end
end
end
end #array
xml.key('name')
xml.string( plugin_name )
end # dict
end
end # array
xml.key('fileHierarchyDrawerWidth')
xml.integer('200')
xml.key('metaData')
xml.dict
xml.key('showFileHierarchyDrawer')
xml.true
xml.key('windowFrame')
xml.string('{{0, 800}, {800, 600}}')
end # dict
end # version
out.close
end
end
Copy/PasteTHAT'S ALOTTA CODE!

Shut Up.
I'm lazy, and reverse engineering can't be that clean. Well, maybe it can. Certainly not after four beers, though.
Anyway, if you're project's called awesome-2-point-oh, run rake mate:project, and you'll have an awesome-2-point-oh.tmproj file in your project's root you can double-click on to get the above screenshot
