module CodeRay::PluginHost
def [] id, *args, &blk
Example:
Returns the Plugin for +id+.
def [] id, *args, &blk plugin = validate_id(id) begin plugin = plugin_hash.[] plugin, *args, &blk end while plugin.is_a? Symbol plugin end
def all_plugins
Returns an array of all Plugins.
def all_plugins load_all plugin_hash.values.grep(Class) end
def const_missing const
Tries to +load+ the missing plugin by translating +const+ to the
def const_missing const id = const.to_s. gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). gsub(/([a-z\d])([A-Z])/,'\1_\2'). downcase load id end
def default id = nil
end
default :gray
map :navy => :dark_blue
class MyColorHost < PluginHost
See also map.
for a given id, or return the default plugin.
Define the default plugin to use when no plugin is found
def default id = nil if id id = validate_id id raise "The default plugin can't be named \"default\"." if id == :default plugin_hash[:default] = id else load :default end end
def extended mod
def extended mod PLUGIN_HOSTS << mod end
def list
Returns an array of all .rb files in the plugin path.
def list Dir[path_to('*')].select do |file| File.basename(file)[/^(?!_)\w+\.rb$/] end.map do |file| File.basename(file, '.rb').to_sym end end
def load_all
def load_all for plugin in list load plugin end end
def load_plugin_map
Loads the map file (see map).
def load_plugin_map mapfile = path_to '_map' @plugin_map_loaded = true if File.exist? mapfile require mapfile true else false end end
def make_plugin_hash
def make_plugin_hash @plugin_map_loaded ||= false Hash.new do |h, plugin_id| id = validate_id(plugin_id) path = path_to id begin raise LoadError, "#{path} not found" unless File.exist? path require path rescue LoadError => boom if @plugin_map_loaded if h.has_key?(:default) warn '%p could not load plugin %p; falling back to %p' % [self, id, h[:default]] h[:default] else raise PluginNotFound, '%p could not load plugin %p: %s' % [self, id, boom] end else load_plugin_map h[plugin_id] end else # Plugin should have registered by now if h.has_key? id h[id] else raise PluginNotFound, "No #{self.name} plugin for #{id.inspect} found in #{path}." end end end end
def map hash
:luna => :moon
:maroon => :brown,
map :navy => :dark_blue,
class MyColorHost < PluginHost
Usage: Put this in a file plugin_path/_map.rb.
Map a plugin_id to another.
def map hash for from, to in hash from = validate_id from to = validate_id to plugin_hash[from] = to unless plugin_hash.has_key? from end end
def path_to plugin_id
def path_to plugin_id File.join plugin_path, "#{plugin_id}.rb" end
def plugin_hash
def plugin_hash @plugin_hash ||= make_plugin_hash end
def plugin_path *args
def plugin_path *args unless args.empty? @plugin_path = File.expand_path File.join(*args) end @plugin_path ||= '' end
def register plugin, id
which calls this method.
Every plugin must register itself for +id+ by calling register_for,
def register plugin, id plugin_hash[validate_id(id)] = plugin end
def validate_id id
Raises +ArgumentError+ for all other objects, or if the
or returns +id+ if it already is a Symbol.
Converts +id+ to a Symbol if it is a String,
def validate_id id if id.is_a? Symbol or id.nil? id elsif id.is_a? String if id[/\w+/] == id id.downcase.to_sym else raise ArgumentError, "Invalid id given: #{id}" end else raise ArgumentError, "String or Symbol expected, but #{id.class} given." end end