Class: Echoes::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/echoes/configuration.rb

Constant Summary collapse

SHORTCUT_MODIFIERS =

Matches the NSEvent modifier flag bits — kept in sync with ‘ObjC::NSEventModifierFlag*` in objc.rb. Defined here so Configuration can resolve shortcut strings without depending on the AppKit-loading objc.rb at config-load time.

{
  'shift'   => 1 << 17,
  'control' => 1 << 18,
  'ctrl'    => 1 << 18,
  'option'  => 1 << 19,
  'opt'     => 1 << 19,
  'alt'     => 1 << 19,
  'cmd'     => 1 << 20,
  'command' => 1 << 20,
  'super'   => 1 << 20,
}.freeze

Instance Method Summary collapse

Constructor Details

#initializeConfiguration

Returns a new instance of Configuration.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/echoes/configuration.rb', line 7

def initialize
  @font_size = 14.0
  @rows = 24
  @cols = 80
  @shell = ENV['SHELL'] || '/bin/bash'
  @scrollback_limit = 1000
  @foreground = [0.9, 0.9, 0.9]
  @background = [0.0, 0.0, 0.0]
  @cursor_color = [0.7, 0.7, 0.7, 0.5]
  @font_family = nil
  @window_title = 'Echoes'
  @tab_position = :top
  @color_palette = nil
  @term = 'xterm-256color'
  @word_separators = ' @*.:/\\()"\'-:,.;<>~!#$%^&*|+=[]{}~?│'
  @selection_color = [0.2, 0.4, 0.7]
  @pane_divider_color = [0.4, 0.4, 0.4]
  @active_pane_border_color = [0.3, 0.5, 0.8]
  @copy_mode_cursor_color = [0.8, 0.7, 0.2]
  register_default_profiles
end

Instance Method Details

#active_pane_border_color(*args) ⇒ Object



118
119
120
# File 'lib/echoes/configuration.rb', line 118

def active_pane_border_color(*args)
  args.empty? ? @active_pane_border_color : @active_pane_border_color = parse_color(args)
end

#all_profilesObject

Profiles plus the synthesized “Default” — the menu / GUI uses this so the View → Profile submenu always has at least a discoverable “Default” entry even when the user hasn’t declared any profiles.



157
158
159
160
# File 'lib/echoes/configuration.rb', line 157

def all_profiles
  base = {'Default' => synthesized_profile}
  base.merge(profiles)
end

#background(*args) ⇒ Object



86
87
88
# File 'lib/echoes/configuration.rb', line 86

def background(*args)
  args.empty? ? @background : @background = parse_color(args)
end

#color_palette(val = nil) ⇒ Object



126
127
128
129
130
131
132
# File 'lib/echoes/configuration.rb', line 126

def color_palette(val = nil)
  if val
    @color_palette = val.map { |c| c.is_a?(String) ? parse_color([c]) : c.map(&:to_f) }
  else
    @color_palette
  end
end

#cols(val = nil) ⇒ Object



70
71
72
# File 'lib/echoes/configuration.rb', line 70

def cols(val = nil)
  val ? @cols = val.to_i : @cols
end

#copy_mode_cursor_color(*args) ⇒ Object



122
123
124
# File 'lib/echoes/configuration.rb', line 122

def copy_mode_cursor_color(*args)
  args.empty? ? @copy_mode_cursor_color : @copy_mode_cursor_color = parse_color(args)
end

#cursor_color(*args) ⇒ Object



90
91
92
# File 'lib/echoes/configuration.rb', line 90

def cursor_color(*args)
  args.empty? ? @cursor_color : @cursor_color = parse_color(args)
end

#default_profile(name = nil) ⇒ Object

Pick / look up the active profile by name. With no arg, returns whatever the user named via ‘default_profile “Foo”`, falling back to the synthesized “Default” so legacy configs (just foreground/background/etc.) keep working unchanged.



212
213
214
215
216
217
218
# File 'lib/echoes/configuration.rb', line 212

def default_profile(name = nil)
  if name
    @default_profile_name = name.to_s
  else
    profiles[@default_profile_name] || synthesized_profile
  end
end

#font_family(val = nil) ⇒ Object



58
59
60
# File 'lib/echoes/configuration.rb', line 58

def font_family(val = nil)
  val ? @font_family = val : @font_family
end

#font_size(val = nil) ⇒ Object



62
63
64
# File 'lib/echoes/configuration.rb', line 62

def font_size(val = nil)
  val ? @font_size = val.to_f : @font_size
end

#foreground(*args) ⇒ Object



82
83
84
# File 'lib/echoes/configuration.rb', line 82

def foreground(*args)
  args.empty? ? @foreground : @foreground = parse_color(args)
end

#keybind(shortcut, action) ⇒ Object

Rebind a menu shortcut. The first arg is a shortcut string like “Cmd+Shift+S” (Cmd / Shift / Ctrl / Option modifiers, case-insensitive); pass an empty string to disable the shortcut entirely. The second is the action symbol — one of the symbols Echoes documents (:new_window, :split_right, :toggle_find, etc.).

keybind "Cmd+Shift+T", :new_tab
keybind "",            :toggle_pointer     # disable


171
172
173
# File 'lib/echoes/configuration.rb', line 171

def keybind(shortcut, action)
  keybinds[action.to_sym] = parse_shortcut(shortcut.to_s)
end

#keybind_for(action) ⇒ Object

Returns modifiers: or nil if no override is set.



180
181
182
# File 'lib/echoes/configuration.rb', line 180

def keybind_for(action)
  keybinds[action.to_sym]
end

#keybindsObject



175
176
177
# File 'lib/echoes/configuration.rb', line 175

def keybinds
  @keybinds ||= {}
end

#pane_divider_color(*args) ⇒ Object



114
115
116
# File 'lib/echoes/configuration.rb', line 114

def pane_divider_color(*args)
  args.empty? ? @pane_divider_color : @pane_divider_color = parse_color(args)
end

#parse_shortcut(str) ⇒ Object



200
201
202
203
204
205
206
# File 'lib/echoes/configuration.rb', line 200

def parse_shortcut(str)
  return {key: '', modifiers: 0} if str.nil? || str.empty?
  parts = str.split('+').map(&:strip)
  key = parts.pop.to_s.downcase
  modifiers = parts.sum { |p| SHORTCUT_MODIFIERS[p.downcase] || 0 }
  {key: key, modifiers: modifiers}
end

#profile(name, &block) ⇒ Object

Define a named profile (color theme). Anything not set inside the block falls back to the top-level config attrs, so a profile is a partial override.

profile "Light" do
  foreground "#1a1a1a"
  background "#ffffff"
end


142
143
144
145
146
147
# File 'lib/echoes/configuration.rb', line 142

def profile(name, &block)
  p = Profile.new(name)
  p.instance_eval(&block) if block
  profiles[p.name] = p
  p
end

#profilesObject



149
150
151
# File 'lib/echoes/configuration.rb', line 149

def profiles
  @profiles ||= {}
end

#register_default_profilesObject

Two opinionated-but-recognizable profiles ship with Echoes so the View → Profile submenu has alternatives the moment the user opens it, without forcing them to write any DSL. Users can declare more (or override these) in their config file —‘profile “Solarized Dark” do …` redeclaring an existing name replaces the entry.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/echoes/configuration.rb', line 35

def register_default_profiles
  profile "Solarized Dark" do
    foreground "#93a1a1"
    background "#002b36"
    cursor_color "#93a1a1"
    selection_color "#586e75"
    color_palette %w[
      #073642 #dc322f #859900 #b58900 #268bd2 #d33682 #2aa198 #eee8d5
      #002b36 #cb4b16 #586e75 #657b83 #839496 #6c71c4 #93a1a1 #fdf6e3
    ]
  end
  profile "Solarized Light" do
    foreground "#586e75"
    background "#fdf6e3"
    cursor_color "#586e75"
    selection_color "#93a1a1"
    color_palette %w[
      #073642 #dc322f #859900 #b58900 #268bd2 #d33682 #2aa198 #eee8d5
      #002b36 #cb4b16 #586e75 #657b83 #839496 #6c71c4 #93a1a1 #fdf6e3
    ]
  end
end

#rows(val = nil) ⇒ Object



66
67
68
# File 'lib/echoes/configuration.rb', line 66

def rows(val = nil)
  val ? @rows = val.to_i : @rows
end

#scrollback_limit(val = nil) ⇒ Object



78
79
80
# File 'lib/echoes/configuration.rb', line 78

def scrollback_limit(val = nil)
  val ? @scrollback_limit = val.to_i : @scrollback_limit
end

#selection_color(*args) ⇒ Object



110
111
112
# File 'lib/echoes/configuration.rb', line 110

def selection_color(*args)
  args.empty? ? @selection_color : @selection_color = parse_color(args)
end

#shell(val = nil) ⇒ Object



74
75
76
# File 'lib/echoes/configuration.rb', line 74

def shell(val = nil)
  val ? @shell = val : @shell
end

#synthesized_profileObject

Build a “Default” Profile from the flat config attrs every time it’s asked for — never memoized, because the user’s config might mutate the flat attrs after our first call.



223
224
225
226
227
228
229
230
231
# File 'lib/echoes/configuration.rb', line 223

def synthesized_profile
  p = Profile.new('Default')
  p.instance_variable_set(:@foreground,      @foreground)
  p.instance_variable_set(:@background,      @background)
  p.instance_variable_set(:@cursor_color,    @cursor_color)
  p.instance_variable_set(:@selection_color, @selection_color)
  p.instance_variable_set(:@color_palette,   @color_palette)
  p
end

#tab_position(val = nil) ⇒ Object



98
99
100
# File 'lib/echoes/configuration.rb', line 98

def tab_position(val = nil)
  val ? @tab_position = val.to_sym : @tab_position
end

#term(val = nil) ⇒ Object



102
103
104
# File 'lib/echoes/configuration.rb', line 102

def term(val = nil)
  val ? @term = val : @term
end

#window_title(val = nil) ⇒ Object



94
95
96
# File 'lib/echoes/configuration.rb', line 94

def window_title(val = nil)
  val ? @window_title = val : @window_title
end

#word_separators(val = nil) ⇒ Object



106
107
108
# File 'lib/echoes/configuration.rb', line 106

def word_separators(val = nil)
  val ? @word_separators = val : @word_separators
end