ruby_jard 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.github/workflows/documentation.yml +65 -0
- data/.github/workflows/{ruby.yml → rspec.yml} +22 -11
- data/.rubocop.yml +6 -0
- data/CHANGELOG.md +15 -3
- data/Gemfile +9 -2
- data/README.md +52 -332
- data/benchmark/path_filter_bench.rb +58 -0
- data/lib/ruby_jard.rb +15 -5
- data/lib/ruby_jard/color_schemes.rb +9 -1
- data/lib/ruby_jard/color_schemes/256_color_scheme.rb +21 -35
- data/lib/ruby_jard/color_schemes/256_light_color_scheme.rb +23 -35
- data/lib/ruby_jard/color_schemes/deep_space_color_scheme.rb +20 -34
- data/lib/ruby_jard/color_schemes/gruvbox_color_scheme.rb +20 -34
- data/lib/ruby_jard/color_schemes/one_half_dark_color_scheme.rb +20 -34
- data/lib/ruby_jard/color_schemes/one_half_light_color_scheme.rb +21 -34
- data/lib/ruby_jard/commands/color_helpers.rb +32 -0
- data/lib/ruby_jard/commands/frame_command.rb +2 -2
- data/lib/ruby_jard/commands/jard/color_scheme_command.rb +25 -3
- data/lib/ruby_jard/commands/jard/filter_command.rb +136 -0
- data/lib/ruby_jard/commands/jard/output_command.rb +13 -5
- data/lib/ruby_jard/commands/jard_command.rb +3 -1
- data/lib/ruby_jard/config.rb +9 -2
- 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 +12 -5
- data/lib/ruby_jard/decorators/hash_decorator.rb +74 -0
- data/lib/ruby_jard/decorators/inspection_decorator.rb +91 -58
- data/lib/ruby_jard/decorators/object_decorator.rb +122 -0
- data/lib/ruby_jard/decorators/path_decorator.rb +55 -72
- data/lib/ruby_jard/decorators/rails_decorator.rb +194 -0
- 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 +23 -10
- data/lib/ruby_jard/keys.rb +1 -0
- data/lib/ruby_jard/layouts/narrow_horizontal_layout.rb +4 -0
- data/lib/ruby_jard/layouts/tiny_layout.rb +4 -0
- data/lib/ruby_jard/pager.rb +21 -5
- 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 +71 -38
- data/lib/ruby_jard/row_renderer.rb +5 -3
- data/lib/ruby_jard/screen.rb +2 -2
- data/lib/ruby_jard/screen_manager.rb +13 -36
- data/lib/ruby_jard/screen_renderer.rb +1 -1
- data/lib/ruby_jard/screens/backtrace_screen.rb +55 -39
- data/lib/ruby_jard/screens/menu_screen.rb +30 -30
- data/lib/ruby_jard/screens/source_screen.rb +46 -62
- data/lib/ruby_jard/screens/threads_screen.rb +59 -72
- data/lib/ruby_jard/screens/variables_screen.rb +168 -124
- data/lib/ruby_jard/session.rb +120 -16
- data/lib/ruby_jard/thread_info.rb +69 -0
- data/lib/ruby_jard/version.rb +1 -1
- data/ruby_jard.gemspec +3 -1
- metadata +20 -39
- data/.travis.yml +0 -6
- data/CNAME +0 -1
- data/_config.yml +0 -1
- data/docs/_config.yml +0 -8
- data/docs/color_schemes/256-light.png +0 -0
- data/docs/color_schemes/256.png +0 -0
- data/docs/color_schemes/deep-space.png +0 -0
- data/docs/color_schemes/gruvbox.png +0 -0
- data/docs/color_schemes/one-half-dark.png +0 -0
- data/docs/color_schemes/one-half-light.png +0 -0
- data/docs/demo.png +0 -0
- data/docs/guide-ui.png +0 -0
- data/docs/index.md +0 -238
- data/docs/logo.jpg +0 -0
- data/docs/screen-backtrace.png +0 -0
- data/docs/screen-repl.png +0 -0
- data/docs/screen-source.png +0 -0
- data/docs/screen-threads.png +0 -0
- data/docs/screen-variables.png +0 -0
- data/images/bg_hr.png +0 -0
- data/images/blacktocat.png +0 -0
- data/images/body-bg.jpg +0 -0
- data/images/download-button.png +0 -0
- data/images/github-button.png +0 -0
- data/images/header-bg.jpg +0 -0
- data/images/highlight-bg.jpg +0 -0
- data/images/icon_download.png +0 -0
- data/images/sidebar-bg.jpg +0 -0
- data/images/sprite_download.png +0 -0
- data/javascripts/main.js +0 -1
- data/stylesheets/github-light.css +0 -130
- data/stylesheets/normalize.css +0 -424
- data/stylesheets/print.css +0 -228
- data/stylesheets/stylesheet.css +0 -245
@@ -25,7 +25,7 @@ module RubyJard
|
|
25
25
|
def calculate_content_lengths
|
26
26
|
@screen.rows.each do |row|
|
27
27
|
row.columns.each do |column|
|
28
|
-
column.content_length = column.spans.map(&:content_length).inject(&:+)
|
28
|
+
column.content_length = column.spans.map(&:content_length).inject(&:+) || 0
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -5,18 +5,43 @@ module RubyJard
|
|
5
5
|
##
|
6
6
|
# Backtrace screen implements the content to display current thread's backtrace to the user.
|
7
7
|
class BacktraceScreen < RubyJard::Screen
|
8
|
+
def initialize(*args)
|
9
|
+
super(*args)
|
10
|
+
@current_frame = @session.current_frame
|
11
|
+
@frames =
|
12
|
+
@session
|
13
|
+
.current_backtrace
|
14
|
+
.select(&:visible?)
|
15
|
+
.sort { |a, b| a.virtual_pos.to_i <=> b.virtual_pos.to_i }
|
16
|
+
insert_current_frame
|
17
|
+
@selected =
|
18
|
+
if @current_frame.nil?
|
19
|
+
0
|
20
|
+
else
|
21
|
+
@frames.find_index { |f| f.real_pos == @current_frame.real_pos }
|
22
|
+
end
|
23
|
+
@frames_count = @frames.length
|
24
|
+
@hidden_frames_count = @session.current_backtrace.length - @frames.length
|
25
|
+
|
26
|
+
@path_decorator = RubyJard::Decorators::PathDecorator.new
|
27
|
+
end
|
28
|
+
|
8
29
|
def title
|
9
|
-
|
30
|
+
if @hidden_frames_count <= 0
|
31
|
+
['Backtrace', "#{@frames_count} frames"]
|
32
|
+
else
|
33
|
+
['Backtrace', "#{@frames_count} frames - #{@hidden_frames_count} hidden"]
|
34
|
+
end
|
10
35
|
end
|
11
36
|
|
12
37
|
def build
|
13
|
-
@rows = @
|
38
|
+
@rows = @frames.map do |frame|
|
14
39
|
RubyJard::Row.new(
|
15
40
|
line_limit: 2,
|
16
41
|
columns: [
|
17
42
|
RubyJard::Column.new(
|
18
43
|
spans: [
|
19
|
-
|
44
|
+
span_frame_pos(frame)
|
20
45
|
]
|
21
46
|
),
|
22
47
|
RubyJard::Column.new(
|
@@ -30,33 +55,38 @@ module RubyJard
|
|
30
55
|
]
|
31
56
|
)
|
32
57
|
end
|
33
|
-
@selected = current_frame
|
34
58
|
end
|
35
59
|
|
36
60
|
private
|
37
61
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
62
|
+
def span_frame_pos(frame)
|
63
|
+
frame_pos_label =
|
64
|
+
if frame.hidden?
|
65
|
+
'*'.rjust(@frames_count.to_s.length)
|
66
|
+
else
|
67
|
+
frame.virtual_pos.to_s.rjust(@frames_count.to_s.length)
|
68
|
+
end
|
69
|
+
if frame.real_pos == @current_frame.real_pos
|
41
70
|
RubyJard::Span.new(
|
42
|
-
content: "
|
43
|
-
styles: :
|
71
|
+
content: "⮕ #{frame_pos_label}",
|
72
|
+
styles: :text_selected
|
44
73
|
)
|
45
74
|
else
|
46
75
|
RubyJard::Span.new(
|
47
|
-
content: " #{
|
48
|
-
styles: :
|
76
|
+
content: " #{frame_pos_label}",
|
77
|
+
styles: :text_dim
|
49
78
|
)
|
50
79
|
end
|
51
80
|
end
|
52
81
|
|
53
82
|
def span_class_label(frame)
|
83
|
+
self_class = RubyJard::Reflection.call_class(frame.frame_self)
|
54
84
|
class_label =
|
55
|
-
if frame.frame_class.nil? ||
|
56
|
-
if frame.frame_self
|
85
|
+
if frame.frame_class.nil? || self_class == frame.frame_class
|
86
|
+
if ::RubyJard::Reflection.call_is_a?(frame.frame_self, Class)
|
57
87
|
frame.frame_self.name
|
58
88
|
else
|
59
|
-
|
89
|
+
self_class.name
|
60
90
|
end
|
61
91
|
elsif frame.frame_class.singleton_class?
|
62
92
|
# No easy way to get the original class of a singleton class
|
@@ -77,7 +107,7 @@ module RubyJard
|
|
77
107
|
RubyJard::Span.new(
|
78
108
|
content: 'in',
|
79
109
|
margin_right: 1,
|
80
|
-
styles: :
|
110
|
+
styles: :text_primary
|
81
111
|
)
|
82
112
|
end
|
83
113
|
|
@@ -96,39 +126,25 @@ module RubyJard
|
|
96
126
|
end
|
97
127
|
|
98
128
|
def span_path(frame)
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
if decorated_path.gem?
|
103
|
-
"in #{decorated_path.gem} (#{decorated_path.gem_version})"
|
104
|
-
else
|
105
|
-
"at #{decorated_path.path}:#{decorated_path.lineno}"
|
106
|
-
end
|
129
|
+
path_label, = @path_decorator.decorate(
|
130
|
+
frame.frame_location.path, frame.frame_location.lineno
|
131
|
+
)
|
107
132
|
RubyJard::Span.new(
|
108
133
|
content: path_label,
|
109
|
-
styles: :
|
134
|
+
styles: :text_primary
|
110
135
|
)
|
111
136
|
end
|
112
137
|
|
113
|
-
def
|
114
|
-
|
115
|
-
end
|
138
|
+
def insert_current_frame
|
139
|
+
return if @current_frame.visible?
|
116
140
|
|
117
|
-
|
118
|
-
if
|
119
|
-
|
141
|
+
index = @frames.find_index { |f| @current_frame.real_pos < f.real_pos }
|
142
|
+
if index.nil?
|
143
|
+
@frames << @current_frame
|
120
144
|
else
|
121
|
-
@
|
145
|
+
@frames.insert(index, @current_frame)
|
122
146
|
end
|
123
147
|
end
|
124
|
-
|
125
|
-
def frames_count
|
126
|
-
@session.current_backtrace.length
|
127
|
-
end
|
128
|
-
|
129
|
-
def decorate_path(path, lineno)
|
130
|
-
RubyJard::Decorators::PathDecorator.new(path, lineno)
|
131
|
-
end
|
132
148
|
end
|
133
149
|
end
|
134
150
|
end
|
@@ -5,6 +5,14 @@ module RubyJard
|
|
5
5
|
##
|
6
6
|
# Display key binding guidelines and shortcuts.
|
7
7
|
class MenuScreen < RubyJard::Screen
|
8
|
+
def initialize(*args)
|
9
|
+
super(*args)
|
10
|
+
@filter = RubyJard.config.filter
|
11
|
+
@filter_included = RubyJard.config.filter_included
|
12
|
+
@filter_excluded = RubyJard.config.filter_excluded
|
13
|
+
@selected = 0
|
14
|
+
end
|
15
|
+
|
8
16
|
def build
|
9
17
|
left_spans = generate_left_spans
|
10
18
|
right_spans = generate_right_spans
|
@@ -21,45 +29,37 @@ module RubyJard
|
|
21
29
|
)
|
22
30
|
]
|
23
31
|
)]
|
24
|
-
@selected = 0
|
25
32
|
end
|
26
33
|
|
27
34
|
private
|
28
35
|
|
29
36
|
def generate_left_spans
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
37
|
+
filter_mode_span = RubyJard::Span.new(
|
38
|
+
content: "Filter (F2): #{@filter.to_s.gsub(/_/, ' ').capitalize}",
|
39
|
+
styles: :text_special
|
40
|
+
)
|
41
|
+
filter_details =
|
42
|
+
@filter_included.map { |f| "+#{f}" } +
|
43
|
+
@filter_excluded.map { |f| "-#{f}" }
|
44
|
+
if filter_details.empty?
|
45
|
+
[filter_mode_span]
|
46
|
+
else
|
47
|
+
filter_exceprt = filter_details.first(3).join(' ')
|
48
|
+
filter_more = filter_details.length > 3 ? " (#{filter_details.length - 3} more...)" : nil
|
49
|
+
filter_details_span = RubyJard::Span.new(
|
50
|
+
content: "#{filter_exceprt}#{filter_more}",
|
51
|
+
styles: :text_primary,
|
52
|
+
margin_left: 1
|
34
53
|
)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
# ),
|
41
|
-
# RubyJard::Span.new(
|
42
|
-
# margin_left: 1,
|
43
|
-
# content: 'All gems',
|
44
|
-
# styles: :menu_mode
|
45
|
-
# ),
|
46
|
-
# RubyJard::Span.new(
|
47
|
-
# margin_left: 1,
|
48
|
-
# content: '|',
|
49
|
-
# styles: :menu_tips
|
50
|
-
# ),
|
51
|
-
# RubyJard::Span.new(
|
52
|
-
# margin_left: 1,
|
53
|
-
# content: 'Application only',
|
54
|
-
# styles: :menu_tips
|
55
|
-
# )
|
56
|
-
# ]
|
54
|
+
[
|
55
|
+
filter_mode_span,
|
56
|
+
filter_details_span
|
57
|
+
]
|
58
|
+
end
|
57
59
|
end
|
58
60
|
|
59
61
|
def generate_right_spans
|
60
62
|
[
|
61
|
-
'Up (F6)',
|
62
|
-
'Down (Shift+F6)',
|
63
63
|
'Step (F7)',
|
64
64
|
'Step Out (Shift+F7)',
|
65
65
|
'Next (F8)',
|
@@ -68,7 +68,7 @@ module RubyJard
|
|
68
68
|
RubyJard::Span.new(
|
69
69
|
content: menu_item,
|
70
70
|
margin_left: 3,
|
71
|
-
styles: :
|
71
|
+
styles: :text_primary
|
72
72
|
)
|
73
73
|
end
|
74
74
|
end
|
@@ -5,49 +5,50 @@ module RubyJard
|
|
5
5
|
##
|
6
6
|
# Display source code of current stopping line and surrounding lines
|
7
7
|
class SourceScreen < RubyJard::Screen
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
def initialize(*args)
|
9
|
+
super
|
10
|
+
@frame_file = @session.current_frame&.frame_file
|
11
|
+
@frame_line = @session.current_frame&.frame_line
|
12
|
+
|
13
|
+
if !@frame_file.nil? && !@frame_line.nil?
|
14
|
+
@path_decorator = RubyJard::Decorators::PathDecorator.new
|
15
|
+
@loc_decorator = RubyJard::Decorators::LocDecorator.new
|
16
|
+
@source_decorator = RubyJard::Decorators::SourceDecorator.new(@frame_file, @frame_line, @layout.height)
|
17
|
+
end
|
18
|
+
|
19
|
+
@selected = 0
|
20
|
+
end
|
11
21
|
|
12
22
|
def title
|
13
|
-
return 'Source' if @
|
23
|
+
return 'Source' if @frame_file.nil? || @frame_line.nil?
|
14
24
|
|
15
|
-
|
16
|
-
|
17
|
-
['Source', "#{decorated_path.gem} - #{decorated_path.path}:#{decorated_path.lineno}"]
|
18
|
-
else
|
19
|
-
['Source', "#{decorated_path.path}:#{decorated_path.lineno}"]
|
20
|
-
end
|
25
|
+
_, path_label = @path_decorator.decorate(@frame_file, @frame_line)
|
26
|
+
['Source', path_label]
|
21
27
|
end
|
22
28
|
|
23
29
|
def build
|
24
|
-
return if @
|
30
|
+
return 'Source' if @frame_file.nil? || @frame_line.nil?
|
25
31
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
)
|
46
|
-
]
|
47
|
-
)
|
48
|
-
end
|
32
|
+
# TODO: screen now supports window.
|
33
|
+
codes = @source_decorator.codes
|
34
|
+
@rows = codes.map.with_index do |loc, index|
|
35
|
+
lineno = @source_decorator.window_start + index
|
36
|
+
RubyJard::Row.new(
|
37
|
+
line_limit: 3,
|
38
|
+
columns: [
|
39
|
+
RubyJard::Column.new(
|
40
|
+
spans: [
|
41
|
+
span_mark(lineno),
|
42
|
+
span_lineno(lineno)
|
43
|
+
]
|
44
|
+
),
|
45
|
+
RubyJard::Column.new(
|
46
|
+
word_wrap: RubyJard::Column::WORD_WRAP_BREAK_WORD,
|
47
|
+
spans: loc_spans(loc)
|
48
|
+
)
|
49
|
+
]
|
50
|
+
)
|
49
51
|
end
|
50
|
-
@selected = 0
|
51
52
|
end
|
52
53
|
|
53
54
|
private
|
@@ -83,44 +84,27 @@ module RubyJard
|
|
83
84
|
]
|
84
85
|
end
|
85
86
|
|
86
|
-
def span_mark(
|
87
|
-
lineno = source_lineno(index)
|
87
|
+
def span_mark(lineno)
|
88
88
|
RubyJard::Span.new(
|
89
89
|
margin_right: 1,
|
90
|
-
content: @
|
91
|
-
styles: :
|
90
|
+
content: @frame_line == lineno ? '⮕' : ' ',
|
91
|
+
styles: :text_selected
|
92
92
|
)
|
93
93
|
end
|
94
94
|
|
95
|
-
def span_lineno(
|
96
|
-
|
95
|
+
def span_lineno(lineno)
|
96
|
+
padded_lineno = lineno.to_s.rjust(@source_decorator.window_end.to_s.length)
|
97
97
|
RubyJard::Span.new(
|
98
|
-
content:
|
99
|
-
styles: @
|
98
|
+
content: padded_lineno,
|
99
|
+
styles: @frame_line == lineno ? :text_selected : :text_dim
|
100
100
|
)
|
101
101
|
end
|
102
102
|
|
103
103
|
def loc_spans(loc)
|
104
|
-
|
105
|
-
spans
|
106
|
-
end
|
107
|
-
|
108
|
-
def path_decorator(path, lineno)
|
109
|
-
@path_decorator ||= RubyJard::Decorators::PathDecorator.new(path, lineno)
|
110
|
-
end
|
104
|
+
return [] if @frame_file.nil?
|
111
105
|
|
112
|
-
|
113
|
-
|
114
|
-
@session.current_frame.frame_file, @session.current_frame.frame_line, @layout.height
|
115
|
-
)
|
116
|
-
end
|
117
|
-
|
118
|
-
def loc_decorator
|
119
|
-
@loc_decorator ||= RubyJard::Decorators::LocDecorator.new
|
120
|
-
end
|
121
|
-
|
122
|
-
def source_lineno(index)
|
123
|
-
source_decorator.window_start + index
|
106
|
+
spans, _tokens = @loc_decorator.decorate(loc, @frame_file)
|
107
|
+
spans
|
124
108
|
end
|
125
109
|
end
|
126
110
|
end
|
@@ -5,122 +5,116 @@ module RubyJard
|
|
5
5
|
##
|
6
6
|
# Display all current alive threads, excluding internal threads
|
7
7
|
class ThreadsScreen < RubyJard::Screen
|
8
|
+
def initialize(*args)
|
9
|
+
super
|
10
|
+
@current_frame_location = @session.current_frame&.frame_location
|
11
|
+
@current_thread = @session.current_thread
|
12
|
+
@threads = @session.threads
|
13
|
+
|
14
|
+
@selected = @threads.index { |c| current_thread?(c) }
|
15
|
+
@path_decorator = RubyJard::Decorators::PathDecorator.new
|
16
|
+
end
|
17
|
+
|
8
18
|
def title
|
9
|
-
['Threads', "#{@
|
19
|
+
['Threads', "#{@threads.length} threads"]
|
10
20
|
end
|
11
21
|
|
12
22
|
def build
|
13
|
-
|
14
|
-
|
15
|
-
@rows = contexts.map do |context|
|
23
|
+
threads = sort_threads(@threads)
|
24
|
+
@rows = threads.map do |thread|
|
16
25
|
RubyJard::Row.new(
|
17
26
|
line_limit: 2,
|
18
27
|
columns: [
|
19
28
|
RubyJard::Column.new(
|
20
29
|
spans: [
|
21
|
-
span_mark(
|
22
|
-
|
30
|
+
span_mark(thread),
|
31
|
+
span_thread_label(thread)
|
23
32
|
]
|
24
33
|
),
|
25
34
|
RubyJard::Column.new(
|
26
35
|
spans: [
|
27
|
-
span_thread_status(
|
36
|
+
span_thread_status(thread)
|
28
37
|
]
|
29
38
|
),
|
30
39
|
RubyJard::Column.new(
|
31
40
|
spans: [
|
32
|
-
span_thread_name(
|
33
|
-
span_thread_location(
|
41
|
+
span_thread_name(thread),
|
42
|
+
span_thread_location(thread)
|
34
43
|
]
|
35
44
|
)
|
36
45
|
]
|
37
46
|
)
|
38
47
|
end
|
39
|
-
@selected = contexts.index { |c| current_thread?(c) }
|
40
48
|
end
|
41
49
|
|
42
50
|
private
|
43
51
|
|
44
|
-
def span_mark(
|
45
|
-
style = thread_status_style(context.thread)
|
52
|
+
def span_mark(thread)
|
46
53
|
RubyJard::Span.new(
|
47
54
|
margin_right: 1,
|
48
|
-
content:
|
49
|
-
styles:
|
55
|
+
content: thread.status == 'run' ? '▸' : '•',
|
56
|
+
styles: thread_status_style(thread)
|
50
57
|
)
|
51
58
|
end
|
52
59
|
|
53
|
-
def
|
60
|
+
def span_thread_label(thread)
|
54
61
|
RubyJard::Span.new(
|
55
|
-
content: "Thread #{
|
56
|
-
styles: :
|
62
|
+
content: "Thread #{thread.label}",
|
63
|
+
styles: :text_highlighted
|
57
64
|
)
|
58
65
|
end
|
59
66
|
|
60
|
-
def span_thread_status(
|
67
|
+
def span_thread_status(thread)
|
61
68
|
RubyJard::Span.new(
|
62
|
-
content: "(#{
|
63
|
-
styles: thread_status_style(
|
69
|
+
content: "(#{thread.status})",
|
70
|
+
styles: thread_status_style(thread)
|
64
71
|
)
|
65
72
|
end
|
66
73
|
|
67
|
-
def span_thread_name(
|
74
|
+
def span_thread_name(thread)
|
68
75
|
RubyJard::Span.new(
|
69
76
|
margin_right: 1,
|
70
|
-
content:
|
71
|
-
styles: :
|
77
|
+
content: thread.name.nil? ? 'untitled' : thread.name,
|
78
|
+
styles: :text_primary
|
72
79
|
)
|
73
80
|
end
|
74
81
|
|
75
|
-
def span_thread_location(
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
@session.current_frame.frame_location
|
82
|
+
def span_thread_location(thread)
|
83
|
+
path_label, =
|
84
|
+
if current_thread?(thread)
|
85
|
+
@path_decorator.decorate(
|
86
|
+
@current_frame_location.path,
|
87
|
+
@current_frame_location.lineno
|
88
|
+
)
|
83
89
|
else
|
84
|
-
|
90
|
+
@path_decorator.decorate(
|
91
|
+
thread.backtrace_locations[1]&.path,
|
92
|
+
thread.backtrace_locations[1]&.lineno
|
93
|
+
)
|
85
94
|
end
|
86
95
|
|
87
|
-
return unknown_thread_location if last_backtrace.nil?
|
88
|
-
|
89
|
-
decorated_path = decorate_path(last_backtrace.path, last_backtrace.lineno)
|
90
|
-
if decorated_path.gem?
|
91
|
-
RubyJard::Span.new(
|
92
|
-
content: "in #{decorated_path.gem} (#{decorated_path.gem_version})",
|
93
|
-
styles: :thread_location
|
94
|
-
)
|
95
|
-
else
|
96
|
-
RubyJard::Span.new(
|
97
|
-
content: "at #{decorated_path.path}:#{decorated_path.lineno}",
|
98
|
-
styles: :thread_location
|
99
|
-
)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def unknown_thread_location
|
104
96
|
RubyJard::Span.new(
|
105
|
-
content:
|
106
|
-
styles: :
|
97
|
+
content: path_label,
|
98
|
+
styles: :text_primary
|
107
99
|
)
|
108
100
|
end
|
109
101
|
|
110
|
-
def
|
111
|
-
# Sort: current
|
112
|
-
# Sort: not debug
|
113
|
-
# Sort: not suspended
|
102
|
+
def sort_threads(threads)
|
103
|
+
# Sort: current thread first
|
104
|
+
# Sort: not debug thread first
|
105
|
+
# Sort: not suspended thread first
|
114
106
|
# Sort: sort by thread num
|
115
|
-
|
107
|
+
threads.sort do |a, b|
|
116
108
|
[
|
117
109
|
bool_to_int(current_thread?(a)),
|
118
|
-
bool_to_int(b.
|
119
|
-
a.
|
110
|
+
bool_to_int(b.name.nil?),
|
111
|
+
a.name,
|
112
|
+
a.backtrace_locations[0].to_s
|
120
113
|
] <=> [
|
121
114
|
bool_to_int(current_thread?(b)),
|
122
|
-
bool_to_int(a.
|
123
|
-
b.
|
115
|
+
bool_to_int(a.name.nil?),
|
116
|
+
b.name,
|
117
|
+
b.backtrace_locations[0].to_s
|
124
118
|
]
|
125
119
|
end
|
126
120
|
end
|
@@ -129,22 +123,15 @@ module RubyJard
|
|
129
123
|
bool == true ? -1 : 1
|
130
124
|
end
|
131
125
|
|
132
|
-
def current_thread?(
|
133
|
-
|
134
|
-
end
|
135
|
-
|
136
|
-
def decorate_path(path, lineno)
|
137
|
-
RubyJard::Decorators::PathDecorator.new(path, lineno)
|
126
|
+
def current_thread?(thread)
|
127
|
+
thread == @current_thread
|
138
128
|
end
|
139
129
|
|
140
130
|
def thread_status_style(thread)
|
141
|
-
|
142
|
-
|
143
|
-
:thread_status_run
|
144
|
-
when 'sleep'
|
145
|
-
:thread_status_sleep
|
131
|
+
if thread.status == 'run'
|
132
|
+
:text_selected
|
146
133
|
else
|
147
|
-
:
|
134
|
+
:text_dim
|
148
135
|
end
|
149
136
|
end
|
150
137
|
end
|