brice 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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