Class: Muby::Configuration

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

Overview

The class that encapsulates all configuration.

To simplify its use, include Muby::Configurable in your class. Then you can access Configuration as ‘conf’ (nice shorthand :)

All options in Configuration are get’able and set’able.

Look in help.rb to get the meaning of them.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfiguration

Returns a new instance of Configuration.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
147
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/muby/configuration.rb', line 27

def initialize
  #
  # verbosity options
  #

  @extra_verbosity_settings = {
    :echo_keycodes => true,
    :echo => true,
    :show_level => :debug,
    :timestamp => true,
    :connection_status => true
  }

  @output_window_geometry = {
    :top => 0,
    :left => 0,
    :width => "Ncurses.COLS",
    :height => "Ncurses.LINES - Muby::InputWindow.get_instance.height"
  }

  @input_window_geometry = {
    :top => "Ncurses.LINES - conf.input_height - 2",
    :left => 0,
    :width => "Ncurses.COLS",
    :height => "conf.input_height + 2"
  }

  @single_shot_gags = []
  
  @echo_keycodes = false

  @echo = true

  @show_level = :info

  @timestamp = false

  @connection_status = true

  #
  # options to control what you see 
  #

  @disable_blink = false
  
  @timeformat = "%H:%M:%S"

  @broken_keycodes = {
    13 => true
  }

  @max_history = 100

  @default_attributes = Ncurses.const_get("A_NORMAL")
  @default_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]

  @echo_attributes = Ncurses.const_get("A_BOLD")
  @echo_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]

  @trace_attributes = Ncurses.const_get("A_NORMAL")
  @trace_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]

  @debug_attributes = Ncurses.const_get("A_NORMAL")
  @debug_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]

  @info_attributes = Ncurses.const_get("A_NORMAL")
  @info_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]

  @warn_attributes = Ncurses.const_get("A_NORMAL")
  @warn_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]

  @error_attributes = Ncurses.const_get("A_NORMAL")
  @error_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]

  @flush = true
  
  @gags = []
  
  @colors = {}

  @anti_gags = []
  
  @remote_substitutions = {}
  
  @local_substitutions = {}

  #
  # options to control what gets run when         #
  #

  @startup_triggers = []

  @disconnect_triggers = []

  @connect_triggers = []

  @shutdown_triggers = []

  @remote_triggers = {}
  
  @remote_character_triggers = {}
  
  @local_triggers = {
    /^\/(.*)\n$/m => :execute_command!,
    /^!(.*)\n$/m => :shell_command!,
    /^#.*\n$/m => :ignore_command!
  }
  
  @key_commands = {
    12 => :resize_application!, # ctrl-l
    Ncurses.const_get("KEY_PPAGE") => :scroll_up!,
    Ncurses.const_get("KEY_NPAGE") => :scroll_down!,
    Ncurses.const_get("KEY_ENTER") => :process_buffer!,
    10 => :process_buffer!, # enter
    3 => :two_step_quit!, # ctrl-c
    9 => :complete!, # tab
    18 => :toggle_history_search!, # ctrl-r
    127 => :backspace_buffer!, # backspace
    Ncurses.const_get("KEY_BACKSPACE") => :backspace_buffer!,
    27 => {
      263 => :word_backspace_buffer!, # alt-backspace
      91 => {
        49 => {
          59 => {
            53 => {
              68 => :previous_word_buffer!, # ctrl-key_left
              67 => :next_word_buffer!, # ctrl-key_right
            }
          }
        }
      }
    },
    Ncurses.const_get("KEY_DC") => :delete_buffer!,
    Ncurses.const_get("KEY_UP") => :previous_history_buffer!,
    Ncurses.const_get("KEY_DOWN") => :next_history_buffer!,
    262 => :home_buffer!, # home_key
    360 => :end_buffer!, # end_key
    Ncurses.const_get("KEY_LEFT") => :previous_character_buffer!,
    Ncurses.const_get("KEY_RIGHT") => :next_character_buffer!,
    22 => :toggle_verbosity!, # ctrl-v
    265 => :help # f1
  }

  #
  # miscellaneous options #
  #

  @connect_timeout = 10

  @feed_completer_with_history = true

  @feed_completer_with_input = true

  @extra_completions = []
  
  @loaded_rc_file = false

  @user_edited_config_file = false
  
  @userdir = File.join(ENV["HOME"], "mubyrc.d")

  @history_file = File.join(@userdir, "history")

  @output_buffer = 1000
  
  @input_height = 3
  
  @input_logfile = nil 
  
  @output_logfile = nil

end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*args) ⇒ Object

The magical method that lets us get and set the settings without having to write getters and setters for all of them



204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/muby/configuration.rb', line 204

def method_missing(*args)
  method_name = args[0].to_s
  var_name = method_name[/^[^=]*/]
  
  setter = method_name =~ /=$/
  if setter
    return super unless args.size == 2
    instance_variable_set("@#{var_name}", args[1])
    return args[1]
  else
    return super unless args.size == 1
    return instance_variable_get("@#{var_name}")
  end
end

Class Method Details

.getObject



23
24
25
# File 'lib/muby/configuration.rb', line 23

def self.get
  @@instance ||= Configuration.new
end

Instance Method Details

#display?(level) ⇒ Boolean

Returns true if we are supposed to display messages of level.

Returns:

  • (Boolean)


246
247
248
249
# File 'lib/muby/configuration.rb', line 246

def display?(level)
  levels = [:trace, :debug, :info, :warn, :error]
  levels.index(level) >= (levels.index(@show_level) || 0)
end

#load_user_files!Object

Tries to load all the users files, defined as any file named .mubyrc or mubyrc in the users ENV and all */.rb files in the users ENV/@userdir with the root of the userdir taking precidence over subdirectories. Directories starting with a . are ignored.

If none of the mubyrc-files existed, it will try to create one for the user to edit to his/her liking.



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# File 'lib/muby/configuration.rb', line 279

def load_user_files!
  @loaded_rc_file = false
  if to_load = [".mubyrc", "mubyrc"].collect do |file_name|
      File.join(ENV["HOME"], file_name)
    end.find do |file_name|
      File.exists?(file_name)
    end
    nice_load!(to_load)
    @loaded_rc_file = to_load
  end

  unless @loaded_rc_file
    save_configuration_file!
  end
  
  if File.exists?(@userdir)
    # Only load *.rb files within sub-directories of the current directory, and not the current directory's *.rb files!)
    # Test:  Dir[File.join(Dir.pwd, "*", "**", "*.rb")].each do |f| puts f end ; nil
    Dir[File.join(@userdir, "*", "**", "*.rb")].each do |file_name|
      nice_load!(file_name)
    end
    # Only load *.rb files of the current directory.
    # This is very useful for users to create "overrides" for items in subdirectories.
    # NOTE: This does follow symbolic links (files and directories)
    # Test:  Dir[File.join(Dir.pwd, "*.rb")].each do |f| puts f end ; nil
    Dir[File.join(@userdir, "*.rb")].each do |file_name|
      nice_load!(file_name)
    end
  else
    Muby::Displayer.warn("#{@userdir} does not exist. If it did, *.rb in it would be loaded now.")
  end
end

#nice_load!(f) ⇒ Object

A non-raising method that tries to load f and tells the output window about its success.



315
316
317
318
319
320
321
322
# File 'lib/muby/configuration.rb', line 315

def nice_load!(f)
  begin
    Kernel::load(f)
    Muby::Displayer.info("Loaded #{f}")
  rescue Exception => e
    Muby::Displayer.exception(e)
  end
end

#reload_application!Object

Will reload the entire app, ie the class files and the user files.

TODO: Remove the spammyness. It is not appropriate to use ‘puts’ when reload_application! is being called by the user. To turn off “uninitialised constant” warnings, do: $VERBOSE = nil

Simply set your show_level to :warn instead of :info, and you wont see the load messages.

Any other messages come from your own files :O



336
337
338
339
340
341
# File 'lib/muby/configuration.rb', line 336

def reload_application!
  Dir[File.join(File.dirname(__FILE__), "**", "*.rb")].each do |file_name|
    nice_load! file_name
  end
  load_user_files!
end

#save_configuration_file!Object

Will save the current configuration to the loaded rc file, or to mubyrc if no such file was loaded.



255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/muby/configuration.rb', line 255

def save_configuration_file!
  to_save = @loaded_rc_file ? @loaded_rc_file : File.join(ENV["HOME"], "mubyrc")
  begin
    Kernel::open(to_save, "w") do |output|
      output.write(self.to_ruby)
      @loaded_rc_file = to_save
    end
    Muby::Displayer.info("Saved default configuration to #{to_save}.")
  rescue Exception => e
    Muby::Displayer.warn("Failed saving default configuration to #{to_save}: #{e.message}")
    Muby::Displayer.debug(e.backtrace.join("\n"))
  end
end

#to_rubyObject

The not so magical at all method that prints our content to a String so that we easily can save our current settings in a file, or create a default config file.



348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# File 'lib/muby/configuration.rb', line 348

def to_ruby
  "#
# This is the default configuration of muby.
# To learn more about how to configure it, you
# can type '/help' in the client.
#
include Muby::Configurable
" +
  instance_variables.sort.collect do |var_name|
    value = eval(var_name)
    case value
    when Hash
      space = "conf.#{var_name[1..-1]} = _".size
      value = value.inspect.gsub(/, /, ",\n#{" " * space}")
    when File
      begin
        value.read(0)
        value = "open(\"#{value.path}\", \"r\")"
      rescue
        value = "open(\"#{value.path}\", \"a\")"
      end
    when NilClass
      value = value.inspect
    else
      value = value.inspect
    end
    var_name = var_name[1..-1]
    help_text = Muby::Help.configuration[var_name.to_sym] || "no help available for #{var_name}"
    help_text = help_text.split("\n").join("\n# ")
    "
# #{help_text}
conf.#{var_name} = #{value}"
  end.join("\n")
end

#toggle_verbosity!Object

The halfway magical method that toggles all settings covered in and then stores them away inside the same hash for back-toggling again.



224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/muby/configuration.rb', line 224

def toggle_verbosity!

  # copy old extra-settings to a copy
  settings_copy = @extra_verbosity_settings.clone

  # set our extra-settings to be the currently applied settings
  @extra_verbosity_settings.clone.each do |key, value|
    @extra_verbosity_settings[key] = self.send(key)
  end

  # apply the extra-settings
  settings_copy.each do |key, value|
    self.send("#{key}=", value)
  end

  Muby::Displayer.info("Toggled verbosity. Press <key> again to toggle back.")
end