lib/rvc/modules.rb in rvc-1.5.0 vs lib/rvc/modules.rb in rvc-1.6.0
- old
+ new
@@ -17,10 +17,11 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
require 'rvc/util'
+require 'shellwords'
module RVC
ALIASES = {}
MODULES = {}
@@ -29,31 +30,85 @@
include RVC::Util
def initialize module_name
@module_name = module_name
@opts = {}
+ @completors = {}
super()
end
def commands
@opts.keys
end
+ def has_command? cmd
+ @opts.member? cmd
+ end
+
def opts cmd, &b
- @opts[cmd] = b
+ if cmd.to_s =~ /[A-Z]/
+ fail "Camel-casing is not allowed (#{cmd.to_s})"
+ end
+
+ @opts[cmd] = OptionParser.new cmd.to_s, &b
+
+ @opts[cmd].specs.each do |name,spec|
+ if name.to_s =~ /[A-Z]/
+ fail "Camel-casing is not allowed (#{cmd.to_s} option #{name})"
+ end
+ end
end
+ def raw_opts cmd, summary
+ @opts[cmd] = RawOptionParser.new cmd.to_s, summary
+ end
+
def opts_for cmd
@opts[cmd]
end
+ def rvc_completor cmd, &b
+ @completors[cmd] = b
+ end
+
+ def completor_for cmd
+ @completors[cmd]
+ end
+
def rvc_alias cmd, target=nil
target ||= cmd
RVC::ALIASES[target.to_s] = "#{@module_name}.#{cmd}"
end
end
+def self.complete_for_cmd line, word
+ if line == nil
+ return []
+ end
+ mod, cmd, args = Shell.parse_input line
+ return [] unless mod != nil
+ #XXX assumes you aren't going to have any positional arguments with spaces
+ if(/ $/.match(line))
+ argnum = args.size
+ else
+ argnum = args.size - 1
+ end
+
+ completor = mod.completor_for(cmd.to_sym)
+ if completor == nil
+ return []
+ end
+
+ candidates = completor.call(line, args, word, argnum)
+ if candidates == nil
+ []
+ else
+ prefix_regex = /^#{Regexp.escape word}/
+ candidates.select { |x,a| x =~ prefix_regex }
+ end
+end
+
BULTIN_MODULE_PATH = [File.expand_path(File.join(File.dirname(__FILE__), 'modules')),
File.join(ENV['HOME'], ".rvc")]
ENV_MODULE_PATH = (ENV['RVC_MODULE_PATH'] || '').split ':'
def self.reload_modules verbose=true
@@ -63,16 +118,21 @@
module_path = (BULTIN_MODULE_PATH+ENV_MODULE_PATH).select { |d| File.directory?(d) }
globs = module_path.map { |d| File.join(d, '*.rb') }
Dir.glob(globs) do |f|
module_name = File.basename(f)[0...-3]
puts "loading #{module_name} from #{f}" if verbose
- code = File.read f
- unless RVC::MODULES.member? module_name
- m = CmdModule.new module_name
- CMD.define_singleton_method(module_name.to_sym) { m }
- RVC::MODULES[module_name] = m
+ begin
+ code = File.read f
+ unless RVC::MODULES.member? module_name
+ m = CmdModule.new module_name
+ CMD.define_singleton_method(module_name.to_sym) { m }
+ RVC::MODULES[module_name] = m
+ end
+ RVC::MODULES[module_name].instance_eval code, f
+ rescue
+ puts "#{$!.class} while loading #{f}: #{$!.message}"
+ $!.backtrace.each { |x| puts x }
end
- RVC::MODULES[module_name].instance_eval code, f
end
end
end