require 'forwardable'

module Scope
  def scope match=self
    self.class.handle match
  end

  module Append
    def append_features mod
      super
      eval <<mod
      class << mod
        def handle *args
          #{name}::Handler.handle *args
        end
        extend Forwardable
        def_delegators #{name}::Handler, :def_handler, :all, :all=
      end
mod
    end
  end
  extend Append

  class Handler

    class << self
      attr_accessor :all
      def handlers
        @handlers ||= {}
        @handlers
      end
      def def_handler pattern, &action
        handlers[pattern] = action
      end
      def handle thing, match_to = thing
        handled = false
        handlers.each_pair do |pat, action|
          if pat === match_to
            handled = true
            action.call thing
            break unless all_actions?
          end
        end
        handled
      end
      def all_actions?
        @all
      end
    end
  end
end

module ScopeRegexp
  include Scope
  extend Append

  class Handler < Scope::Handler
    def self.handle thing, match_to = thing.to_s
      super
    end
  end
end

module ScopeFile
  include ScopeRegexp
  extend Scope::Append

  class Handler < ScopeRegexp::Handler
    def self.handle thing, match_to = thing
      if thing.respond_to? :mime
        super thing, thing.mime
      else
        super thing
      end
    end
  end
end

require 'pathname'

module Kernel
  def btick cmd, *args
    IO.popen("-") {|f| f ? f.read : exec(cmd, *args)}
  end
end

class Symbol
  def btick *args
    super to_s, *args
  end
  alias [] btick
end

class Pathname
  def mime
    :file["-bi", realpath].chomp
  end

  def entries_resolved
    entries.map {|e| self + e}
  end

  include ScopeFile
end
