module Scide # Scide configuration for one project. class Project # The project key in the projects configuration hash. attr_reader :key # The path where the project is located. See {#initialize}. attr_reader :path # Project-specific options. Can be used by commands. See {#initialize}. attr_reader :options # The GNU Screen windows of this project. attr_reader :windows # The name or index of the window that should be displayed by default for # this project (defaults to the last window). attr_reader :default_window # Returns a project configuration. # # If not given in the project hash, {#path} is built by joining # the global path and key. # # == Arguments # * global - The global configuration. # * key - The key identifying the project. This is the # key in the projects hash. # * contents - The project hash. # # == Project Options # # {#options} is built by merging the options given in the project # hash with the global options. # # The following default options are added if not given: # * name - Defaults to the project key. # * path - The path where the project is located. def initialize global, key, contents raise ArgumentError, "project '#{key}' must be a hash" unless contents.kind_of? Hash raise ArgumentError, "windows of project '#{key}' must be an array" unless contents[:windows].kind_of?(Array) raise ArgumentError, "options of project '#{key}' must be a hash" unless contents[:options].nil? or contents[:options].kind_of?(Hash) @key = key # path defaults to project key @path = contents[:path].try(:to_s) || key.to_s unless path.match /^\// # if not absolute if global.path # expand from global directory @path = File.join global.path, @path else # or from home directory @path = File.join File.expand_path('~'), @path end end @options = global.options.dup @options[:name] = key @options[:path] = @path @options.merge!(contents[:options] || {}) @windows = contents[:windows].collect{ |w| Scide::Window.new self, w } # find default window if specified @default_window = if contents[:default_window].kind_of? Fixnum @windows[contents[:default_window]] elsif contents[:default_window].kind_of?(String) or contents[:default_window].kind_of?(Symbol) @windows.find{ |w| w.name == contents[:default_window].to_s } elsif !contents[:default_window].nil? raise ArgumentError, "default window of project '#{key}' should be an integer, string or symbol" end raise ArgumentError, "default window of project '#{key}' must be the name or index of one of its windows" if !contents[:default_window].nil? and @default_window.nil? end # Returns a representation of this project as a GNU Screen # configuration fragment. Returns nil if this project has # no configured windows. def to_screen return nil if @windows.blank? String.new.tap do |s| @windows.each_with_index do |w,i| s << w.to_screen(i) s << "\n" if i != (@windows.length - 1) end s << "\nselect #{@default_window.name}" if @default_window end end end end