lib/bond/missions/object_mission.rb in bond-0.1.4 vs lib/bond/missions/object_mission.rb in bond-0.2.0
- old
+ new
@@ -1,49 +1,46 @@
-# Represents a completion mission specified by :object in Bond.complete. Unlike other missions, this
-# one needs to both match the mission condition and have the current object being completed have
-# an ancestor specified by :object.
-class Bond::Missions::ObjectMission < Bond::Mission
+# A mission which completes an object's methods. For this mission to match,
+# the condition must match and the current object must have an ancestor that matches :object.
+# Note: To access to the current object being completed on within an action, use the input's
+# object attribute.
+#
+# ==== Bond.complete Options:
+# [*:object*] String representing a module/class of object whose methods are completed.
+# [*:action*] If an action is not specified, the default action is to complete an object's
+# non-operator methods.
+#
+# ===== Example:
+# Bond.complete(:object=>ActiveRecord::Base) {|input| input.object.class.instance_methods(false) }
+class Bond::ObjectMission < Bond::Mission
#:stopdoc:
- attr_reader :object_condition
-
+ OBJECTS = %w<\S+> + Bond::Mission::OBJECTS
+ CONDITION = '(OBJECTS)\.(\w*(?:\?|!)?)$'
def initialize(options={})
- @object_condition = options.delete(:object)
- @object_condition = /^#{Regexp.escape(@object_condition.to_s)}$/ unless @object_condition.is_a?(Regexp)
- options[:on] ||= /(\S+|[^.]+)\.([^.\s]*)$/
- @eval_binding = options[:eval_binding]
+ @object_condition = /^#{options[:object]}$/
+ options[:on] ||= Regexp.new condition_with_objects
super
end
def unique_id
- "#{@object_condition.inspect}+#{@condition.inspect}"
+ "#{@object_condition.inspect}+#{@on.inspect}"
end
- def handle_valid_match(input)
- if (match = super)
- begin
- eval_object(match)
- rescue Exception
- return false
- end
- if (match = @evaled_object.class.ancestors.any? {|e| e.to_s =~ @object_condition })
- @completion_prefix = @matched[1] + "."
- @input = @matched[2]
- @input.instance_variable_set("@object", @evaled_object)
- @input.instance_eval("def self.object; @object ; end")
- @action ||= lambda {|e| default_action(e.object) }
- else
- match = false
- end
- end
- match
+ def do_match(input)
+ super && eval_object(@matched[1]) && @evaled_object.class.respond_to?(:ancestors) &&
+ @evaled_object.class.ancestors.any? {|e| e.to_s =~ @object_condition }
end
- def eval_object(match)
- @matched = match
- @evaled_object = self.class.current_eval(match[1], @eval_binding)
+ def after_match(input)
+ @completion_prefix = @matched[1] + "."
+ @action ||= lambda {|e| default_action(e.object) }
+ create_input @matched[2], :object=>@evaled_object
end
def default_action(obj)
obj.methods.map {|e| e.to_s} - OPERATORS
+ end
+
+ def match_message
+ "Matches completion for object with ancestor matching #{@object_condition.inspect}."
end
#:startdoc:
end
\ No newline at end of file