Class: Redwood::Colormap

Inherits:
Object show all
Defined in:
lib/sup/colormap.rb

Constant Summary collapse

DEFAULT_COLORS =
{
  :text => { :fg => "white", :bg => "black" },
  :status => { :fg => "white", :bg => "blue", :attrs => ["bold"] },
  :index_old => { :fg => "white", :bg => "default" },
  :index_new => { :fg => "white", :bg => "default", :attrs => ["bold"] },
  :index_starred => { :fg => "yellow", :bg => "default", :attrs => ["bold"] },
  :index_draft => { :fg => "red", :bg => "default", :attrs => ["bold"] },
  :labellist_old => { :fg => "white", :bg => "default" },
  :labellist_new => { :fg => "white", :bg => "default", :attrs => ["bold"] },
  :twiddle => { :fg => "blue", :bg => "default" },
  :label => { :fg => "yellow", :bg => "default" },
  :message_patina => { :fg => "black", :bg => "green" },
  :alternate_patina => { :fg => "black", :bg => "blue" },
  :missing_message => { :fg => "black", :bg => "red" },
  :attachment => { :fg => "cyan", :bg => "default" },
  :cryptosig_valid => { :fg => "yellow", :bg => "default", :attrs => ["bold"] },
  :cryptosig_valid_untrusted => { :fg => "yellow", :bg => "blue", :attrs => ["bold"] },
  :cryptosig_unknown => { :fg => "cyan", :bg => "default" },
  :cryptosig_invalid => { :fg => "yellow", :bg => "red", :attrs => ["bold"] },
  :generic_notice_patina => { :fg => "cyan", :bg => "default" },
  :quote_patina => { :fg => "yellow", :bg => "default" },
  :sig_patina => { :fg => "yellow", :bg => "default" },
  :quote => { :fg => "yellow", :bg => "default" },
  :sig => { :fg => "yellow", :bg => "default" },
  :to_me => { :fg => "green", :bg => "default" },
  :with_attachment => { :fg => "green", :bg => "default" },
  :starred => { :fg => "yellow", :bg => "default", :attrs => ["bold"] },
  :starred_patina => { :fg => "yellow", :bg => "green", :attrs => ["bold"] },
  :alternate_starred_patina => { :fg => "yellow", :bg => "blue", :attrs => ["bold"] },
  :snippet => { :fg => "cyan", :bg => "default" },
  :option => { :fg => "white", :bg => "default" },
  :tagged => { :fg => "yellow", :bg => "default", :attrs => ["bold"] },
  :draft_notification => { :fg => "red", :bg => "default", :attrs => ["bold"] },
  :completion_character => { :fg => "white", :bg => "default", :attrs => ["bold"] },
  :horizontal_selector_selected => { :fg => "yellow", :bg => "default", :attrs => ["bold"] },
  :horizontal_selector_unselected => { :fg => "cyan", :bg => "default" },
  :search_highlight => { :fg => "black", :bg => "yellow", :attrs => ["bold"] },
  :system_buf => { :fg => "blue", :bg => "default" },
  :regular_buf => { :fg => "white", :bg => "default" },
  :modified_buffer => { :fg => "yellow", :bg => "default", :attrs => ["bold"] },
  :date => { :fg => "white", :bg => "default"},
  :size_widget => { :fg => "white", :bg => "default"},
}
@@instance =
nil

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize {|_self| ... } ⇒ Colormap

Returns a new instance of Colormap.

Yields:

  • (_self)

Yield Parameters:



75
76
77
78
79
80
81
82
83
# File 'lib/sup/colormap.rb', line 75

def initialize
  raise "only one instance can be created" if @@instance
  @@instance = self
  @color_pairs = {[Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK] => 0}
  @users = []
  @next_id = 0
  reset
  yield self if block_given?
end

Class Method Details

.color_for(*a) ⇒ Object

Performance shortcut



239
# File 'lib/sup/colormap.rb', line 239

def self.color_for(*a); @@instance.color_for(*a); end

.instanceObject



233
# File 'lib/sup/colormap.rb', line 233

def self.instance; @@instance; end

.method_missing(meth, *a) ⇒ Object



234
235
236
237
# File 'lib/sup/colormap.rb', line 234

def self.method_missing meth, *a
  Colormap.new unless @@instance
  @@instance.send meth, *a
end

Instance Method Details

#add(sym, fg, bg, attr = nil, highlight = nil) ⇒ Object

Raises:

  • (ArgumentError)


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/sup/colormap.rb', line 93

def add sym, fg, bg, attr=nil, highlight=nil
  raise ArgumentError, "color for #{sym} already defined" if @entries.member? sym
  raise ArgumentError, "color '#{fg}' unknown" unless (-1...Ncurses::NUM_COLORS).include? fg
  raise ArgumentError, "color '#{bg}' unknown" unless (-1...Ncurses::NUM_COLORS).include? bg
  attrs = [attr].flatten.compact

  @entries[sym] = [fg, bg, attrs, nil]

  if not highlight
    highlight = highlight_sym(sym)
    @entries[highlight] = highlight_for(fg, bg, attrs) + [nil]
  end

  @highlights[sym] = highlight
end

#color_for(sym, highlight = false) ⇒ Object

Raises:

  • (ArgumentError)


148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/sup/colormap.rb', line 148

def color_for sym, highlight=false
  sym = @highlights[sym] if highlight
  return Ncurses::COLOR_BLACK if sym == :none
  raise ArgumentError, "undefined color #{sym}" unless @entries.member? sym

  ## if this color is cached, return it
  fg, bg, attrs, color = @entries[sym]
  return color if color

  if(cp = @color_pairs[[fg, bg]])
    ## nothing
  else ## need to get a new colorpair
    @next_id = (@next_id + 1) % Ncurses::MAX_PAIRS
    @next_id += 1 if @next_id == 0 # 0 is always white on black
    id = @next_id
    debug "colormap: for color #{sym}, using id #{id} -> #{fg}, #{bg}"
    Ncurses.init_pair id, fg, bg or raise ArgumentError,
      "couldn't initialize curses color pair #{fg}, #{bg} (key #{id})"

    cp = @color_pairs[[fg, bg]] = Ncurses.COLOR_PAIR(id)
    ## delete the old mapping, if it exists
    if @users[cp]
      @users[cp].each do |usym|
        warn "dropping color #{usym} (#{id})"
        @entries[usym][3] = nil
      end
      @users[cp] = []
    end
  end

  ## by now we have a color pair
  color = attrs.inject(cp) { |color, attr| color | attr }
  @entries[sym][3] = color # fill the cache
  (@users[cp] ||= []) << sym # record entry as a user of that color pair
  color
end

#highlight_for(fg, bg, attrs) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/sup/colormap.rb', line 113

def highlight_for fg, bg, attrs
  hfg =
    case fg
    when Ncurses::COLOR_BLUE
      Ncurses::COLOR_WHITE
    when Ncurses::COLOR_YELLOW, Ncurses::COLOR_GREEN
      fg
    else
      Ncurses::COLOR_BLACK
    end

  hbg =
    case bg
    when Ncurses::COLOR_CYAN
      Ncurses::COLOR_YELLOW
    when Ncurses::COLOR_YELLOW
      Ncurses::COLOR_BLUE
    else
      Ncurses::COLOR_CYAN
    end

  attrs =
    if fg == Ncurses::COLOR_WHITE && attrs.include?(Ncurses::A_BOLD)
      [Ncurses::A_BOLD]
    else
      case hfg
      when Ncurses::COLOR_BLACK
        []
      else
        [Ncurses::A_BOLD]
      end
    end
  [hfg, hbg, attrs]
end

#highlight_sym(sym) ⇒ Object



109
110
111
# File 'lib/sup/colormap.rb', line 109

def highlight_sym sym
  "#{sym}_highlight".intern
end

#populate_colormapObject

Try to use the user defined colors, in case of an error fall back to the default ones.



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/sup/colormap.rb', line 191

def populate_colormap
  user_colors = if File.exist? Redwood::COLOR_FN
    debug "loading user colors from #{Redwood::COLOR_FN}"
    Redwood::load_yaml_obj Redwood::COLOR_FN
  end

  ## Set attachment sybmol to sane default for existing colorschemes
  if user_colors and user_colors.has_key? :to_me
    user_colors[:with_attachment] = user_colors[:to_me] unless user_colors.has_key? :with_attachment
  end

  Colormap::DEFAULT_COLORS.merge(user_colors||{}).each_pair do |k, v|
    fg = begin
      Ncurses.const_get "COLOR_#{v[:fg].to_s.upcase}"
    rescue NameError
      warn "there is no color named \"#{v[:fg]}\""
      Ncurses::COLOR_GREEN
    end

    bg = begin
      Ncurses.const_get "COLOR_#{v[:bg].to_s.upcase}"
    rescue NameError
      warn "there is no color named \"#{v[:bg]}\""
      Ncurses::COLOR_RED
    end

    attrs = (v[:attrs]||[]).map do |a|
      begin
        Ncurses.const_get "A_#{a.upcase}"
      rescue NameError
        warn "there is no attribute named \"#{a}\", using fallback."
        nil
      end
    end.compact

    highlight_symbol = v[:highlight] ? :"#{v[:highlight]}_color" : nil

    symbol = (k.to_s + "_color").to_sym
    add symbol, fg, bg, attrs, highlight_symbol
  end
end

#resetObject



85
86
87
88
89
90
91
# File 'lib/sup/colormap.rb', line 85

def reset
  @entries = {}
  @highlights = { :none => highlight_sym(:none)}
  @entries[highlight_sym(:none)] = highlight_for(Ncurses::COLOR_WHITE,
                                                 Ncurses::COLOR_BLACK,
                                                 []) + [nil]
end

#sym_is_defined(sym) ⇒ Object



185
186
187
# File 'lib/sup/colormap.rb', line 185

def sym_is_defined sym
    return sym if @entries.member? sym
end