brice 0.2.8 → 0.4.2
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.
- checksums.yaml +5 -5
- data/ChangeLog +18 -0
- data/README +6 -8
- data/Rakefile +12 -9
- data/lib/brice.rb +28 -26
- data/lib/brice/colours.rb +234 -232
- data/lib/brice/config.rb +2 -3
- data/lib/brice/dsl.rb +1 -3
- data/lib/brice/history.rb +8 -8
- data/lib/brice/loud.rb +1 -1
- data/lib/brice/rc/{010_added_methods.rb → 010_added_methods_.rb} +0 -0
- data/lib/brice/rc/{040_colours.rb → 040_colours_.rb} +0 -0
- data/lib/brice/rc/060_init.rb +3 -3
- data/lib/brice/rc/070_prompt.rb +13 -13
- data/lib/brice/rc/080_rails.rb +6 -6
- data/lib/brice/really_loud.rb +1 -1
- data/lib/brice/shortcuts.rb +14 -13
- data/lib/brice/version.rb +2 -2
- data/spec/brice/history_spec.rb +11 -13
- data/spec/spec_helper.rb +3 -2
- metadata +80 -28
- data/.rspec +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 36999aee54c54f1de81d06593f1038074c2b9726c8201752cb692ba28c33a411
|
4
|
+
data.tar.gz: 6dd8b2419fc5e1f0a3192ba5fb3273c1ab9c66f1136d12e27865f4ba0e8104db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d00c57bd13955221544ae079b8fe8f62553419544c716f1492fab2a3850fe4d8a5f92716b9ab5adfecc9c37b78c3716d02ad40c5d438d709e3c71a3408c3670
|
7
|
+
data.tar.gz: 10ab3f892e919a92a29b32e5c4d2064bb3045ea375adfe74648642dbd35af9c0ac9101a754ec31285ca4aa26a1fc3caa766a0c74b5af3a1b1fa46206b1b21afe
|
data/ChangeLog
CHANGED
@@ -1,5 +1,23 @@
|
|
1
|
+
# markup: rd
|
2
|
+
|
1
3
|
= Revision history for brice
|
2
4
|
|
5
|
+
== 0.4.2 [2020-09-17]
|
6
|
+
|
7
|
+
* Ruby 2.7 compatibility.
|
8
|
+
|
9
|
+
== 0.4.1 [2016-03-29]
|
10
|
+
|
11
|
+
* To mark default packages as optional, use underscore in addition to question
|
12
|
+
mark, since the latter is not supported on Windows file systems (issue #10
|
13
|
+
by Hovis Biddle).
|
14
|
+
|
15
|
+
== 0.4.0 [2014-10-31]
|
16
|
+
|
17
|
+
* Require at least Ruby 1.9.3.
|
18
|
+
* Only set prompt if left at default.
|
19
|
+
* Default package +added_methods+ now optional.
|
20
|
+
|
3
21
|
== 0.0.1 [2008-11-14]
|
4
22
|
|
5
23
|
* Birthday :-)
|
data/README
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
== VERSION
|
4
4
|
|
5
|
-
This documentation refers to brice version 0.2
|
5
|
+
This documentation refers to brice version 0.4.2
|
6
6
|
|
7
7
|
|
8
8
|
== DESCRIPTION
|
@@ -15,12 +15,10 @@ in that regard.
|
|
15
15
|
|
16
16
|
Add this to your <tt>~/.irbrc</tt> and receive the default goodness:
|
17
17
|
|
18
|
-
require 'rubygems'
|
19
18
|
require 'brice/init' # equivalent to: require 'brice'; Brice.init
|
20
19
|
|
21
20
|
Or get some more control over the configuration:
|
22
21
|
|
23
|
-
require 'rubygems'
|
24
22
|
require 'brice'
|
25
23
|
|
26
24
|
Brice.init { |config|
|
@@ -64,10 +62,10 @@ guaranteed to have any effect after <tt>Brice.init</tt> has been called.
|
|
64
62
|
|
65
63
|
== LINKS
|
66
64
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
65
|
+
Documentation:: https://blackwinter.github.com/brice
|
66
|
+
Source code:: https://github.com/blackwinter/brice
|
67
|
+
RubyGem:: https://rubygems.org/gems/brice
|
68
|
+
Travis CI:: https://travis-ci.org/blackwinter/brice
|
71
69
|
|
72
70
|
|
73
71
|
== AUTHORS
|
@@ -77,7 +75,7 @@ RubyGem:: http://rubygems.org/gems/brice
|
|
77
75
|
|
78
76
|
== LICENSE AND COPYRIGHT
|
79
77
|
|
80
|
-
Copyright (C) 2008-
|
78
|
+
Copyright (C) 2008-2020 Jens Wille
|
81
79
|
|
82
80
|
brice is free software: you can redistribute it and/or modify it under the
|
83
81
|
terms of the GNU Affero General Public License as published by the Free
|
data/Rakefile
CHANGED
@@ -1,17 +1,20 @@
|
|
1
|
-
|
1
|
+
require_relative 'lib/brice/version'
|
2
2
|
|
3
3
|
begin
|
4
4
|
require 'hen'
|
5
5
|
|
6
6
|
Hen.lay! {{
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
7
|
+
gem: {
|
8
|
+
name: %q{brice},
|
9
|
+
version: Brice::VERSION,
|
10
|
+
summary: %q{Extra cool IRb goodness for the masses},
|
11
|
+
author: %q{Jens Wille},
|
12
|
+
email: %q{jens.wille@gmail.com},
|
13
|
+
license: %q{AGPL-3.0},
|
14
|
+
homepage: :blackwinter,
|
15
|
+
dependencies: { nuggets: '~> 1.6' },
|
16
|
+
|
17
|
+
required_ruby_version: '>= 1.9.3'
|
15
18
|
}
|
16
19
|
}}
|
17
20
|
rescue LoadError => err
|
data/lib/brice.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# #
|
4
4
|
# brice -- Extra cool IRb goodness for the masses #
|
5
5
|
# #
|
6
|
-
# Copyright (C) 2008-
|
6
|
+
# Copyright (C) 2008-2016 Jens Wille #
|
7
7
|
# #
|
8
8
|
# Authors: #
|
9
9
|
# Jens Wille <jens.wille@gmail.com> #
|
@@ -27,16 +27,11 @@
|
|
27
27
|
require 'irb'
|
28
28
|
require 'nuggets/env/user_home'
|
29
29
|
|
30
|
-
|
30
|
+
require_relative 'brice/dsl'
|
31
|
+
require_relative 'brice/version'
|
31
32
|
|
32
33
|
module Brice
|
33
34
|
|
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
35
|
RC_DIR = __FILE__.sub(/\.rb\z/, '/rc')
|
41
36
|
|
42
37
|
BRICE_HOME = File.join(ENV.user_home, '.brice')
|
@@ -53,24 +48,25 @@ module Brice
|
|
53
48
|
|
54
49
|
# call-seq:
|
55
50
|
# Brice.init { |config| ... }
|
56
|
-
# Brice.init(:
|
51
|
+
# Brice.init(verbose: true) { |config| ... }
|
57
52
|
#
|
58
53
|
# Initialize Brice and optionally configure any packages.
|
59
54
|
def init(options = {})
|
60
55
|
@irb_rc = []
|
61
56
|
|
62
|
-
@config = Config.new(rc_files(true).map { |rc|
|
63
|
-
File.basename(rc, '.rb').sub(/\A\d+_/, '')
|
64
|
-
})
|
65
|
-
|
66
57
|
options.each { |key, value|
|
67
|
-
|
68
|
-
|
69
|
-
else
|
70
|
-
raise ArgumentError, "illegal option: #{key}"
|
71
|
-
end
|
58
|
+
respond_to?(set = "#{key}=") ? send(set, value) :
|
59
|
+
raise(ArgumentError, "illegal option: #{key}")
|
72
60
|
}
|
73
61
|
|
62
|
+
packages = rc_files(true).map { |rc|
|
63
|
+
File.basename(rc, '.rb').sub(/\A\d+_/, '')
|
64
|
+
}.reject { |rc| rc.end_with?('?') || rc.end_with?('_') }
|
65
|
+
|
66
|
+
warn "Default packages: #{packages.join(', ')}" if verbose
|
67
|
+
|
68
|
+
@config = Config.new(packages)
|
69
|
+
|
74
70
|
yield config if block_given?
|
75
71
|
|
76
72
|
load_rc_files(true)
|
@@ -85,11 +81,8 @@ module Brice
|
|
85
81
|
# Set config to +config+. Raises a TypeError if +config+ is not a
|
86
82
|
# Brice::Config.
|
87
83
|
def config=(config)
|
88
|
-
|
89
|
-
|
90
|
-
else
|
91
|
-
raise TypeError, "expected Brice::Config, got #{config.class}"
|
92
|
-
end
|
84
|
+
config.is_a?(Config) ? @config = config :
|
85
|
+
raise(TypeError, "Brice::Config expected, got #{config.class}")
|
93
86
|
end
|
94
87
|
|
95
88
|
# call-seq:
|
@@ -127,7 +120,11 @@ module Brice
|
|
127
120
|
# Returns the value of +opt+ at +key+ if present, or +default+
|
128
121
|
# otherwise.
|
129
122
|
def opt(opt, key, default = true)
|
130
|
-
opt.is_a?(Hash) && opt.
|
123
|
+
opt.is_a?(Hash) && opt.key?(key) ? opt[key] : default
|
124
|
+
end
|
125
|
+
|
126
|
+
def error(obj, met, err)
|
127
|
+
warn "Error in #{obj}##{met}: #{err.backtrace.first}: #{err} (#{err.class})"
|
131
128
|
end
|
132
129
|
|
133
130
|
private
|
@@ -145,7 +142,7 @@ module Brice
|
|
145
142
|
brice_load rc
|
146
143
|
}
|
147
144
|
|
148
|
-
include_custom_extensions ? res
|
145
|
+
include_custom_extensions ? res + load_custom_extensions : res
|
149
146
|
end
|
150
147
|
|
151
148
|
# call-seq:
|
@@ -164,7 +161,7 @@ module Brice
|
|
164
161
|
#
|
165
162
|
# Find the actual extension files in +dir+.
|
166
163
|
def find_rc_files(dir = RC_DIR)
|
167
|
-
File.directory?(dir) ? Dir["#{dir}
|
164
|
+
File.directory?(dir) ? Dir["#{dir}/**/*.rb"].sort : []
|
168
165
|
end
|
169
166
|
|
170
167
|
# call-seq:
|
@@ -178,3 +175,8 @@ module Brice
|
|
178
175
|
end
|
179
176
|
|
180
177
|
end
|
178
|
+
|
179
|
+
require_relative 'brice/config'
|
180
|
+
require_relative 'brice/colours'
|
181
|
+
require_relative 'brice/history'
|
182
|
+
require_relative 'brice/shortcuts'
|
data/lib/brice/colours.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# #
|
4
4
|
# A component of brice, the extra cool IRb goodness donator #
|
5
5
|
# #
|
6
|
-
# Copyright (C) 2008-
|
6
|
+
# Copyright (C) 2008-2014 Jens Wille #
|
7
7
|
# #
|
8
8
|
# Authors: #
|
9
9
|
# Jens Wille <jens.wille@gmail.com> #
|
@@ -24,15 +24,13 @@
|
|
24
24
|
###############################################################################
|
25
25
|
#++
|
26
26
|
|
27
|
-
require 'brice'
|
28
|
-
|
29
27
|
module Brice
|
30
28
|
|
31
29
|
# Add colour support to IRb.
|
32
30
|
#
|
33
|
-
# Set your own colours with <tt>config.colours.opt = { :
|
31
|
+
# Set your own colours with <tt>config.colours.opt = { colours: { ... } }</tt>
|
34
32
|
# or modify the default scheme (DEFAULT_COLOURS) with <tt>config.colours.opt =
|
35
|
-
# { :
|
33
|
+
# { colours: Brice::Colours::DEFAULT_COLOURS.merge(...) }</tt>.
|
36
34
|
|
37
35
|
module Colours
|
38
36
|
|
@@ -41,61 +39,63 @@ module Brice
|
|
41
39
|
# Default IRb colour scheme.
|
42
40
|
DEFAULT_COLOURS = {
|
43
41
|
# delimiter colours
|
44
|
-
:
|
45
|
-
:
|
42
|
+
comma: :blue,
|
43
|
+
refers: :blue,
|
46
44
|
|
47
45
|
# container colours (hash and array)
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
46
|
+
open_hash: :green,
|
47
|
+
close_hash: :green,
|
48
|
+
open_array: :green,
|
49
|
+
close_array: :green,
|
52
50
|
|
53
51
|
# object colours
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
52
|
+
open_object: :light_red,
|
53
|
+
object_class: :white,
|
54
|
+
object_addr_prefix: :blue,
|
55
|
+
object_line_prefix: :blue,
|
56
|
+
close_object: :light_red,
|
59
57
|
|
60
58
|
# symbol colours
|
61
|
-
:
|
62
|
-
:
|
59
|
+
symbol: :yellow,
|
60
|
+
symbol_prefix: :yellow,
|
63
61
|
|
64
62
|
# string colours
|
65
|
-
:
|
66
|
-
:
|
67
|
-
:
|
63
|
+
open_string: :red,
|
64
|
+
string: :cyan,
|
65
|
+
close_string: :red,
|
68
66
|
|
69
67
|
# misc colours
|
70
|
-
:
|
71
|
-
:
|
72
|
-
:
|
73
|
-
:
|
74
|
-
:
|
68
|
+
number: :cyan,
|
69
|
+
keyword: :green,
|
70
|
+
class: :light_green,
|
71
|
+
range: :red,
|
72
|
+
unknown: :green
|
75
73
|
}
|
76
74
|
|
77
75
|
# Fruity testing colours.
|
78
76
|
TESTING_COLOURS = {
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
77
|
+
comma: :red,
|
78
|
+
refers: :red,
|
79
|
+
open_hash: :blue,
|
80
|
+
close_hash: :blue,
|
81
|
+
open_array: :green,
|
82
|
+
close_array: :green,
|
83
|
+
open_object: :light_red,
|
84
|
+
object_class: :light_green,
|
85
|
+
object_addr: :purple,
|
86
|
+
object_line: :light_purple,
|
87
|
+
close_object: :light_red,
|
88
|
+
symbol: :yellow,
|
89
|
+
symbol_prefix: :yellow,
|
90
|
+
number: :cyan,
|
91
|
+
string: :cyan,
|
92
|
+
keyword: :white,
|
93
|
+
range: :light_blue
|
96
94
|
}
|
97
95
|
|
98
96
|
def init(opt = {})
|
97
|
+
require 'ripper'
|
98
|
+
|
99
99
|
enable_irb if Brice.opt(opt, :irb, STDOUT.tty?)
|
100
100
|
enable_pp if Brice.opt(opt, :pp, STDOUT.tty?)
|
101
101
|
|
@@ -109,51 +109,26 @@ module Brice
|
|
109
109
|
|
110
110
|
# Enable colourized IRb results.
|
111
111
|
def enable_irb
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
alias_method :inspect_value_without_colour, :inspect_value
|
116
|
-
|
117
|
-
def inspect_value_with_colour(value)
|
118
|
-
Colours.colourize(inspect_value_without_colour(value))
|
119
|
-
end
|
120
|
-
end
|
112
|
+
IRB::Inspector.class_eval {
|
113
|
+
unless method_defined?(:inspect_value_with_colour)
|
114
|
+
alias_method :inspect_value_without_colour, :inspect_value
|
121
115
|
|
122
|
-
|
123
|
-
|
124
|
-
else
|
125
|
-
IRB::Irb.class_eval {
|
126
|
-
unless method_defined?(:output_value_with_colour)
|
127
|
-
alias_method :output_value_without_colour, :output_value
|
128
|
-
|
129
|
-
def output_value_with_colour
|
130
|
-
value = @context.last_value
|
131
|
-
value = Colours.colourize(value.inspect) if @context.inspect?
|
132
|
-
|
133
|
-
printf(@context.return_format, value)
|
134
|
-
end
|
116
|
+
def inspect_value_with_colour(value)
|
117
|
+
Colours.colourize(inspect_value_without_colour(value))
|
135
118
|
end
|
119
|
+
end
|
136
120
|
|
137
|
-
|
138
|
-
|
139
|
-
end
|
121
|
+
alias_method :inspect_value, :inspect_value_with_colour
|
122
|
+
}
|
140
123
|
end
|
141
124
|
|
142
125
|
# Disable colourized IRb results.
|
143
126
|
def disable_irb
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
}
|
150
|
-
else
|
151
|
-
IRB::Irb.class_eval {
|
152
|
-
if method_defined?(:output_value_without_colour)
|
153
|
-
alias_method :output_value, :output_value_without_colour
|
154
|
-
end
|
155
|
-
}
|
156
|
-
end
|
127
|
+
IRB::Inspector.class_eval {
|
128
|
+
if method_defined?(:inspect_value_without_colour)
|
129
|
+
alias_method :inspect_value, :inspect_value_without_colour
|
130
|
+
end
|
131
|
+
}
|
157
132
|
end
|
158
133
|
|
159
134
|
def enable_pp
|
@@ -215,14 +190,11 @@ module Brice
|
|
215
190
|
|
216
191
|
# Colourize the results of inspect
|
217
192
|
def colourize(str)
|
218
|
-
|
219
|
-
|
220
|
-
Tokenizer.tokenize(str) { |token, value|
|
193
|
+
''.tap { |res| Tokenizer.tokenize(str.to_s) { |token, value|
|
221
194
|
res << colourize_string(value, colours[token])
|
222
|
-
}
|
223
|
-
|
224
|
-
|
225
|
-
rescue
|
195
|
+
} }
|
196
|
+
rescue => err
|
197
|
+
Brice.error(self, __method__, err)
|
226
198
|
str
|
227
199
|
end
|
228
200
|
|
@@ -233,28 +205,28 @@ module Brice
|
|
233
205
|
extend self
|
234
206
|
|
235
207
|
COLOURS = {
|
236
|
-
:
|
237
|
-
:
|
238
|
-
:
|
239
|
-
:
|
240
|
-
:
|
241
|
-
:
|
242
|
-
:
|
243
|
-
:
|
244
|
-
:
|
245
|
-
:
|
246
|
-
:
|
247
|
-
:
|
248
|
-
:
|
249
|
-
:
|
250
|
-
:
|
251
|
-
:
|
252
|
-
:
|
208
|
+
reset: '0;0',
|
209
|
+
black: '0;30',
|
210
|
+
red: '0;31',
|
211
|
+
green: '0;32',
|
212
|
+
brown: '0;33',
|
213
|
+
blue: '0;34',
|
214
|
+
cyan: '0;36',
|
215
|
+
purple: '0;35',
|
216
|
+
light_gray: '0;37',
|
217
|
+
dark_gray: '1;30',
|
218
|
+
light_red: '1;31',
|
219
|
+
light_green: '1;32',
|
220
|
+
yellow: '1;33',
|
221
|
+
light_blue: '1;34',
|
222
|
+
light_cyan: '1;36',
|
223
|
+
light_purple: '1;35',
|
224
|
+
white: '1;37'
|
253
225
|
}
|
254
226
|
|
255
227
|
# Return the escape code for a given colour.
|
256
228
|
def escape(key)
|
257
|
-
"\033[#{COLOURS[key]}m" if COLOURS.
|
229
|
+
"\033[#{COLOURS[key]}m" if COLOURS.key?(key)
|
258
230
|
end
|
259
231
|
|
260
232
|
alias_method :[], :escape
|
@@ -263,144 +235,174 @@ module Brice
|
|
263
235
|
|
264
236
|
# Tokenize an inspection string.
|
265
237
|
|
266
|
-
|
238
|
+
class Tokenizer
|
239
|
+
|
240
|
+
EVENT_MAP = {
|
241
|
+
# on_CHAR: :unknown,
|
242
|
+
# on___end__: :unknown,
|
243
|
+
# on_backref: :unknown,
|
244
|
+
# on_backtick: :unknown,
|
245
|
+
on_comma: :comma,
|
246
|
+
on_comment: :unknown,
|
247
|
+
on_const: :class,
|
248
|
+
# on_cvar: :unknown,
|
249
|
+
# on_embdoc: :unknown,
|
250
|
+
# on_embdoc_beg: :unknown,
|
251
|
+
# on_embdoc_end: :unknown,
|
252
|
+
# on_embexpr_beg: :unknown,
|
253
|
+
# on_embexpr_end: :unknown,
|
254
|
+
# on_embvar: :unknown,
|
255
|
+
on_float: :number,
|
256
|
+
# on_gvar: :unknown,
|
257
|
+
# on_heredoc_beg: :unknown,
|
258
|
+
# on_heredoc_end: :unknown,
|
259
|
+
on_ident: :symbol,
|
260
|
+
# on_ignored_nl: :unknown,
|
261
|
+
on_imaginary: :number,
|
262
|
+
on_int: :number,
|
263
|
+
# on_ivar: :unknown,
|
264
|
+
on_kw: :keyword,
|
265
|
+
on_label: :unknown,
|
266
|
+
on_lbrace: :open_hash,
|
267
|
+
on_lbracket: :open_array,
|
268
|
+
on_lparen: :unknown,
|
269
|
+
# on_nl: :unknown,
|
270
|
+
on_op: :refers,
|
271
|
+
on_period: :comma,
|
272
|
+
# on_qsymbols_beg: :unknown,
|
273
|
+
# on_qwords_beg: :unknown,
|
274
|
+
on_rational: :number,
|
275
|
+
on_rbrace: :close_hash,
|
276
|
+
on_rbracket: :close_array,
|
277
|
+
on_regexp_beg: :unknown,
|
278
|
+
on_regexp_end: :unknown,
|
279
|
+
on_rparen: :unknown,
|
280
|
+
on_semicolon: :comma,
|
281
|
+
on_sp: :whitespace,
|
282
|
+
on_symbeg: :symbol_prefix,
|
283
|
+
# on_symbols_beg: :unknown,
|
284
|
+
# on_tlambda: :unknown,
|
285
|
+
# on_tlambeg: :unknown,
|
286
|
+
on_tstring_beg: :open_string,
|
287
|
+
on_tstring_content: :string,
|
288
|
+
on_tstring_end: :close_string,
|
289
|
+
# on_words_beg: :unknown,
|
290
|
+
# on_words_sep: :unknown
|
291
|
+
}
|
267
292
|
|
268
|
-
|
293
|
+
OBJECT_RE = %r{
|
294
|
+
\A
|
295
|
+
( \#< )
|
296
|
+
( .+ )
|
297
|
+
( > )
|
298
|
+
\z
|
299
|
+
}x
|
300
|
+
|
301
|
+
OBJECT_CLASS_RE = %r{
|
302
|
+
\A
|
303
|
+
(?: \w | :: )+
|
304
|
+
}x
|
305
|
+
|
306
|
+
OBJECT_ADDR_RE = %r{
|
307
|
+
\A
|
308
|
+
( : )
|
309
|
+
( 0x [\hx]+ )
|
310
|
+
(?= \s | \z )
|
311
|
+
}x
|
312
|
+
|
313
|
+
IVAR_RE = %r{
|
314
|
+
\A
|
315
|
+
( @ )
|
316
|
+
( .+ )
|
317
|
+
\z
|
318
|
+
}x
|
319
|
+
|
320
|
+
RANGE_RE = %r{
|
321
|
+
\A
|
322
|
+
\.+
|
323
|
+
\z
|
324
|
+
}x
|
325
|
+
|
326
|
+
def self.tokenize(str, &block)
|
327
|
+
new(&block).tokenize(str)
|
328
|
+
end
|
329
|
+
|
330
|
+
def initialize(&block)
|
331
|
+
@block = block or raise ArgumentError, 'no block given'
|
332
|
+
end
|
333
|
+
|
334
|
+
attr_reader :block
|
269
335
|
|
270
336
|
def tokenize(str)
|
271
|
-
|
337
|
+
return if str.empty?
|
338
|
+
return if enc_event(str)
|
272
339
|
|
273
|
-
|
274
|
-
char = last_char = repeat = nil
|
275
|
-
states, value, index = [], '', 0
|
340
|
+
lex, prev = Ripper.lex(str), nil
|
276
341
|
|
277
|
-
|
278
|
-
|
342
|
+
len = lex[-1][0][-1] + lex[-1][-1].bytesize
|
343
|
+
str, rest = str.byteslice(0, len), str.byteslice(len .. -1)
|
279
344
|
|
280
|
-
|
281
|
-
|
282
|
-
|
345
|
+
return block[:unknown, rest] if str.empty?
|
346
|
+
|
347
|
+
lex.each { |_, event, tok|
|
348
|
+
sym_event(event, tok, prev) ||
|
349
|
+
obj_event(event, tok) ||
|
350
|
+
rng_event(event, tok) ||
|
351
|
+
var_event(event, tok) ||
|
352
|
+
map_event(event, tok)
|
283
353
|
|
284
|
-
|
285
|
-
yield states.last, value
|
286
|
-
reset[*args]
|
354
|
+
prev = event
|
287
355
|
}
|
288
356
|
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
when '[' then yield :open_array, '['
|
306
|
-
when ']' then yield :close_array, ']'
|
307
|
-
when '}' then yield :close_hash, '}'
|
308
|
-
when /\s/ then yield :whitespace, char
|
309
|
-
when ',' then yield :comma, ','
|
310
|
-
when '>' then yield :refers, '=>' if last_char == '='
|
311
|
-
when '.' then yield :range, '..' if last_char == '.'
|
312
|
-
when '=' then nil
|
313
|
-
else yield :unknown, char
|
314
|
-
end
|
315
|
-
when :symbol
|
316
|
-
if char =~ /[a-z0-9_!?]/ # should have =, but that messes up foo=>bar
|
317
|
-
value << char
|
318
|
-
else
|
319
|
-
yield :symbol_prefix, ':'
|
320
|
-
yield_last[true]
|
321
|
-
end
|
322
|
-
when :string
|
323
|
-
if char == '"'
|
324
|
-
if last_char == '\\'
|
325
|
-
value[-1] = char
|
326
|
-
else
|
327
|
-
yield :open_string, char
|
328
|
-
yield_last[]
|
329
|
-
yield :close_string, char
|
330
|
-
end
|
331
|
-
else
|
332
|
-
value << char
|
333
|
-
end
|
334
|
-
when :keyword
|
335
|
-
if char =~ /[a-z0-9_]/i
|
336
|
-
value << char
|
337
|
-
else
|
338
|
-
states[-1] = :class if value =~ /\A[A-Z]/
|
339
|
-
yield_last[true]
|
340
|
-
|
341
|
-
value << char if char == '.'
|
342
|
-
end
|
343
|
-
when :number
|
344
|
-
case char
|
345
|
-
when /[0-9e-]/
|
346
|
-
value << char
|
347
|
-
when '.'
|
348
|
-
if last_char == char
|
349
|
-
value.chop!
|
350
|
-
|
351
|
-
yield_last[]
|
352
|
-
yield :range, '..'
|
353
|
-
else
|
354
|
-
value << char
|
355
|
-
end
|
356
|
-
else
|
357
|
-
yield_last[true]
|
358
|
-
end
|
359
|
-
when :object
|
360
|
-
case char
|
361
|
-
when '<'
|
362
|
-
yield :open_object, '#<'
|
363
|
-
states << :object_class
|
364
|
-
when ':'
|
365
|
-
states << :object_addr
|
366
|
-
when '@'
|
367
|
-
states << :object_line
|
368
|
-
when '>'
|
369
|
-
yield :close_object, '>'
|
370
|
-
reset[]
|
371
|
-
end
|
372
|
-
when :object_class
|
373
|
-
if char == ':'
|
374
|
-
yield_last[true]
|
375
|
-
else
|
376
|
-
value << char
|
377
|
-
end
|
378
|
-
when :object_addr
|
379
|
-
case char
|
380
|
-
when '>'
|
381
|
-
# ignore
|
382
|
-
when '@'
|
383
|
-
yield :object_addr_prefix, ':'
|
384
|
-
yield_last[true]
|
385
|
-
else
|
386
|
-
value << char
|
387
|
-
end
|
388
|
-
when :object_line
|
389
|
-
if char == '>'
|
390
|
-
yield :object_line_prefix, '@'
|
391
|
-
yield_last[true]
|
392
|
-
else
|
393
|
-
value << char
|
394
|
-
end
|
395
|
-
else
|
396
|
-
raise "unknown state: #{states}"
|
397
|
-
end
|
357
|
+
tokenize(rest)
|
358
|
+
end
|
359
|
+
|
360
|
+
private
|
361
|
+
|
362
|
+
def enc_event(str) # XXX /\A\s*#.*?coding\s*:\s*./
|
363
|
+
object($1, $2, $3) if str =~ OBJECT_RE && str.include?('coding')
|
364
|
+
end
|
365
|
+
|
366
|
+
def obj_event(event, tok)
|
367
|
+
object($1, $2, $3) if event == :on_comment && tok =~ OBJECT_RE
|
368
|
+
end
|
369
|
+
|
370
|
+
def sym_event(event, tok, prev)
|
371
|
+
block[:symbol, tok] if event == :on_kw && prev == :on_symbeg
|
372
|
+
end
|
398
373
|
|
399
|
-
|
400
|
-
|
401
|
-
|
374
|
+
def rng_event(event, tok)
|
375
|
+
block[:range, tok] if event == :on_op && tok =~ RANGE_RE
|
376
|
+
end
|
377
|
+
|
378
|
+
def var_event(event, tok)
|
379
|
+
if event == :on_ivar && tok =~ IVAR_RE
|
380
|
+
block[:object_line_prefix, $1]
|
381
|
+
block[:keyword, $2]
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
def map_event(event, tok)
|
386
|
+
block[EVENT_MAP[event], tok]
|
387
|
+
end
|
388
|
+
|
389
|
+
def object(open, str, close)
|
390
|
+
block[:open_object, open]
|
391
|
+
|
392
|
+
if str.sub!(OBJECT_CLASS_RE, '')
|
393
|
+
block[:object_class, $&]
|
394
|
+
|
395
|
+
if str.sub!(OBJECT_ADDR_RE, '')
|
396
|
+
block[:object_addr_prefix, $1]
|
397
|
+
block[:object_addr, $2]
|
398
|
+
|
399
|
+
str = tokenize(str)
|
402
400
|
end
|
403
401
|
end
|
402
|
+
|
403
|
+
block[:unknown, str] if str
|
404
|
+
|
405
|
+
block[:close_object, close]
|
404
406
|
end
|
405
407
|
|
406
408
|
end
|