Skip to content

Instantly share code, notes, and snippets.

@swieton
Created February 4, 2011 14:56
Show Gist options
  • Save swieton/811191 to your computer and use it in GitHub Desktop.
Save swieton/811191 to your computer and use it in GitHub Desktop.
Bash completion for thor
#!/usr/bin/env ruby
# Complete thor tasks script for bash
# Save it somewhere and then add
# complete -C path/to/script -o default thor
# to your ~/.bashrc
# Mike Swieton ([email protected]), based almost entirely on:
# Xavier Shay (http://rhnh.net), combining work from
# Francis Hwang ( http://fhwang.net/ ) - http://fhwang.net/rb/rake-complete.rb
# Nicholas Seckar <[email protected]> - http://www.webtypes.com/2006/03/31/rake-completion-script-that-handles-namespaces
# Saimon Moore <[email protected]>
require 'fileutils'
THORFILES = ['thorfile', 'Thorfile', 'thorfile.rb', 'Thorfile.rb']
exit 0 unless THORFILES.any? { |rf| File.file?(File.join(Dir.pwd, rf)) }
exit 0 unless /^thor\b/ =~ ENV["COMP_LINE"]
after_match = $'
task_match = (after_match.empty? || after_match =~ /\s$/) ? nil : after_match.split.last
cache_dir = File.join( ENV['HOME'], '.thor_tc_cache' )
FileUtils.mkdir_p cache_dir
thorfile = THORFILES.detect { |rf| File.file?(File.join(Dir.pwd, rf)) }
thorfile_path = File.join( Dir.pwd, thorfile )
cache_file = File.join( cache_dir, thorfile_path.gsub( %r{/}, '_' ) )
if File.exist?( cache_file ) &&
File.mtime( cache_file ) >= (Dir['tasks/*.rb'] << thorfile).collect {|x| File.mtime(x) }.max
task_lines = File.read( cache_file )
else
task_lines = `thor list`
File.open( cache_file, 'w' ) do |f| f << task_lines; end
end
tasks = task_lines.split("\n")[1..-1].collect {|line| line.split[1]}
tasks = tasks.select {|t| /^#{Regexp.escape task_match}/ =~ t} if task_match
# handle namespaces
if task_match =~ /^([-\w:]+:)/
upto_last_colon = $1
after_match = $'
tasks = tasks.collect { |t| (t =~ /^#{Regexp.escape upto_last_colon}([-\w:]+)$/) ? "#{$1}" : t }
end
puts tasks
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment