oo, a shell script for opening things

Sometimes… sometimes you just want to open something. On OS X, you have some choices.

  • open XXX opens the given file with the default application for its type. It will open directories in Finder.
  • mate XXX opens the given file or directory in TextMate.

You want to choose the right one for the job, but you have to think! mate . for Rails projects, open Spinner.xcodeproj for Xcode projects, open Crap.fla for Flash, … When I don't want to think about it, I yell, "OPEN, OPEN!" and type oo (pronounced "ooh"). It does the right thing.

#!/usr/bin/env ruby

# context-sensitive "open" alternative
# just go into a directory and run "oo"
# the correct project editor be used to open it

# usage:
#  $ oo                         guess what to do with current directory
#  $ oo [file or directory]     guess what to do with the given file/directory

# from: http://alltom.com/pages/oo
# gist: https://gist.github.com/803281

@file = "."

# if a filename was given, let's operate from there
# instead of the current directory
if ARGV.first
  unless File.exist?(ARGV.first)
    puts "\"#{ARGV.first}\" doesn't exist"
    exit 1
  end

  # if it's a file, operate on that
  # otherwise, operate on that directory
  if File.file?(ARGV.first)
    Dir.chdir(File.dirname ARGV.first)
    @file = File.basename ARGV.first
  else
    Dir.chdir(ARGV.first)
  end
end

# does this glob match anything in the directory?
def has(glob)
  Dir[glob].length > 0
end

# is @file included in the glob?
# (I'd check the glob against the string directly, but I don't know how)
def is(glob)
  Dir[glob].include? @file
end

dir_matchers = [
  { :matcher => lambda { has "*.xcodeproj" }, :open => "*.xcodeproj" },
  { :matcher => lambda { has "*.pbxproj" }, :open => "." }, # inside *.xcodeproj dir
  { :matcher => lambda { has "*.fla" }, :open => "*.fla" },
  { :matcher => lambda { has "app" }, :cmd => "mate" }, # rails
  { :matcher => lambda { true }, :cmd => "mate" } # default
]

file_matchers = [
  { :matcher => lambda { is "*.fla" }, :cmd => "open" },
  { :matcher => lambda { true }, :cmd => "mate" } # default
]

(@file == "." ? dir_matchers : file_matchers).each do |m|
  if m[:matcher][]
    exec(m[:cmd] || "open",
         m[:open] ? Dir[m[:open]].first : @file)
    exit
  end
end

Comments

Click here to view the comments on this post, or just send me an e-mail.