muby 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +339 -0
- data/bin/muby +37 -0
- data/contrib/aardmud.org_4000/README.txt +39 -0
- data/contrib/aardmud.org_4000/aard-config.rb +234 -0
- data/contrib/aardmud.org_4000/aard-helpers.rb +464 -0
- data/contrib/aardmud.org_4000/aliases/aard-aliases.rb +205 -0
- data/contrib/aardmud.org_4000/gags/aard-gags.rb +182 -0
- data/contrib/aardmud.org_4000/misc/aard-affects.rb +252 -0
- data/contrib/aardmud.org_4000/misc/aard-know.rb +147 -0
- data/contrib/aardmud.org_4000/misc/aard-poznai_sebia.rb +191 -0
- data/contrib/aardmud.org_4000/misc/aard-prompts.rb +65 -0
- data/contrib/aardmud.org_4000/misc/aard-status_toggling.rb +156 -0
- data/contrib/aardmud.org_4000/misc/aard_consider_substitutions.rb +319 -0
- data/contrib/aardmud.org_4000/speedwalks/aard-sw-areas-hero.rb +86 -0
- data/contrib/aardmud.org_4000/speedwalks/aard-sw-areas-newbie.rb +98 -0
- data/contrib/aardmud.org_4000/speedwalks/aard-sw-areas-noble.rb +170 -0
- data/contrib/aardmud.org_4000/speedwalks/aard-sw-areas-vidblain.rb +88 -0
- data/contrib/aardmud.org_4000/speedwalks/aard-sw-areas.rb +850 -0
- data/contrib/aardmud.org_4000/speedwalks/aard-sw-clans.rb +43 -0
- data/contrib/aardmud.org_4000/speedwalks/aard-sw-guilds.rb +13 -0
- data/contrib/aardmud.org_4000/speedwalks/aard-sw.rb +45 -0
- data/contrib/aardmud.org_4000/triggers/aard-triggers-items.rb +254 -0
- data/contrib/aardmud.org_4000/triggers/aard-triggers.rb +227 -0
- data/contrib/sy/cce.rb +120 -0
- data/lib/muby.rb +15 -0
- data/lib/muby/application.rb +66 -0
- data/lib/muby/completer.rb +62 -0
- data/lib/muby/configuration.rb +379 -0
- data/lib/muby/connection.rb +332 -0
- data/lib/muby/displayer.rb +60 -0
- data/lib/muby/help.rb +88 -0
- data/lib/muby/helper_methods.rb +46 -0
- data/lib/muby/inputwindow.rb +173 -0
- data/lib/muby/logger.rb +28 -0
- data/lib/muby/outputwindow.rb +189 -0
- data/lib/muby/style.rb +142 -0
- data/lib/muby/user_methods.rb +463 -0
- metadata +90 -0
data/contrib/sy/cce.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
#
|
2
|
+
# Colour Code Echo
|
3
|
+
#
|
4
|
+
# cce("@R RED @r red @G GREEN @g green @B BLUE @b blue @C CYAN @c cyan @M MAGENTA @m magenta @Y YELLOW @y yellow @W WHITE @w white\n\n")
|
5
|
+
# It's magic, baby!
|
6
|
+
|
7
|
+
$cce_display_invalid_codes = true
|
8
|
+
def cce(source)
|
9
|
+
|
10
|
+
# TODO: If printing redundant normal / bold codes offends someone's sensibilities, I could extract the current colour code, and only display another colour code if it's different!
|
11
|
+
# I'd do it right now, but I'm not sure how that works.
|
12
|
+
# Style.extract(@outputWindow.outputBuffer)
|
13
|
+
def normal ; $INPUTATTRIBUTES = Ncurses.const_get("A_NORMAL") end
|
14
|
+
def reset ; normal ; $INPUTCOLORS = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")] end
|
15
|
+
def bold ; $INPUTATTRIBUTES = Ncurses.const_get("A_BOLD") end
|
16
|
+
def red ; color_codes_set("COLOR_RED") end
|
17
|
+
def green ; color_codes_set("COLOR_GREEN") end
|
18
|
+
def blue ; color_codes_set("COLOR_BLUE") end
|
19
|
+
def cyan ; color_codes_set("COLOR_CYAN") end
|
20
|
+
def magenta ; color_codes_set("COLOR_MAGENTA") end
|
21
|
+
def yellow ; color_codes_set("COLOR_YELLOW") end
|
22
|
+
def white ; color_codes_set("COLOR_WHITE") end
|
23
|
+
|
24
|
+
def color_codes_set(ncurses_colour_code)
|
25
|
+
$INPUTCOLORS = [Ncurses.const_get(ncurses_colour_code), Ncurses.const_get("COLOR_BLACK")]
|
26
|
+
end
|
27
|
+
|
28
|
+
# echon in colour
|
29
|
+
def echon_colour (string)
|
30
|
+
# If I wasn't sent anything useful, then .. don't do anything useful:
|
31
|
+
if string == nil || string == "" then return nil end
|
32
|
+
|
33
|
+
oldStyle = Style.extract(@outputWindow.outputBuffer)
|
34
|
+
style = Style.new($INPUTATTRIBUTES, $INPUTCOLORS[0], $INPUTCOLORS[1])
|
35
|
+
@outputWindow.print([style, string, oldStyle])
|
36
|
+
end
|
37
|
+
|
38
|
+
def colour_codes_code(code)
|
39
|
+
# If I wasn't sent anything useful, then .. don't do anything useful:
|
40
|
+
if code == nil || code == "" then return nil end
|
41
|
+
# Weird code requires brackets:
|
42
|
+
if (code.kind_of? String) == false then return nil end
|
43
|
+
# If someone passed me @x then just use x
|
44
|
+
# Also, behave semi-sanely if passed a weird string length. Make it a string, then use element #2
|
45
|
+
if code.length > 1 then code = code.to_s[1,1] end
|
46
|
+
|
47
|
+
# This could offend someone, since it sends "unnecessary" bold/normal codes:
|
48
|
+
if code == code.upcase then bold else normal end
|
49
|
+
|
50
|
+
# Work with the different flavours of colour:
|
51
|
+
case code.downcase
|
52
|
+
when "r" then red
|
53
|
+
when "g" then green
|
54
|
+
when "b" then blue
|
55
|
+
when "c" then cyan
|
56
|
+
when "m" then magenta
|
57
|
+
when "y" then yellow
|
58
|
+
when "w" then white
|
59
|
+
when "@" then echon_colour "@"
|
60
|
+
else # If an invalid colour code has been found
|
61
|
+
if $cce_display_invalid_codes == true then echon_colour "@" + code end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
# If I wasn't sent anything useful, then .. don't do anything useful:
|
68
|
+
if source == nil || source == "" then return nil end
|
69
|
+
|
70
|
+
# Debug:
|
71
|
+
# echon "# " + source
|
72
|
+
|
73
|
+
# Gather an array of all the interesting text.
|
74
|
+
strings = []
|
75
|
+
source.split(/@./).each { |element|
|
76
|
+
strings << element
|
77
|
+
}
|
78
|
+
|
79
|
+
# Gather an array of all the interesting codes
|
80
|
+
codes = source.scan(/@./)
|
81
|
+
|
82
|
+
# Debug:
|
83
|
+
# echo strings.inspect
|
84
|
+
# echo codes.inspect
|
85
|
+
|
86
|
+
# If all strings are nil, then return the last colour code:
|
87
|
+
if strings.nitems == 0 then colour_codes_code codes.compact.last end
|
88
|
+
|
89
|
+
|
90
|
+
# Work with the two halves of my source text:
|
91
|
+
strings.each_index { |i|
|
92
|
+
echon_colour(strings[i])
|
93
|
+
colour_codes_code(codes[i])
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def cce_test
|
98
|
+
echo "echon_colour test:\n------------------\n"
|
99
|
+
cce("@R RED @r red @G GREEN @g green @B BLUE @b blue @C CYAN @c cyan @M MAGENTA @m magenta @Y YELLOW @y yellow @W WHITE @w white\n\n")
|
100
|
+
cce("@rred @Rbold red\n")
|
101
|
+
cce("@ggreen @Gbold green\n")
|
102
|
+
cce("@bblue @Bbold blue\n")
|
103
|
+
cce("@ccyan @Cbold cyan\n")
|
104
|
+
cce("@mmagenta @Mbold magenta\n")
|
105
|
+
cce("@yyellow @Ybold yellow\n")
|
106
|
+
cce("@wwhite @Wbold white\n")
|
107
|
+
cce("A simple string can be passed.\n")
|
108
|
+
cce("A single colour code can be passed.\n")
|
109
|
+
cce("@w")
|
110
|
+
cce("@@an at symbol\n")
|
111
|
+
$cce_display_invalid_codes = true
|
112
|
+
cce("An invalid code can be set to appear: @xan invalid code\n")
|
113
|
+
$cce_display_invalid_codes = false
|
114
|
+
cce("Or to be removed: @xinvalid code\n")
|
115
|
+
cce("@r@rmultiple colour codes at the start\n")
|
116
|
+
cce("@w\n")
|
117
|
+
cce("multiple colour codes at the end@r@r")
|
118
|
+
echo ""
|
119
|
+
echon_colour "bleed test"
|
120
|
+
end
|
data/lib/muby.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$: << File.join(File.dirname(__FILE__), "lib")
|
2
|
+
require 'pp'
|
3
|
+
require "muby/helper_methods"
|
4
|
+
require "muby/user_methods"
|
5
|
+
require "muby/displayer"
|
6
|
+
require "muby/configuration"
|
7
|
+
require "muby/logger"
|
8
|
+
require "muby/style"
|
9
|
+
require "muby/outputwindow"
|
10
|
+
require "muby/inputwindow"
|
11
|
+
require "muby/connection"
|
12
|
+
require "muby/help"
|
13
|
+
require "muby/completer"
|
14
|
+
require "muby/application"
|
15
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
|
2
|
+
module Muby
|
3
|
+
|
4
|
+
class Application
|
5
|
+
|
6
|
+
include Muby::Configurable
|
7
|
+
include Muby::Displayer
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
|
11
|
+
#
|
12
|
+
# Load all user files
|
13
|
+
#
|
14
|
+
conf.load_user_files!
|
15
|
+
|
16
|
+
# Init all the ncurses magic.
|
17
|
+
Ncurses.initscr
|
18
|
+
Ncurses.raw
|
19
|
+
Ncurses.keypad(Ncurses.stdscr, true)
|
20
|
+
Ncurses.noecho
|
21
|
+
Ncurses.refresh
|
22
|
+
if Ncurses.has_colors?
|
23
|
+
Ncurses.start_color
|
24
|
+
end
|
25
|
+
|
26
|
+
# initialize late (to enable changes from $RC_FILE)
|
27
|
+
Muby::OutputWindow.get_instance.go
|
28
|
+
Muby::InputWindow.get_instance.go
|
29
|
+
|
30
|
+
#
|
31
|
+
# Exit commands
|
32
|
+
# If we die by normal death (control-C for example):
|
33
|
+
#
|
34
|
+
at_exit do
|
35
|
+
begin
|
36
|
+
conf.shutdown_triggers.each do |proc|
|
37
|
+
Muby::InputWindow.get_instance.execute(proc)
|
38
|
+
end
|
39
|
+
Muby::InputWindow.get_instance.saveHistory
|
40
|
+
rescue Exception => e
|
41
|
+
exception(e)
|
42
|
+
error("Sleeping 10 seconds before closing")
|
43
|
+
sleep(10)
|
44
|
+
ensure
|
45
|
+
Ncurses.endwin
|
46
|
+
puts "Exiting muby..."
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# The main loop
|
52
|
+
#
|
53
|
+
begin
|
54
|
+
Muby::InputWindow.get_instance.process
|
55
|
+
rescue SystemExit => ex
|
56
|
+
violentDeath = false
|
57
|
+
raise ex
|
58
|
+
rescue Exception => error
|
59
|
+
exception(error)
|
60
|
+
error("Sleeping 10 seconds before closing")
|
61
|
+
sleep(10)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Muby
|
2
|
+
|
3
|
+
class Completer
|
4
|
+
|
5
|
+
attr_reader :completions
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@completions = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
@@instance = Muby::Completer.new
|
12
|
+
|
13
|
+
def self.get_instance
|
14
|
+
@@instance
|
15
|
+
end
|
16
|
+
|
17
|
+
def complete(s)
|
18
|
+
subhash = find_subhash(s, @completions) || {}
|
19
|
+
find_endings(s, subhash)
|
20
|
+
end
|
21
|
+
|
22
|
+
def store(s)
|
23
|
+
s.split(/\W+/).each do |part|
|
24
|
+
store_in_hash(part, @completions) unless part.empty?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def find_endings(s, hash)
|
29
|
+
return_value = []
|
30
|
+
hash.each do |char, value|
|
31
|
+
if char == :end
|
32
|
+
return_value << s
|
33
|
+
else
|
34
|
+
return_value |= find_endings(s + char, value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
return_value
|
38
|
+
end
|
39
|
+
|
40
|
+
def find_subhash(s, hash)
|
41
|
+
return {} if hash.nil?
|
42
|
+
if s.size == 0
|
43
|
+
hash
|
44
|
+
else
|
45
|
+
rval = find_subhash(s[1..-1], hash[s[0..0]])
|
46
|
+
rval.merge(find_subhash(s[1..-1], hash[s[0..0].swapcase]))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def store_in_hash(s, hash)
|
51
|
+
if s.size == 1
|
52
|
+
hash[s] ||= {}
|
53
|
+
hash[s][:end] = true
|
54
|
+
else
|
55
|
+
hash[s[0..0]] ||= {}
|
56
|
+
store_in_hash(s[1..-1], hash[s[0..0]])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,379 @@
|
|
1
|
+
|
2
|
+
require 'ncurses'
|
3
|
+
|
4
|
+
module Muby
|
5
|
+
|
6
|
+
VERSION = "0.6.6"
|
7
|
+
|
8
|
+
#
|
9
|
+
# The class that encapsulates all configuration.
|
10
|
+
#
|
11
|
+
# To simplify its use, include Muby::Configurable in your class.
|
12
|
+
# Then you can access Configuration as 'conf' (nice shorthand :)
|
13
|
+
#
|
14
|
+
# All options in Configuration are get'able and set'able.
|
15
|
+
#
|
16
|
+
# Look in help.rb to get the meaning of them.
|
17
|
+
#
|
18
|
+
class Configuration
|
19
|
+
|
20
|
+
@@instance = nil
|
21
|
+
|
22
|
+
def self.get
|
23
|
+
@@instance ||= Configuration.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
#
|
28
|
+
# verbosity options
|
29
|
+
#
|
30
|
+
|
31
|
+
@extra_verbosity_settings = {
|
32
|
+
:echo_keycodes => true,
|
33
|
+
:echo => true,
|
34
|
+
:show_level => :debug,
|
35
|
+
:timestamp => true,
|
36
|
+
:connection_status => true
|
37
|
+
}
|
38
|
+
|
39
|
+
@output_window_geometry = {
|
40
|
+
:top => 0,
|
41
|
+
:left => 0,
|
42
|
+
:width => "Ncurses.COLS",
|
43
|
+
:height => "Ncurses.LINES - Muby::InputWindow.get_instance.height"
|
44
|
+
}
|
45
|
+
|
46
|
+
@input_window_geometry = {
|
47
|
+
:top => "Ncurses.LINES - conf.input_height - 2",
|
48
|
+
:left => 0,
|
49
|
+
:width => "Ncurses.COLS",
|
50
|
+
:height => "conf.input_height + 2"
|
51
|
+
}
|
52
|
+
|
53
|
+
@echo_keycodes = false
|
54
|
+
|
55
|
+
@echo = true
|
56
|
+
|
57
|
+
@show_level = :info
|
58
|
+
|
59
|
+
@timestamp = false
|
60
|
+
|
61
|
+
@connection_status = true
|
62
|
+
|
63
|
+
#
|
64
|
+
# options to control what you see
|
65
|
+
#
|
66
|
+
|
67
|
+
@disable_blink = false
|
68
|
+
|
69
|
+
@timeformat = "%H:%M:%S"
|
70
|
+
|
71
|
+
@broken_keycodes = {
|
72
|
+
13 => true
|
73
|
+
}
|
74
|
+
|
75
|
+
@max_history = 100
|
76
|
+
|
77
|
+
@default_attributes = Ncurses.const_get("A_NORMAL")
|
78
|
+
@default_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]
|
79
|
+
|
80
|
+
@echo_attributes = Ncurses.const_get("A_BOLD")
|
81
|
+
@echo_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]
|
82
|
+
|
83
|
+
@trace_attributes = Ncurses.const_get("A_NORMAL")
|
84
|
+
@trace_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]
|
85
|
+
|
86
|
+
@debug_attributes = Ncurses.const_get("A_NORMAL")
|
87
|
+
@debug_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]
|
88
|
+
|
89
|
+
@info_attributes = Ncurses.const_get("A_NORMAL")
|
90
|
+
@info_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]
|
91
|
+
|
92
|
+
@warn_attributes = Ncurses.const_get("A_NORMAL")
|
93
|
+
@warn_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]
|
94
|
+
|
95
|
+
@error_attributes = Ncurses.const_get("A_NORMAL")
|
96
|
+
@error_colors = [Ncurses.const_get("COLOR_WHITE"), Ncurses.const_get("COLOR_BLACK")]
|
97
|
+
|
98
|
+
@flush = true
|
99
|
+
|
100
|
+
@gags = []
|
101
|
+
|
102
|
+
@anti_gags = []
|
103
|
+
|
104
|
+
@remote_substitutions = {}
|
105
|
+
|
106
|
+
@local_substitutions = {}
|
107
|
+
|
108
|
+
#
|
109
|
+
# options to control what gets run when #
|
110
|
+
#
|
111
|
+
|
112
|
+
@startup_triggers = []
|
113
|
+
|
114
|
+
@connect_triggers = []
|
115
|
+
|
116
|
+
@shutdown_triggers = []
|
117
|
+
|
118
|
+
@remote_triggers = {}
|
119
|
+
|
120
|
+
@remote_character_triggers = {}
|
121
|
+
|
122
|
+
@local_triggers = {
|
123
|
+
/^\/(.*)\n$/m => :execute_command!,
|
124
|
+
/^!(.*)\n$/m => :shell_command!,
|
125
|
+
/^#.*\n$/m => :ignore_command!
|
126
|
+
}
|
127
|
+
|
128
|
+
@key_commands = {
|
129
|
+
#18 => :resize, # ctrl-l
|
130
|
+
Ncurses.const_get("KEY_PPAGE") => :scroll_up!,
|
131
|
+
Ncurses.const_get("KEY_NPAGE") => :scroll_down!,
|
132
|
+
Ncurses.const_get("KEY_ENTER") => :process_buffer!,
|
133
|
+
10 => :process_buffer!, # enter
|
134
|
+
3 => :two_step_quit!, # ctrl-c
|
135
|
+
9 => :complete!, # tab
|
136
|
+
18 => :toggle_history_search!, # ctrl-r
|
137
|
+
127 => :backspace_buffer!, # backspace
|
138
|
+
Ncurses.const_get("KEY_BACKSPACE") => :backspace_buffer!,
|
139
|
+
27 => {
|
140
|
+
91 => {
|
141
|
+
53 => {
|
142
|
+
68 => :previous_word_buffer!, # ctrl-key_left
|
143
|
+
67 => :next_word_buffer!, # ctrl-key_right
|
144
|
+
}
|
145
|
+
}
|
146
|
+
},
|
147
|
+
Ncurses.const_get("KEY_DC") => :delete_buffer!,
|
148
|
+
Ncurses.const_get("KEY_UP") => :previous_history_buffer!,
|
149
|
+
Ncurses.const_get("KEY_DOWN") => :next_history_buffer!,
|
150
|
+
262 => :home_buffer!, # home_key
|
151
|
+
360 => :end_buffer!, # end_key
|
152
|
+
Ncurses.const_get("KEY_LEFT") => :previous_character_buffer!,
|
153
|
+
Ncurses.const_get("KEY_RIGHT") => :next_character_buffer!,
|
154
|
+
22 => :toggle_verbosity!, # ctrl-v
|
155
|
+
265 => :help # f1
|
156
|
+
}
|
157
|
+
|
158
|
+
#
|
159
|
+
# miscellaneous options #
|
160
|
+
#
|
161
|
+
|
162
|
+
@feed_completer_with_history = true
|
163
|
+
|
164
|
+
@feed_completer_with_input = true
|
165
|
+
|
166
|
+
@extra_completions = []
|
167
|
+
|
168
|
+
@loaded_rc_file = false
|
169
|
+
|
170
|
+
@user_edited_config_file = false
|
171
|
+
|
172
|
+
@userdir = File.join(ENV["HOME"], "mubyrc.d")
|
173
|
+
|
174
|
+
@history_file = File.join(@userdir, "history")
|
175
|
+
|
176
|
+
@output_buffer = 1000
|
177
|
+
|
178
|
+
@input_height = 3
|
179
|
+
|
180
|
+
@input_logfile = nil
|
181
|
+
|
182
|
+
@output_logfile = nil
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
#
|
187
|
+
# The magical method that lets us get and set the settings without
|
188
|
+
# having to write getters and setters for all of them
|
189
|
+
#
|
190
|
+
def method_missing(*args)
|
191
|
+
method_name = args[0].to_s
|
192
|
+
var_name = method_name[/^[^=]*/]
|
193
|
+
|
194
|
+
setter = method_name =~ /=$/
|
195
|
+
if setter
|
196
|
+
return super unless args.size == 2
|
197
|
+
instance_variable_set("@#{var_name}", args[1])
|
198
|
+
return args[1]
|
199
|
+
else
|
200
|
+
return super unless args.size == 1
|
201
|
+
return instance_variable_get("@#{var_name}")
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
#
|
206
|
+
# The halfway magical method that toggles all settings covered in
|
207
|
+
# @extra_verbosity_settings to what they are in that hash,
|
208
|
+
# and then stores them away inside the same hash for back-toggling again.
|
209
|
+
#
|
210
|
+
def toggle_verbosity!
|
211
|
+
|
212
|
+
# copy old extra-settings to a copy
|
213
|
+
settings_copy = @extra_verbosity_settings.clone
|
214
|
+
|
215
|
+
# set our extra-settings to be the currently applied settings
|
216
|
+
@extra_verbosity_settings.clone.each do |key, value|
|
217
|
+
@extra_verbosity_settings[key] = self.send(key)
|
218
|
+
end
|
219
|
+
|
220
|
+
# apply the extra-settings
|
221
|
+
settings_copy.each do |key, value|
|
222
|
+
self.send("#{key}=", value)
|
223
|
+
end
|
224
|
+
|
225
|
+
Muby::Displayer.info("Toggled verbosity. Press <key> again to toggle back.")
|
226
|
+
end
|
227
|
+
|
228
|
+
#
|
229
|
+
# Returns true if we are supposed to display messages
|
230
|
+
# of +level+.
|
231
|
+
#
|
232
|
+
def display?(level)
|
233
|
+
levels = [:trace, :debug, :info, :warn, :error]
|
234
|
+
levels.index(level) >= (levels.index(@show_level) || 0)
|
235
|
+
end
|
236
|
+
|
237
|
+
#
|
238
|
+
# Will save the current configuration to the loaded rc file,
|
239
|
+
# or to mubyrc if no such file was loaded.
|
240
|
+
#
|
241
|
+
def save_configuration_file!
|
242
|
+
to_save = @loaded_rc_file ? @loaded_rc_file : File.join(ENV["HOME"], "mubyrc")
|
243
|
+
begin
|
244
|
+
Kernel::open(to_save, "w") do |output|
|
245
|
+
output.write(self.to_ruby)
|
246
|
+
@loaded_rc_file = to_save
|
247
|
+
end
|
248
|
+
Muby::Displayer.info("Saved default configuration to #{to_save}.")
|
249
|
+
rescue Exception => e
|
250
|
+
Muby::Displayer.warn("Failed saving default configuration to #{to_save}: #{e.message}")
|
251
|
+
Muby::Displayer.debug(e.backtrace.join("\n"))
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
#
|
256
|
+
# Tries to load all the users files, defined as
|
257
|
+
# any file named .mubyrc or mubyrc in the users ENV["HOME"]
|
258
|
+
# and all **/*.rb files in the users ENV["HOME"]/@userdir
|
259
|
+
# with the root of the userdir taking precidence over subdirectories.
|
260
|
+
# Directories starting with a . are ignored.
|
261
|
+
#
|
262
|
+
# If none of the mubyrc-files existed, it will try to create one
|
263
|
+
# for the user to edit to his/her liking.
|
264
|
+
#
|
265
|
+
def load_user_files!
|
266
|
+
@loaded_rc_file = false
|
267
|
+
if to_load = [".mubyrc", "mubyrc"].find do |file_name|
|
268
|
+
File.exists?(File.join(ENV["HOME"], file_name))
|
269
|
+
end
|
270
|
+
nice_load!(to_load)
|
271
|
+
@loaded_rc_file = to_load
|
272
|
+
end
|
273
|
+
|
274
|
+
unless @loaded_rc_file
|
275
|
+
save_configuration_file!
|
276
|
+
end
|
277
|
+
|
278
|
+
if File.exists?(@userdir)
|
279
|
+
# Only load *.rb files within sub-directories of the current directory, and not the current directory's *.rb files!)
|
280
|
+
# Test: Dir[File.join(Dir.pwd, "*", "**", "*.rb")].each do |f| puts f end ; nil
|
281
|
+
Dir[File.join(@userdir, "*", "**", "*.rb")].each do |file_name|
|
282
|
+
nice_load!(file_name)
|
283
|
+
end
|
284
|
+
# Only load *.rb files of the current directory.
|
285
|
+
# This is very useful for users to create "overrides" for items in subdirectories.
|
286
|
+
# NOTE: This does follow symbolic links (files and directories)
|
287
|
+
# Test: Dir[File.join(Dir.pwd, "*.rb")].each do |f| puts f end ; nil
|
288
|
+
Dir[File.join(@userdir, "*.rb")].each do |file_name|
|
289
|
+
nice_load!(file_name)
|
290
|
+
end
|
291
|
+
else
|
292
|
+
Muby::Displayer.warn("#{@userdir} does not exist. If it did, *.rb in it would be loaded now.")
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
#
|
297
|
+
# A non-raising method that tries to load +f+ and tells the output window about its success.
|
298
|
+
#
|
299
|
+
def nice_load!(f)
|
300
|
+
begin
|
301
|
+
Kernel::load(f)
|
302
|
+
Muby::Displayer.info("Loaded #{f}")
|
303
|
+
rescue Exception => e
|
304
|
+
Muby::Displayer.exception(e)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
#
|
309
|
+
# Will reload the entire app, ie the class files and the
|
310
|
+
# user files.
|
311
|
+
#
|
312
|
+
# TODO: Remove the spammyness.
|
313
|
+
# It is not appropriate to use 'puts' when reload_application! is being called by the user.
|
314
|
+
# To turn off "uninitialised constant" warnings, do: $VERBOSE = nil
|
315
|
+
#
|
316
|
+
# Simply set your show_level to :warn instead of :info, and you wont see the load messages.
|
317
|
+
#
|
318
|
+
# Any other messages come from your own files :O
|
319
|
+
#
|
320
|
+
def reload_application!
|
321
|
+
Dir[File.join(File.dirname(__FILE__), "**", "*.rb")].each do |file_name|
|
322
|
+
nice_load! file_name
|
323
|
+
end
|
324
|
+
load_user_files!
|
325
|
+
end
|
326
|
+
|
327
|
+
#
|
328
|
+
# The not so magical at all method that prints our content
|
329
|
+
# to a String so that we easily can save our current settings
|
330
|
+
# in a file, or create a default config file.
|
331
|
+
#
|
332
|
+
def to_ruby
|
333
|
+
"#
|
334
|
+
# This is the default configuration of muby.
|
335
|
+
# To learn more about how to configure it, you
|
336
|
+
# can type '/help' in the client.
|
337
|
+
#
|
338
|
+
include Muby::Configurable
|
339
|
+
" +
|
340
|
+
instance_variables.sort.collect do |var_name|
|
341
|
+
value = eval(var_name)
|
342
|
+
case value
|
343
|
+
when Hash
|
344
|
+
space = "conf.#{var_name[1..-1]} = _".size
|
345
|
+
value = value.inspect.gsub(/, /, ",\n#{" " * space}")
|
346
|
+
when File
|
347
|
+
begin
|
348
|
+
value.read(0)
|
349
|
+
value = "open(\"#{value.path}\", \"r\")"
|
350
|
+
rescue
|
351
|
+
value = "open(\"#{value.path}\", \"a\")"
|
352
|
+
end
|
353
|
+
when NilClass
|
354
|
+
value = value.inspect
|
355
|
+
else
|
356
|
+
value = value.inspect
|
357
|
+
end
|
358
|
+
var_name = var_name[1..-1]
|
359
|
+
help_text = Muby::Help.configuration[var_name.to_sym] || "no help available for #{var_name}"
|
360
|
+
help_text = help_text.split("\n").join("\n# ")
|
361
|
+
"
|
362
|
+
# #{help_text}
|
363
|
+
conf.#{var_name} = #{value}"
|
364
|
+
end.join("\n")
|
365
|
+
end
|
366
|
+
|
367
|
+
end
|
368
|
+
|
369
|
+
#
|
370
|
+
# The module that provides the shorthand for
|
371
|
+
# using classes.
|
372
|
+
#
|
373
|
+
module Configurable
|
374
|
+
def conf
|
375
|
+
Configuration.get
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
end
|