|
| 1 | +#!/usr/bin/env ruby |
| 2 | + |
| 3 | +# to install, add the following line to your .bash_profile or .bashrc |
| 4 | +# complete -C path/to/rake_completion -o default rake |
| 5 | + |
| 6 | +# Rake completion will return matching rake tasks given typed text. This way |
| 7 | +# you can auto-complete tasks as you are typing them by hitting [tab] or [tab][tab] |
| 8 | +# This also caches the rake tasks for optimium speed |
| 9 | +class RakeCompletion |
| 10 | + CACHE_FILE_NAME = '.rake_tasks~' |
| 11 | + |
| 12 | + def initialize(command) |
| 13 | + @command = command |
| 14 | + end |
| 15 | + |
| 16 | + def matches |
| 17 | + exit 0 if rakefile.nil? |
| 18 | + matching_tasks.map do |task| |
| 19 | + task.sub(typed_before_colon, '') |
| 20 | + end |
| 21 | + end |
| 22 | + |
| 23 | + private |
| 24 | + |
| 25 | + def typed |
| 26 | + @command[/\s(.+?)$/, 1] || '' |
| 27 | + end |
| 28 | + |
| 29 | + def typed_before_colon |
| 30 | + typed[/.+\:/] || '' |
| 31 | + end |
| 32 | + |
| 33 | + def matching_tasks |
| 34 | + all_tasks.select do |task| |
| 35 | + task[0, typed.length] == typed |
| 36 | + end |
| 37 | + end |
| 38 | + |
| 39 | + def all_tasks |
| 40 | + cache_current? ? tasks_from_cache : generate_tasks |
| 41 | + end |
| 42 | + |
| 43 | + def cache_current? |
| 44 | + File.exist?(cache_file) && File.mtime(cache_file) >= File.mtime(rakefile) |
| 45 | + end |
| 46 | + |
| 47 | + def rakefile |
| 48 | + ['rakefile', 'Rakefile', 'rakefile.rb', 'Rakefile.rb'].detect do |file| |
| 49 | + File.file? File.join(Dir.pwd, file) |
| 50 | + end |
| 51 | + end |
| 52 | + |
| 53 | + def cache_file |
| 54 | + File.join(Dir.pwd, CACHE_FILE_NAME) |
| 55 | + end |
| 56 | + |
| 57 | + def tasks_from_cache |
| 58 | + IO.read(cache_file).split |
| 59 | + end |
| 60 | + |
| 61 | + def generate_tasks |
| 62 | + tasks = `rake --tasks`.split("\n")[1..-1].collect {|line| line.split[1]} |
| 63 | + File.open(cache_file, 'w') { |f| f.write tasks.join("\n") } |
| 64 | + tasks |
| 65 | + end |
| 66 | +end |
| 67 | + |
| 68 | +puts RakeCompletion.new(ENV["COMP_LINE"]).matches |
| 69 | +exit 0 |
| 70 | + |
0 commit comments