brice 0.1.1 → 0.2.0

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.
@@ -0,0 +1,168 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # A component of brice, the extra cool IRb goodness donator #
5
+ # #
6
+ # Copyright (C) 2008-2011 Jens Wille #
7
+ # #
8
+ # Authors: #
9
+ # Jens Wille <jens.wille@uni-koeln.de> #
10
+ # #
11
+ # brice is free software: you can redistribute it and/or modify it under the #
12
+ # terms of the GNU Affero General Public License as published by the Free #
13
+ # Software Foundation, either version 3 of the License, or (at your option) #
14
+ # any later version. #
15
+ # #
16
+ # brice is distributed in the hope that it will be useful, but WITHOUT ANY #
17
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
18
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
19
+ # more details. #
20
+ # #
21
+ # You should have received a copy of the GNU Affero General Public License #
22
+ # along with brice. If not, see <http://www.gnu.org/licenses/>. #
23
+ # #
24
+ ###############################################################################
25
+ #++
26
+
27
+ require 'brice'
28
+
29
+ module Brice
30
+
31
+ # IRb history support.
32
+
33
+ class History
34
+
35
+ DEFAULTS = {
36
+ :path => ENV['IRB_HISTORY_FILE'] || File.join(ENV.user_home, '.irb_history'),
37
+ :size => (ENV['IRB_HISTORY_SIZE'] || 1000).to_i,
38
+ :perms => File::WRONLY | File::CREAT | File::TRUNC,
39
+ :uniq => :reverse,
40
+ :merge => true
41
+ }
42
+
43
+ def self.init(opt = {})
44
+ new(opt)
45
+ end
46
+
47
+ def initialize(opt = {}, history = defined?(Readline::HISTORY) && Readline::HISTORY)
48
+ DEFAULTS.each { |key, val|
49
+ instance_variable_set("@#{key}", Brice.opt(opt, key, val))
50
+ }
51
+
52
+ @path = File.expand_path(@path)
53
+ @reverse = @uniq.to_s == 'reverse'
54
+
55
+ init_history(history) if history
56
+ end
57
+
58
+ private
59
+
60
+ def init_history(history)
61
+ @history = history
62
+
63
+ @libedit = begin
64
+ Readline.emacs_editing_mode
65
+ true
66
+ rescue NotImplementedError
67
+ false
68
+ end
69
+
70
+ load_history
71
+ extend_history
72
+
73
+ Kernel.at_exit { save_history }
74
+ end
75
+
76
+ def read_history
77
+ File.foreach(@path) { |line|
78
+ line.chomp!
79
+ yield line
80
+ }
81
+ end
82
+
83
+ def load_history(history = @history)
84
+ return unless File.readable?(@path)
85
+ read_history { |line| history << line }
86
+
87
+ return unless @libedit
88
+ @first_line = read_history { |line| break line }
89
+ end
90
+
91
+ def extend_history
92
+ @history.extend(Tee) if @merge && class << @history; !include?(Tee); end
93
+ end
94
+
95
+ def save_history
96
+ if @merge
97
+ load_history(lines = [])
98
+ @history.tee! { |t| lines.concat(t) }
99
+ else
100
+ lines = @history.to_a
101
+ end
102
+
103
+ lines.unshift(@first_line) if @first_line
104
+
105
+ lines.reverse! if @reverse
106
+ lines.uniq! if @uniq
107
+ lines.reverse! if @reverse
108
+
109
+ lines.slice!(0, lines.size - @size)
110
+
111
+ File.open(@path, @perms) { |f| f.puts(lines) }
112
+ end
113
+
114
+ module Tee
115
+
116
+ def self.extended(base)
117
+ class << base
118
+ alias_method :push_without_tee, :<<
119
+ alias_method :push_m_without_tee, :push
120
+
121
+ alias_method :<<, :push_with_tee
122
+ alias_method :push, :push_m_with_tee
123
+ end
124
+ end
125
+
126
+ def tee
127
+ @tee ||= []
128
+ end
129
+
130
+ def tee!
131
+ yield tee
132
+ ensure
133
+ tee.clear
134
+ end
135
+
136
+ def push_with_tee(arg)
137
+ _tee_delete(arg)
138
+
139
+ tee << arg
140
+ push_without_tee(arg)
141
+ end
142
+
143
+ def push_m_with_tee(*args)
144
+ _tee_delete(*args)
145
+
146
+ tee.concat(args)
147
+ push_m_without_tee(*args)
148
+ end
149
+
150
+ private
151
+
152
+ def _tee_delete(*args)
153
+ args.each { |arg| tee.delete(arg) }
154
+
155
+ indexes = []
156
+
157
+ each_with_index { |line, index|
158
+ indexes << index if args.include?(line)
159
+ }
160
+
161
+ indexes.reverse_each { |index| delete_at(index) }
162
+ end
163
+
164
+ end
165
+
166
+ end
167
+
168
+ end
@@ -0,0 +1,17 @@
1
+ # Load AddedMethods[http://added_methods.rubyforge.org/] if one
2
+ # (or both) of the following environment variables has been set:
3
+ #
4
+ # <tt>WATCH_FOR_ADDED_METHODS</tt>:: Regular expression or <tt>true</tt>
5
+ # <tt>WATCH_FOR_ADDED_METHODS_IN</tt>:: Space- or comma-delimited list of class names
6
+
7
+ brice 'added_methods' do |config|
8
+
9
+ pattern = ENV['WATCH_FOR_ADDED_METHODS']
10
+ list = ENV['WATCH_FOR_ADDED_METHODS_IN']
11
+
12
+ AddedMethods.init(
13
+ (pattern != 'true' || list) && Regexp.new(pattern || ''),
14
+ (list || '').split(/\s|,/).reject { |name| name.empty? }
15
+ ) if pattern || list
16
+
17
+ end
@@ -2,15 +2,14 @@
2
2
 
3
3
  brice 'libs' => nil do |config|
4
4
 
5
- libs = config.entries
6
- libs = %w[
5
+ (config.empty? ? %w[
6
+ pp
7
7
  yaml
8
8
  tempfile
9
9
  benchmark
10
10
  backports
11
11
  what_methods
12
- ] if libs.empty?
13
-
14
- libs.each { |lib| brice_require lib }
12
+ irb/completion
13
+ ] : config).each { |lib| brice_require lib }
15
14
 
16
15
  end
@@ -0,0 +1,7 @@
1
+ # Configure IRb history support
2
+
3
+ brice 'history' => 'brice/history' do |config|
4
+
5
+ Brice::History.init(config.opt)
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ # Configure IRb colour support
2
+
3
+ brice 'colours' => 'brice/colours' do |config|
4
+
5
+ Brice::Colours.init(config.opt)
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ # Include convenient shortcut methods
2
+
3
+ brice 'shortcuts' => 'brice/shortcuts' do |config|
4
+
5
+ Brice::Shortcuts.init(config.opt)
6
+
7
+ end
@@ -0,0 +1,9 @@
1
+ # Basic initialization for IRb
2
+
3
+ brice 'init' => nil do |config|
4
+
5
+ $KCODE = 'u' if RUBY_VERSION < '1.9'
6
+
7
+ IRB.conf[:AUTO_INDENT] = true
8
+
9
+ end
@@ -18,7 +18,7 @@ brice 'prompt' => nil do |config|
18
18
  end
19
19
  end
20
20
 
21
- IRB.conf[:PROMPT] ||= {} # prevent error in webrick
21
+ IRB.conf[:PROMPT] ||= {}
22
22
 
23
23
  # prompt configuration:
24
24
  #
@@ -18,7 +18,7 @@ brice 'rails' => nil do |config|
18
18
  prompt = File.basename(Dir.pwd) << hint
19
19
  end
20
20
 
21
- # add "ENV['RAILS_SANDBOX'] = 'true'" in rails-X.X.X/lib/commands/console.rb
21
+ # add "ENV['RAILS_SANDBOX'] = 'true'" in rails/lib/commands/console.rb
22
22
  prompt << "#{ENV['RAILS_SANDBOX'] ? '>' : '$'} "
23
23
 
24
24
  IRB.conf[:PROMPT] ||= {}
File without changes
@@ -0,0 +1,110 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # A component of brice, the extra cool IRb goodness donator #
5
+ # #
6
+ # Copyright (C) 2008-2011 Jens Wille #
7
+ # #
8
+ # Authors: #
9
+ # Jens Wille <jens.wille@uni-koeln.de> #
10
+ # #
11
+ # brice is free software: you can redistribute it and/or modify it under the #
12
+ # terms of the GNU Affero General Public License as published by the Free #
13
+ # Software Foundation, either version 3 of the License, or (at your option) #
14
+ # any later version. #
15
+ # #
16
+ # brice is distributed in the hope that it will be useful, but WITHOUT ANY #
17
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
18
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
19
+ # more details. #
20
+ # #
21
+ # You should have received a copy of the GNU Affero General Public License #
22
+ # along with brice. If not, see <http://www.gnu.org/licenses/>. #
23
+ # #
24
+ ###############################################################################
25
+ #++
26
+
27
+ require 'brice'
28
+
29
+ module Brice
30
+
31
+ # Convenient shortcut methods.
32
+ module Shortcuts
33
+
34
+ extend self
35
+
36
+ def init(opt = {})
37
+ init_object if Brice.opt(opt, :object)
38
+ init_ri if Brice.opt(opt, :ri)
39
+ end
40
+
41
+ def init_object
42
+ Object.send(:include, ObjectShortcuts)
43
+ end
44
+
45
+ def init_ri
46
+ Module.class_eval {
47
+ def ri(*args)
48
+ ri!('--no-pager', *args)
49
+ end
50
+
51
+ def ri!(*args)
52
+ opts, args = args.partition { |arg| arg.to_s =~ /\A--/ }
53
+
54
+ args.empty? ? args << name : args.map! { |arg|
55
+ arg, method = arg.to_s, nil
56
+
57
+ delim = [['#', :instance_method], ['::', :method]].find { |i, m|
58
+ match = arg.sub!(/\A#{i}/, '')
59
+ method = begin; send(m, arg); rescue NameError; end
60
+
61
+ break i if match || method
62
+ } or next arg
63
+
64
+ "#{method && method.to_s[/\((\w+)\)/, 1] || name}#{delim}#{arg}"
65
+ }
66
+
67
+ system('ri', *opts.concat(args))
68
+ end
69
+ }
70
+
71
+ instance_eval {
72
+ def ri(*args); Kernel.ri(*args); end
73
+ def ri!(*args); Kernel.ri!(*args); end
74
+ }
75
+ end
76
+
77
+ module ObjectShortcuts
78
+
79
+ # Print object methods, sorted by name. (excluding methods that
80
+ # exist in the class Object)
81
+ def po(obj = self)
82
+ obj.methods.sort - Object.methods
83
+ end
84
+
85
+ # Print object constants, sorted by name.
86
+ def poc(obj = self)
87
+ obj.constants.sort if obj.respond_to?(:constants)
88
+ end
89
+
90
+ # Cf. <http://rubyforge.org/snippet/detail.php?type=snippet&id=22>
91
+ def aorta(obj = self)
92
+ tempfile = Tempfile.new('aorta')
93
+ YAML.dump(obj, tempfile)
94
+ tempfile.close
95
+
96
+ path = tempfile.path
97
+
98
+ system(ENV['VISUAL'] || ENV['EDITOR'] || 'vi', path)
99
+ return obj unless File.exists?(path)
100
+
101
+ content = YAML.load_file(path)
102
+ tempfile.unlink
103
+ content
104
+ end
105
+
106
+ end
107
+
108
+ end
109
+
110
+ end
data/lib/brice/version.rb CHANGED
@@ -1,10 +1,10 @@
1
- class Brice
1
+ module Brice
2
2
 
3
3
  module Version
4
4
 
5
5
  MAJOR = 0
6
- MINOR = 1
7
- TINY = 1
6
+ MINOR = 2
7
+ TINY = 0
8
8
 
9
9
  class << self
10
10
 
data/lib/brice.rb CHANGED
@@ -25,146 +25,156 @@
25
25
  #++
26
26
 
27
27
  require 'irb'
28
- require 'rubygems'
29
28
  require 'nuggets/env/user_home'
30
29
 
31
- %w[config dsl version].each { |lib|
32
- lib = "brice/#{lib}"
33
- require lib
34
- }
30
+ require 'brice/version'
35
31
 
36
- class Brice
32
+ module Brice
33
+
34
+ autoload :Config, 'brice/config'
35
+ autoload :Colours, 'brice/colours'
36
+ autoload :DSL, 'brice/dsl'
37
+ autoload :History, 'brice/history'
38
+ autoload :Shortcuts, 'brice/shortcuts'
39
+
40
+ RC_DIR = __FILE__.sub(/\.rb\z/, '/rc')
37
41
 
38
42
  BRICE_HOME = File.join(ENV.user_home, '.brice')
39
43
 
40
44
  @verbose = false
41
45
  @quiet = false
42
46
 
43
- class << self
44
-
45
- include DSL
47
+ extend self
48
+ include DSL
46
49
 
47
- attr_reader :config, :irb_rc
50
+ attr_reader :config, :irb_rc
48
51
 
49
- attr_accessor :verbose, :quiet
52
+ attr_accessor :verbose, :quiet
50
53
 
51
- # call-seq:
52
- # Brice.init { |config| ... }
53
- # Brice.init(:verbose => true) { |config| ... }
54
- #
55
- # Initialize Brice and optionally configure any packages.
56
- def init(options = {})
57
- @irb_rc = []
58
- @config = Config.new(rc_files(true).map { |rc|
59
- File.basename(rc, '.rb').sub(/\A\d+_/, '')
60
- })
54
+ # call-seq:
55
+ # Brice.init { |config| ... }
56
+ # Brice.init(:verbose => true) { |config| ... }
57
+ #
58
+ # Initialize Brice and optionally configure any packages.
59
+ def init(options = {})
60
+ @irb_rc = []
61
61
 
62
- options.each { |key, value|
63
- method = "#{key}="
62
+ @config = Config.new(rc_files(true).map { |rc|
63
+ File.basename(rc, '.rb').sub(/\A\d+_/, '')
64
+ })
64
65
 
65
- if respond_to?(method)
66
- send(method, value)
67
- else
68
- raise ArgumentError, "illegal option: #{key}"
69
- end
70
- }
66
+ options.each { |key, value|
67
+ if respond_to?(method = "#{key}=")
68
+ send(method, value)
69
+ else
70
+ raise ArgumentError, "illegal option: #{key}"
71
+ end
72
+ }
71
73
 
72
- yield config if block_given?
74
+ yield config if block_given?
73
75
 
74
- load_rc_files(true)
75
- finalize_irb_rc!
76
+ load_rc_files(true)
77
+ finalize_irb_rc!
76
78
 
77
- config
78
- end
79
-
80
- # call-seq:
81
- # Brice.config = config
82
- #
83
- # Set config to +config+. Raises a TypeError if +config+ is not a
84
- # Brice::Config.
85
- def config=(config)
86
- raise TypeError, "expected Brice::Config, got #{config.class}" \
87
- unless config.is_a?(Config)
79
+ config
80
+ end
88
81
 
82
+ # call-seq:
83
+ # Brice.config = config
84
+ #
85
+ # Set config to +config+. Raises a TypeError if +config+ is not a
86
+ # Brice::Config.
87
+ def config=(config)
88
+ if config.is_a?(Config)
89
89
  @config = config
90
+ else
91
+ raise TypeError, "expected Brice::Config, got #{config.class}"
90
92
  end
93
+ end
91
94
 
92
- # call-seq:
93
- # Brice.include?(package) => true or false
94
- # Brice.have?(package) => true or false
95
- #
96
- # See whether package +package+ is enabled/included.
97
- def include?(package)
98
- config.include?(package)
99
- end
95
+ # call-seq:
96
+ # Brice.include?(package) => true or false
97
+ # Brice.have?(package) => true or false
98
+ #
99
+ # See whether package +package+ is enabled/included.
100
+ def include?(package)
101
+ config.include?(package)
102
+ end
100
103
 
101
- alias_method :have?, :include?
104
+ alias_method :have?, :include?
102
105
 
103
- # call-seq:
104
- # Brice.rc_files(include_custom_extensions = false) => anArray
105
- #
106
- # Get the extension files, optionally including custom extensions
107
- # if +include_custom_extensions+ is true.
108
- def rc_files(include_custom_extensions = false)
109
- @rc_files ||= find_rc_files
110
- include_custom_extensions ? @rc_files + custom_extensions : @rc_files
111
- end
106
+ # call-seq:
107
+ # Brice.rc_files(include_custom_extensions = false) => anArray
108
+ #
109
+ # Get the extension files, optionally including custom extensions
110
+ # if +include_custom_extensions+ is true.
111
+ def rc_files(include_custom_extensions = false)
112
+ @rc_files ||= find_rc_files
113
+ include_custom_extensions ? @rc_files + custom_extensions : @rc_files
114
+ end
112
115
 
113
- # call-seq:
114
- # Brice.custom_extensions => anArray
115
- #
116
- # Get the custom extension files.
117
- def custom_extensions
118
- @custom_extensions ||= find_rc_files(BRICE_HOME)
119
- end
116
+ # call-seq:
117
+ # Brice.custom_extensions => anArray
118
+ #
119
+ # Get the custom extension files.
120
+ def custom_extensions
121
+ @custom_extensions ||= find_rc_files(BRICE_HOME)
122
+ end
120
123
 
121
- private
124
+ # call-seq:
125
+ # Brice.opt(opt, key, default = true) -> anObject
126
+ #
127
+ # Returns the value of +opt+ at +key+ if present, or +default+
128
+ # otherwise.
129
+ def opt(opt, key, default = true)
130
+ opt.is_a?(Hash) && opt.has_key?(key) ? opt[key] : default
131
+ end
122
132
 
123
- # call-seq:
124
- # load_rc_files(include_custom_extensions = false) => anArray
125
- #
126
- # Load the extension files, optionally including custom extensions
127
- # if +include_custom_extensions+ is true.
128
- def load_rc_files(include_custom_extensions = false)
129
- Object.send(:include, DSL)
133
+ private
130
134
 
131
- res = rc_files.each { |rc|
132
- warn "Loading #{rc}..." if verbose
133
- brice_load rc
134
- }
135
+ # call-seq:
136
+ # load_rc_files(include_custom_extensions = false) => anArray
137
+ #
138
+ # Load the extension files, optionally including custom extensions
139
+ # if +include_custom_extensions+ is true.
140
+ def load_rc_files(include_custom_extensions = false)
141
+ Object.send(:include, DSL)
135
142
 
136
- include_custom_extensions ? res += load_custom_extensions : res
137
- end
143
+ res = rc_files.each { |rc|
144
+ warn "Loading #{rc}..." if verbose
145
+ brice_load rc
146
+ }
138
147
 
139
- # call-seq:
140
- # load_custom_extensions => anArray
141
- #
142
- # Load the custom extension files.
143
- def load_custom_extensions
144
- custom_extensions.each { |rc|
145
- warn "Loading custom #{rc}..." if verbose
146
- brice_load rc
147
- }
148
- end
148
+ include_custom_extensions ? res += load_custom_extensions : res
149
+ end
149
150
 
150
- # call-seq:
151
- # find_rc_files(dir = ...) => anArray
152
- #
153
- # Find the actual extension files in +dir+.
154
- def find_rc_files(dir = File.join(File.dirname(__FILE__), 'rc'))
155
- File.directory?(dir) ? Dir["#{dir}/*.rb"].sort : []
156
- end
151
+ # call-seq:
152
+ # load_custom_extensions => anArray
153
+ #
154
+ # Load the custom extension files.
155
+ def load_custom_extensions
156
+ custom_extensions.each { |rc|
157
+ warn "Loading custom #{rc}..." if verbose
158
+ brice_load rc
159
+ }
160
+ end
157
161
 
158
- # call-seq:
159
- # finalize_irb_rc! => aProc
160
- #
161
- # Generate proc for IRB_RC from all added procs.
162
- def finalize_irb_rc!
163
- IRB.conf[:IRB_RC] = lambda { |context|
164
- irb_rc.each { |rc| rc[context] }
165
- } unless irb_rc.empty?
166
- end
162
+ # call-seq:
163
+ # find_rc_files(dir = ...) => anArray
164
+ #
165
+ # Find the actual extension files in +dir+.
166
+ def find_rc_files(dir = RC_DIR)
167
+ File.directory?(dir) ? Dir["#{dir}/*.rb"].sort : []
168
+ end
167
169
 
170
+ # call-seq:
171
+ # finalize_irb_rc! => aProc
172
+ #
173
+ # Generate proc for IRB_RC from all added procs.
174
+ def finalize_irb_rc!
175
+ IRB.conf[:IRB_RC] = lambda { |context|
176
+ irb_rc.each { |rc| rc[context] }
177
+ } unless irb_rc.empty?
168
178
  end
169
179
 
170
180
  end