ruby_jard 0.1.0 → 0.3.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.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +32 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/documentation.yml +65 -0
- data/.github/workflows/rspec.yml +96 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +90 -2
- data/CHANGELOG.md +112 -0
- data/Gemfile +14 -4
- data/README.md +95 -3
- data/benchmark/path_filter_bench.rb +58 -0
- data/bin/console +1 -2
- data/lib/ruby_jard.rb +68 -32
- data/lib/ruby_jard/box_drawer.rb +175 -0
- data/lib/ruby_jard/color_scheme.rb +28 -0
- data/lib/ruby_jard/color_schemes.rb +54 -0
- data/lib/ruby_jard/color_schemes/256_color_scheme.rb +50 -0
- data/lib/ruby_jard/color_schemes/256_light_color_scheme.rb +50 -0
- data/lib/ruby_jard/color_schemes/deep_space_color_scheme.rb +49 -0
- data/lib/ruby_jard/color_schemes/gruvbox_color_scheme.rb +48 -0
- data/lib/ruby_jard/color_schemes/one_half_dark_color_scheme.rb +47 -0
- data/lib/ruby_jard/color_schemes/one_half_light_color_scheme.rb +49 -0
- data/lib/ruby_jard/column.rb +26 -0
- data/lib/ruby_jard/commands/color_helpers.rb +32 -0
- data/lib/ruby_jard/commands/continue_command.rb +4 -9
- data/lib/ruby_jard/commands/down_command.rb +9 -8
- data/lib/ruby_jard/commands/exit_command.rb +27 -0
- data/lib/ruby_jard/commands/frame_command.rb +13 -11
- data/lib/ruby_jard/commands/jard/color_scheme_command.rb +74 -0
- data/lib/ruby_jard/commands/jard/filter_command.rb +136 -0
- data/lib/ruby_jard/commands/jard/hide_command.rb +40 -0
- data/lib/ruby_jard/commands/jard/output_command.rb +36 -0
- data/lib/ruby_jard/commands/jard/show_command.rb +41 -0
- data/lib/ruby_jard/commands/jard_command.rb +52 -0
- data/lib/ruby_jard/commands/list_command.rb +31 -0
- data/lib/ruby_jard/commands/next_command.rb +11 -8
- data/lib/ruby_jard/commands/step_command.rb +11 -8
- data/lib/ruby_jard/commands/step_out_command.rb +34 -0
- data/lib/ruby_jard/commands/up_command.rb +10 -8
- data/lib/ruby_jard/commands/validation_helpers.rb +50 -0
- data/lib/ruby_jard/config.rb +61 -0
- data/lib/ruby_jard/console.rb +158 -0
- data/lib/ruby_jard/control_flow.rb +73 -0
- data/lib/ruby_jard/decorators/array_decorator.rb +79 -0
- data/lib/ruby_jard/decorators/attributes_decorator.rb +172 -0
- data/lib/ruby_jard/decorators/color_decorator.rb +80 -0
- data/lib/ruby_jard/decorators/hash_decorator.rb +74 -0
- data/lib/ruby_jard/decorators/inspection_decorator.rb +109 -0
- data/lib/ruby_jard/decorators/loc_decorator.rb +108 -119
- data/lib/ruby_jard/decorators/object_decorator.rb +122 -0
- data/lib/ruby_jard/decorators/path_decorator.rb +56 -60
- data/lib/ruby_jard/decorators/rails_decorator.rb +194 -0
- data/lib/ruby_jard/decorators/source_decorator.rb +3 -1
- data/lib/ruby_jard/decorators/string_decorator.rb +41 -0
- data/lib/ruby_jard/decorators/struct_decorator.rb +79 -0
- data/lib/ruby_jard/frame.rb +68 -0
- data/lib/ruby_jard/key_binding.rb +14 -0
- data/lib/ruby_jard/key_bindings.rb +96 -0
- data/lib/ruby_jard/keys.rb +48 -0
- data/lib/ruby_jard/layout.rb +17 -88
- data/lib/ruby_jard/layout_calculator.rb +168 -0
- data/lib/ruby_jard/layout_picker.rb +34 -0
- data/lib/ruby_jard/layouts.rb +52 -0
- data/lib/ruby_jard/layouts/narrow_horizontal_layout.rb +32 -0
- data/lib/ruby_jard/layouts/narrow_vertical_layout.rb +32 -0
- data/lib/ruby_jard/layouts/tiny_layout.rb +29 -0
- data/lib/ruby_jard/layouts/wide_layout.rb +50 -0
- data/lib/ruby_jard/pager.rb +112 -0
- data/lib/ruby_jard/path_classifier.rb +133 -0
- data/lib/ruby_jard/path_filter.rb +125 -0
- data/lib/ruby_jard/reflection.rb +97 -0
- data/lib/ruby_jard/repl_processor.rb +151 -89
- data/lib/ruby_jard/repl_proxy.rb +337 -0
- data/lib/ruby_jard/row.rb +31 -0
- data/lib/ruby_jard/row_renderer.rb +119 -0
- data/lib/ruby_jard/screen.rb +14 -41
- data/lib/ruby_jard/screen_adjuster.rb +104 -0
- data/lib/ruby_jard/screen_drawer.rb +25 -0
- data/lib/ruby_jard/screen_manager.rb +167 -82
- data/lib/ruby_jard/screen_renderer.rb +152 -0
- data/lib/ruby_jard/screens.rb +31 -12
- data/lib/ruby_jard/screens/backtrace_screen.rb +118 -116
- data/lib/ruby_jard/screens/menu_screen.rb +73 -45
- data/lib/ruby_jard/screens/source_screen.rb +86 -106
- data/lib/ruby_jard/screens/threads_screen.rb +103 -78
- data/lib/ruby_jard/screens/variables_screen.rb +224 -142
- data/lib/ruby_jard/session.rb +151 -16
- data/lib/ruby_jard/span.rb +23 -0
- data/lib/ruby_jard/templates/layout_template.rb +35 -0
- data/lib/ruby_jard/templates/screen_template.rb +34 -0
- data/lib/ruby_jard/thread_info.rb +69 -0
- data/lib/ruby_jard/version.rb +1 -1
- data/ruby_jard.gemspec +7 -8
- metadata +84 -50
- data/.travis.yml +0 -6
- data/lib/ruby_jard/commands/finish_command.rb +0 -31
- data/lib/ruby_jard/decorators/text_decorator.rb +0 -61
- data/lib/ruby_jard/layout_template.rb +0 -101
- data/lib/ruby_jard/screens/breakpoints_screen.rb +0 -23
- data/lib/ruby_jard/screens/empty_screen.rb +0 -13
- data/lib/ruby_jard/screens/expressions_sreen.rb +0 -22
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ruby_jard/decorators/array_decorator'
|
4
|
+
require 'ruby_jard/decorators/string_decorator'
|
5
|
+
require 'ruby_jard/decorators/hash_decorator'
|
6
|
+
require 'ruby_jard/decorators/struct_decorator'
|
7
|
+
require 'ruby_jard/decorators/object_decorator'
|
8
|
+
require 'ruby_jard/decorators/attributes_decorator'
|
9
|
+
require 'ruby_jard/decorators/rails_decorator'
|
10
|
+
|
11
|
+
module RubyJard
|
12
|
+
module Decorators
|
13
|
+
##
|
14
|
+
# Generate beauty inspection of a particular variable.
|
15
|
+
# The inspection doesn't aim to become a better version of PP. Instead,
|
16
|
+
# it's scope is to generate an overview of a variable within a limited
|
17
|
+
# space. So, it only keeps useful information, and tries to reach the
|
18
|
+
# very shallow layers of a nested data structure.
|
19
|
+
# This class is inspired by Ruby's PP:
|
20
|
+
# https://github.com/ruby/ruby/blob/master/lib/pp.rb
|
21
|
+
class InspectionDecorator
|
22
|
+
PRIMITIVE_TYPES = {
|
23
|
+
# Intertal classes for those values may differ between Ruby versions
|
24
|
+
# For example: Bignum is renamed to Integer
|
25
|
+
# So, it's safer to use discrete value's class as the key for this mapping.
|
26
|
+
true.class.name => :literal,
|
27
|
+
false.class.name => :literal,
|
28
|
+
1.class.name => :literal,
|
29
|
+
1.1.class.name => :literal,
|
30
|
+
1.to_r.class.name => :literal, # Rational: (1/1)
|
31
|
+
1.to_c.class.name => :literal, # Complex: (1+0i)
|
32
|
+
:sym.class.name => :literal,
|
33
|
+
//.class.name => :literal, # TODO: create a new class to handle range
|
34
|
+
(0..0).class.name => :literal,
|
35
|
+
nil.class.name => :text_dim,
|
36
|
+
Class.class.name => :text_primary, # Sorry, I lied, Class will never change
|
37
|
+
Proc.name => :text_primary # TODO: create a new class to handle proc.
|
38
|
+
}.freeze
|
39
|
+
|
40
|
+
def initialize
|
41
|
+
@klass_decorators = [
|
42
|
+
@array_decorator = ArrayDecorator.new(self),
|
43
|
+
@string_decorator = StringDecorator.new(self),
|
44
|
+
@hash_decorator = HashDecorator.new(self),
|
45
|
+
@struct_decorator = StructDecorator.new(self),
|
46
|
+
@rails_decorator = RailsDecorator.new(self)
|
47
|
+
]
|
48
|
+
@object_decorator = ObjectDecorator.new(self)
|
49
|
+
end
|
50
|
+
|
51
|
+
def decorate_singleline(variable, line_limit:, depth: 0)
|
52
|
+
if primitive?(variable)
|
53
|
+
return decorate_primitive(variable, line_limit)
|
54
|
+
end
|
55
|
+
|
56
|
+
@klass_decorators.each do |klass_decorator|
|
57
|
+
next unless klass_decorator.match?(variable)
|
58
|
+
|
59
|
+
spans = klass_decorator.decorate_singleline(variable, line_limit: line_limit, depth: depth)
|
60
|
+
return spans unless spans.nil?
|
61
|
+
end
|
62
|
+
@object_decorator.decorate_singleline(variable, line_limit: line_limit, depth: depth)
|
63
|
+
end
|
64
|
+
|
65
|
+
def decorate_multiline(variable, first_line_limit:, lines:, line_limit:, depth: 0)
|
66
|
+
if primitive?(variable)
|
67
|
+
return decorate_primitive(variable, first_line_limit)
|
68
|
+
end
|
69
|
+
|
70
|
+
@klass_decorators.each do |klass_decorator|
|
71
|
+
next unless klass_decorator.match?(variable)
|
72
|
+
|
73
|
+
spans = klass_decorator.decorate_multiline(
|
74
|
+
variable,
|
75
|
+
first_line_limit: first_line_limit,
|
76
|
+
lines: lines,
|
77
|
+
line_limit: line_limit,
|
78
|
+
depth: depth
|
79
|
+
)
|
80
|
+
return spans unless spans.nil?
|
81
|
+
end
|
82
|
+
@object_decorator.decorate_multiline(
|
83
|
+
variable,
|
84
|
+
first_line_limit: first_line_limit,
|
85
|
+
lines: lines,
|
86
|
+
line_limit: line_limit,
|
87
|
+
depth: depth
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def primitive?(variable)
|
94
|
+
!PRIMITIVE_TYPES[RubyJard::Reflection.call_class(variable).name].nil?
|
95
|
+
end
|
96
|
+
|
97
|
+
def decorate_primitive(variable, line_limit)
|
98
|
+
inspection = variable.inspect
|
99
|
+
inspection = inspection[0..line_limit - 2] + '…' if inspection.length >= line_limit
|
100
|
+
[
|
101
|
+
RubyJard::Span.new(
|
102
|
+
content: inspection,
|
103
|
+
styles: PRIMITIVE_TYPES[RubyJard::Reflection.call_class(variable).name]
|
104
|
+
)
|
105
|
+
]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -1,135 +1,126 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'coderay'
|
4
|
+
|
3
5
|
module RubyJard
|
4
6
|
module Decorators
|
5
7
|
##
|
6
8
|
# Decorate a line of code fetched from the source file.
|
7
9
|
# The line is tokenized, and feed into JardEncoder to append color (with
|
8
|
-
#
|
10
|
+
# Span).
|
9
11
|
class LocDecorator
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@loc = loc
|
14
|
-
@highlighted = highlighted
|
15
|
-
@encoder = JardLocEncoder.new(
|
16
|
-
color_decorator: color_decorator,
|
17
|
-
highlighted: highlighted
|
18
|
-
)
|
12
|
+
def initialize
|
13
|
+
@encoder = JardLocEncoder.new
|
14
|
+
end
|
19
15
|
|
20
|
-
|
16
|
+
def decorate(loc, file = nil)
|
17
|
+
tokens = CodeRay.scan(loc, extension(file))
|
18
|
+
spans = @encoder.encode_tokens(tokens)
|
19
|
+
[spans, tokens]
|
21
20
|
end
|
22
21
|
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
private
|
23
|
+
|
24
|
+
def extension(file)
|
25
|
+
# TODO: A map constant is better
|
26
|
+
if file =~ /.*\.erb$/
|
27
|
+
:erb
|
28
|
+
elsif file =~ /.*\.haml$/
|
29
|
+
:haml
|
30
|
+
else
|
31
|
+
:ruby
|
32
|
+
end
|
26
33
|
end
|
27
34
|
|
28
35
|
# A shameless copy from https://github.com/rubychan/coderay/blob/master/lib/coderay/encoders/terminal.rb
|
29
36
|
class JardLocEncoder < CodeRay::Encoders::Encoder
|
30
|
-
|
31
|
-
|
32
|
-
annotation:
|
33
|
-
attribute_name:
|
34
|
-
attribute_value:
|
37
|
+
DEFAULT_STYLE = :normal_token
|
38
|
+
TOKEN_STYLES = {
|
39
|
+
annotation: :keyword,
|
40
|
+
attribute_name: :keyword,
|
41
|
+
attribute_value: :keyword,
|
35
42
|
binary: {
|
36
|
-
self:
|
37
|
-
char:
|
38
|
-
delimiter:
|
43
|
+
self: :keyword,
|
44
|
+
char: :keyword,
|
45
|
+
delimiter: :keyword
|
39
46
|
},
|
40
47
|
char: {
|
41
|
-
self:
|
42
|
-
delimiter:
|
48
|
+
self: :keyword,
|
49
|
+
delimiter: :keyword
|
43
50
|
},
|
44
|
-
class:
|
45
|
-
class_variable:
|
46
|
-
color:
|
51
|
+
class: :constant,
|
52
|
+
class_variable: :constant,
|
53
|
+
color: :constant,
|
47
54
|
comment: {
|
48
|
-
self:
|
49
|
-
char:
|
50
|
-
delimiter:
|
55
|
+
self: :comment,
|
56
|
+
char: :comment,
|
57
|
+
delimiter: :comment
|
51
58
|
},
|
52
|
-
constant:
|
53
|
-
decorator:
|
54
|
-
definition:
|
55
|
-
directive:
|
56
|
-
docstring:
|
57
|
-
doctype:
|
58
|
-
done:
|
59
|
-
entity:
|
60
|
-
error:
|
61
|
-
exception:
|
62
|
-
float:
|
63
|
-
function:
|
64
|
-
method:
|
65
|
-
global_variable:
|
66
|
-
hex:
|
67
|
-
id:
|
68
|
-
include:
|
69
|
-
integer:
|
70
|
-
imaginary:
|
71
|
-
important:
|
59
|
+
constant: :constant,
|
60
|
+
decorator: :keyword,
|
61
|
+
definition: :keyword,
|
62
|
+
directive: :keyword,
|
63
|
+
docstring: :keyword,
|
64
|
+
doctype: :keyword,
|
65
|
+
done: :keyword,
|
66
|
+
entity: :keyword,
|
67
|
+
error: :constant,
|
68
|
+
exception: :keyword,
|
69
|
+
float: :literal,
|
70
|
+
function: :constant,
|
71
|
+
method: :method,
|
72
|
+
global_variable: :constant,
|
73
|
+
hex: :keyword,
|
74
|
+
id: :keyword,
|
75
|
+
include: :keyword,
|
76
|
+
integer: :literal,
|
77
|
+
imaginary: :keyword,
|
78
|
+
important: :keyword,
|
72
79
|
key: {
|
73
|
-
self:
|
74
|
-
char:
|
75
|
-
delimiter:
|
80
|
+
self: :literal,
|
81
|
+
char: :literal,
|
82
|
+
delimiter: :literal
|
76
83
|
},
|
77
|
-
label:
|
78
|
-
local_variable:
|
79
|
-
namespace:
|
80
|
-
octal:
|
81
|
-
predefined:
|
82
|
-
predefined_constant:
|
83
|
-
predefined_type:
|
84
|
-
preprocessor:
|
85
|
-
pseudo_class:
|
84
|
+
label: :literal,
|
85
|
+
local_variable: :keyword,
|
86
|
+
namespace: :keyword,
|
87
|
+
octal: :keyword,
|
88
|
+
predefined: :keyword,
|
89
|
+
predefined_constant: :keyword,
|
90
|
+
predefined_type: :constant,
|
91
|
+
preprocessor: :keyword,
|
92
|
+
pseudo_class: :keyword,
|
86
93
|
regexp: {
|
87
|
-
self:
|
88
|
-
delimiter:
|
89
|
-
modifier:
|
90
|
-
char:
|
94
|
+
self: :keyword,
|
95
|
+
delimiter: :keyword,
|
96
|
+
modifier: :keyword,
|
97
|
+
char: :keyword
|
91
98
|
},
|
92
|
-
reserved:
|
93
|
-
keyword:
|
99
|
+
reserved: :keyword,
|
100
|
+
keyword: :keyword,
|
94
101
|
shell: {
|
95
|
-
self:
|
96
|
-
char:
|
97
|
-
delimiter:
|
98
|
-
escape:
|
102
|
+
self: :keyword,
|
103
|
+
char: :keyword,
|
104
|
+
delimiter: :keyword,
|
105
|
+
escape: :keyword
|
99
106
|
},
|
100
107
|
string: {
|
101
|
-
self:
|
102
|
-
modifier:
|
103
|
-
char:
|
104
|
-
delimiter:
|
105
|
-
escape:
|
108
|
+
self: :string,
|
109
|
+
modifier: :string,
|
110
|
+
char: :string,
|
111
|
+
delimiter: :string,
|
112
|
+
escape: :string,
|
113
|
+
content: :string
|
106
114
|
},
|
107
115
|
symbol: {
|
108
|
-
self:
|
109
|
-
delimiter:
|
110
|
-
},
|
111
|
-
tag: [:green],
|
112
|
-
type: [:blue],
|
113
|
-
value: [:blue],
|
114
|
-
variable: [:blue],
|
115
|
-
insert: {
|
116
|
-
self: [:on_green],
|
117
|
-
insert: [:green, :on_green],
|
118
|
-
eyecatcher: [:italic]
|
116
|
+
self: :literal,
|
117
|
+
delimiter: :literal
|
119
118
|
},
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
change: {
|
126
|
-
self: [:on_blue],
|
127
|
-
change: [:white, :on_blue]
|
128
|
-
},
|
129
|
-
head: {
|
130
|
-
self: [:on_red],
|
131
|
-
filename: [:white, :on_red]
|
132
|
-
}
|
119
|
+
tag: :constant,
|
120
|
+
type: :keyword,
|
121
|
+
value: :keyword,
|
122
|
+
variable: :keyword,
|
123
|
+
instance_variable: :instance_variable
|
133
124
|
}.freeze
|
134
125
|
|
135
126
|
protected
|
@@ -137,9 +128,8 @@ module RubyJard
|
|
137
128
|
def setup(options)
|
138
129
|
super
|
139
130
|
@opened = []
|
140
|
-
@color_scopes = [
|
141
|
-
@
|
142
|
-
@highlighted = options[:highlighted]
|
131
|
+
@color_scopes = [TOKEN_STYLES]
|
132
|
+
@out = []
|
143
133
|
end
|
144
134
|
|
145
135
|
public
|
@@ -147,19 +137,26 @@ module RubyJard
|
|
147
137
|
def text_token(text, kind)
|
148
138
|
color = @color_scopes.last[kind]
|
149
139
|
text.gsub!("\n", '')
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
140
|
+
style =
|
141
|
+
if !color
|
142
|
+
DEFAULT_STYLE
|
143
|
+
elsif color.is_a? Hash
|
144
|
+
color[:self]
|
145
|
+
else
|
146
|
+
color
|
147
|
+
end
|
148
|
+
@out << Span.new(
|
149
|
+
content: text,
|
150
|
+
content_length: text.length,
|
151
|
+
styles: style.to_sym
|
152
|
+
)
|
156
153
|
end
|
157
154
|
|
158
155
|
def begin_group(kind)
|
159
156
|
@opened << kind
|
160
157
|
open_token(kind)
|
161
158
|
end
|
162
|
-
|
159
|
+
alias_method :begin_line, :begin_group
|
163
160
|
|
164
161
|
def end_group(_kind)
|
165
162
|
return unless @opened.pop
|
@@ -186,14 +183,6 @@ module RubyJard
|
|
186
183
|
@color_scopes.last
|
187
184
|
end
|
188
185
|
end
|
189
|
-
|
190
|
-
def compose_color(color)
|
191
|
-
if @highlighted
|
192
|
-
[:clear] + color
|
193
|
-
else
|
194
|
-
[:dim] + color
|
195
|
-
end
|
196
|
-
end
|
197
186
|
end
|
198
187
|
end
|
199
188
|
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyJard
|
4
|
+
module Decorators
|
5
|
+
##
|
6
|
+
# Default decorator for non-primitive data structure. It is aimed to replace default `inspect`.
|
7
|
+
# If a variable re-implement `#inspect`, it hornors this decision, but still try to
|
8
|
+
# parse the result.
|
9
|
+
# Otherwise, it use `Kernel#to_s`, and try to push instance variables into the result.
|
10
|
+
class ObjectDecorator
|
11
|
+
DEFAULT_INSPECTION_PATTERN = /#<(.*:0x[0-9a-z]+)(.*)>/i.freeze
|
12
|
+
|
13
|
+
def initialize(generic_decorator)
|
14
|
+
@generic_decorator = generic_decorator
|
15
|
+
@attributes_decorator = RubyJard::Decorators::AttributesDecorator.new(generic_decorator)
|
16
|
+
end
|
17
|
+
|
18
|
+
def decorate_singleline(variable, line_limit:, depth: 0)
|
19
|
+
if native_inspect?(variable)
|
20
|
+
decorate_native_inspection(variable, line_limit: line_limit, depth: depth)
|
21
|
+
else
|
22
|
+
decorate_custom_inspection(variable, line_limit: line_limit)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def decorate_multiline(variable, first_line_limit:, lines:, line_limit:, depth: 0)
|
27
|
+
singleline = decorate_singleline(variable, line_limit: first_line_limit)
|
28
|
+
return [singleline] if singleline.map(&:content_length).sum < line_limit
|
29
|
+
|
30
|
+
spans = [decorate_native_inspection(variable, line_limit: first_line_limit, with_children: false)]
|
31
|
+
|
32
|
+
item_count = 0
|
33
|
+
instance_variables = RubyJard::Reflection.call_instance_variables(variable)
|
34
|
+
instance_variables.each do |key|
|
35
|
+
spans << @attributes_decorator.pair(
|
36
|
+
key, RubyJard::Reflection.call_instance_variable_get(variable, key),
|
37
|
+
line_limit: line_limit, process_key: false, depth: depth + 1
|
38
|
+
)
|
39
|
+
|
40
|
+
item_count += 1
|
41
|
+
break if item_count >= lines - 2
|
42
|
+
end
|
43
|
+
|
44
|
+
if instance_variables.length > item_count
|
45
|
+
spans << [
|
46
|
+
RubyJard::Span.new(
|
47
|
+
content: "▸ #{instance_variables.length - item_count} more...",
|
48
|
+
margin_left: 2, styles: :text_dim
|
49
|
+
)
|
50
|
+
]
|
51
|
+
end
|
52
|
+
|
53
|
+
spans
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def native_inspect?(variable)
|
59
|
+
return true unless RubyJard::Reflection.call_respond_to?(variable, :inspect)
|
60
|
+
|
61
|
+
RubyJard::Reflection.bind_call(::Kernel, :method, variable, :inspect).owner == ::Kernel
|
62
|
+
end
|
63
|
+
|
64
|
+
def call_inspect(variable)
|
65
|
+
variable.inspect
|
66
|
+
rescue StandardError
|
67
|
+
RubyJard::Reflection.call_to_s(variable)
|
68
|
+
end
|
69
|
+
|
70
|
+
def decorate_native_inspection(variable, line_limit:, depth: 0, with_children: true)
|
71
|
+
raw_inspection = RubyJard::Reflection.call_to_s(variable)
|
72
|
+
match = raw_inspection.match(DEFAULT_INSPECTION_PATTERN)
|
73
|
+
|
74
|
+
if match
|
75
|
+
instance_variables = RubyJard::Reflection.call_instance_variables(variable)
|
76
|
+
spans = [
|
77
|
+
RubyJard::Span.new(content: '#<', styles: :text_primary),
|
78
|
+
RubyJard::Span.new(content: match[1], styles: :text_primary)
|
79
|
+
]
|
80
|
+
if with_children && !instance_variables.empty?
|
81
|
+
spans << RubyJard::Span.new(content: ' ', styles: :text_primary)
|
82
|
+
spans += @attributes_decorator.inline_pairs(
|
83
|
+
instance_variables.each_with_index, total: instance_variables.length,
|
84
|
+
line_limit: line_limit - spans.map(&:content_length).sum - 1,
|
85
|
+
depth: depth + 1, process_key: false,
|
86
|
+
value_proc: ->(key) { RubyJard::Reflection.call_instance_variable_get(variable, key) }
|
87
|
+
)
|
88
|
+
end
|
89
|
+
spans << RubyJard::Span.new(content: '>', styles: :text_primary)
|
90
|
+
spans
|
91
|
+
elsif raw_inspection.length <= line_limit
|
92
|
+
[RubyJard::Span.new(content: raw_inspection[0..line_limit], styles: :text_primary)]
|
93
|
+
else
|
94
|
+
[RubyJard::Span.new(content: raw_inspection[0..line_limit - 3] + '…>', styles: :text_primary)]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def decorate_custom_inspection(variable, line_limit:)
|
99
|
+
raw_inspection = call_inspect(variable)
|
100
|
+
match = raw_inspection.match(DEFAULT_INSPECTION_PATTERN)
|
101
|
+
if match
|
102
|
+
detail =
|
103
|
+
if match[2].length < line_limit - match[1].length - 3
|
104
|
+
match[2]
|
105
|
+
else
|
106
|
+
match[2][0..line_limit - match[1].length - 4] + '…'
|
107
|
+
end
|
108
|
+
[
|
109
|
+
RubyJard::Span.new(content: '#<', styles: :text_primary),
|
110
|
+
RubyJard::Span.new(content: match[1], styles: :text_primary),
|
111
|
+
RubyJard::Span.new(content: detail, styles: :text_dim),
|
112
|
+
RubyJard::Span.new(content: '>', styles: :text_primary)
|
113
|
+
]
|
114
|
+
elsif raw_inspection.length <= line_limit
|
115
|
+
[RubyJard::Span.new(content: raw_inspection[0..line_limit], styles: :text_primary)]
|
116
|
+
else
|
117
|
+
[RubyJard::Span.new(content: raw_inspection[0..line_limit - 3] + '…>', styles: :text_primary)]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|