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