ruby_jard 0.2.3 → 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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +3 -0
  3. data/.github/workflows/documentation.yml +65 -0
  4. data/.github/workflows/{ruby.yml → rspec.yml} +22 -11
  5. data/.rubocop.yml +6 -0
  6. data/CHANGELOG.md +15 -3
  7. data/Gemfile +9 -2
  8. data/README.md +52 -332
  9. data/benchmark/path_filter_bench.rb +58 -0
  10. data/lib/ruby_jard.rb +15 -5
  11. data/lib/ruby_jard/color_schemes.rb +9 -1
  12. data/lib/ruby_jard/color_schemes/256_color_scheme.rb +21 -35
  13. data/lib/ruby_jard/color_schemes/256_light_color_scheme.rb +23 -35
  14. data/lib/ruby_jard/color_schemes/deep_space_color_scheme.rb +20 -34
  15. data/lib/ruby_jard/color_schemes/gruvbox_color_scheme.rb +20 -34
  16. data/lib/ruby_jard/color_schemes/one_half_dark_color_scheme.rb +20 -34
  17. data/lib/ruby_jard/color_schemes/one_half_light_color_scheme.rb +21 -34
  18. data/lib/ruby_jard/commands/color_helpers.rb +32 -0
  19. data/lib/ruby_jard/commands/frame_command.rb +2 -2
  20. data/lib/ruby_jard/commands/jard/color_scheme_command.rb +25 -3
  21. data/lib/ruby_jard/commands/jard/filter_command.rb +136 -0
  22. data/lib/ruby_jard/commands/jard/output_command.rb +13 -5
  23. data/lib/ruby_jard/commands/jard_command.rb +3 -1
  24. data/lib/ruby_jard/config.rb +9 -2
  25. data/lib/ruby_jard/decorators/array_decorator.rb +79 -0
  26. data/lib/ruby_jard/decorators/attributes_decorator.rb +172 -0
  27. data/lib/ruby_jard/decorators/color_decorator.rb +12 -5
  28. data/lib/ruby_jard/decorators/hash_decorator.rb +74 -0
  29. data/lib/ruby_jard/decorators/inspection_decorator.rb +91 -58
  30. data/lib/ruby_jard/decorators/object_decorator.rb +122 -0
  31. data/lib/ruby_jard/decorators/path_decorator.rb +55 -72
  32. data/lib/ruby_jard/decorators/rails_decorator.rb +194 -0
  33. data/lib/ruby_jard/decorators/string_decorator.rb +41 -0
  34. data/lib/ruby_jard/decorators/struct_decorator.rb +79 -0
  35. data/lib/ruby_jard/frame.rb +23 -10
  36. data/lib/ruby_jard/keys.rb +1 -0
  37. data/lib/ruby_jard/layouts/narrow_horizontal_layout.rb +4 -0
  38. data/lib/ruby_jard/layouts/tiny_layout.rb +4 -0
  39. data/lib/ruby_jard/pager.rb +21 -5
  40. data/lib/ruby_jard/path_classifier.rb +133 -0
  41. data/lib/ruby_jard/path_filter.rb +125 -0
  42. data/lib/ruby_jard/reflection.rb +97 -0
  43. data/lib/ruby_jard/repl_processor.rb +71 -38
  44. data/lib/ruby_jard/row_renderer.rb +5 -3
  45. data/lib/ruby_jard/screen.rb +2 -2
  46. data/lib/ruby_jard/screen_manager.rb +13 -36
  47. data/lib/ruby_jard/screen_renderer.rb +1 -1
  48. data/lib/ruby_jard/screens/backtrace_screen.rb +55 -39
  49. data/lib/ruby_jard/screens/menu_screen.rb +30 -30
  50. data/lib/ruby_jard/screens/source_screen.rb +46 -62
  51. data/lib/ruby_jard/screens/threads_screen.rb +59 -72
  52. data/lib/ruby_jard/screens/variables_screen.rb +168 -124
  53. data/lib/ruby_jard/session.rb +120 -16
  54. data/lib/ruby_jard/thread_info.rb +69 -0
  55. data/lib/ruby_jard/version.rb +1 -1
  56. data/ruby_jard.gemspec +3 -1
  57. metadata +20 -39
  58. data/.travis.yml +0 -6
  59. data/CNAME +0 -1
  60. data/_config.yml +0 -1
  61. data/docs/_config.yml +0 -8
  62. data/docs/color_schemes/256-light.png +0 -0
  63. data/docs/color_schemes/256.png +0 -0
  64. data/docs/color_schemes/deep-space.png +0 -0
  65. data/docs/color_schemes/gruvbox.png +0 -0
  66. data/docs/color_schemes/one-half-dark.png +0 -0
  67. data/docs/color_schemes/one-half-light.png +0 -0
  68. data/docs/demo.png +0 -0
  69. data/docs/guide-ui.png +0 -0
  70. data/docs/index.md +0 -238
  71. data/docs/logo.jpg +0 -0
  72. data/docs/screen-backtrace.png +0 -0
  73. data/docs/screen-repl.png +0 -0
  74. data/docs/screen-source.png +0 -0
  75. data/docs/screen-threads.png +0 -0
  76. data/docs/screen-variables.png +0 -0
  77. data/images/bg_hr.png +0 -0
  78. data/images/blacktocat.png +0 -0
  79. data/images/body-bg.jpg +0 -0
  80. data/images/download-button.png +0 -0
  81. data/images/github-button.png +0 -0
  82. data/images/header-bg.jpg +0 -0
  83. data/images/highlight-bg.jpg +0 -0
  84. data/images/icon_download.png +0 -0
  85. data/images/sidebar-bg.jpg +0 -0
  86. data/images/sprite_download.png +0 -0
  87. data/javascripts/main.js +0 -1
  88. data/stylesheets/github-light.css +0 -130
  89. data/stylesheets/normalize.css +0 -424
  90. data/stylesheets/print.css +0 -228
  91. 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
- ['Backtrace', "#{frames_count} frames"]
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 = @session.current_backtrace.map.with_index do |frame, frame_id|
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
- span_frame_id(frame_id)
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 span_frame_id(frame_id)
39
- frame_id_label = frame_id.to_s.rjust(frames_count.to_s.length)
40
- if current_frame?(frame_id)
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: " #{frame_id_label}",
43
- styles: :frame_id_highlighted
71
+ content: " #{frame_pos_label}",
72
+ styles: :text_selected
44
73
  )
45
74
  else
46
75
  RubyJard::Span.new(
47
- content: " #{frame_id_label}",
48
- styles: :frame_id
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? || frame.frame_self.class == frame.frame_class
56
- if frame.frame_self.is_a?(Class)
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
- frame.frame_self.class.name
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: :frame_location
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
- decorated_path = decorate_path(frame.frame_location.absolute_path, frame.frame_location.lineno)
100
-
101
- path_label =
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: :frame_location
134
+ styles: :text_primary
110
135
  )
111
136
  end
112
137
 
113
- def current_frame?(frame_id)
114
- frame_id == current_frame
115
- end
138
+ def insert_current_frame
139
+ return if @current_frame.visible?
116
140
 
117
- def current_frame
118
- if @session.current_frame.nil?
119
- 0
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
- @session.current_frame.pos.to_i
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
- RubyJard::Span.new(
32
- content: ' REPL ',
33
- styles: :title_highlighted
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
- # RubyJard::Span.new(
38
- # content: ' Mode (F2) ',
39
- # styles: :title_highlighted
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: :menu_tips
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
- ANONYMOUS_SIGNATURES = [
9
- '(eval)', '-e'
10
- ].freeze
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 @session.current_frame.nil?
23
+ return 'Source' if @frame_file.nil? || @frame_line.nil?
14
24
 
15
- decorated_path = path_decorator(@session.current_frame.frame_file, @session.current_frame.frame_line)
16
- if decorated_path.gem?
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 @session.current_frame.nil?
30
+ return 'Source' if @frame_file.nil? || @frame_line.nil?
25
31
 
26
- if ANONYMOUS_SIGNATURES.include? @session.current_frame.frame_file
27
- # (eval) is hard-coded in Ruby source code for in-code evaluation
28
- handle_anonymous_evaluation
29
- else
30
- # TODO: screen now supports window.
31
- codes = source_decorator.codes
32
- @rows = codes.map.with_index do |loc, index|
33
- RubyJard::Row.new(
34
- line_limit: 3,
35
- columns: [
36
- RubyJard::Column.new(
37
- spans: [
38
- span_mark(index),
39
- span_lineno(index)
40
- ]
41
- ),
42
- RubyJard::Column.new(
43
- word_wrap: RubyJard::Column::WORD_WRAP_BREAK_WORD,
44
- spans: loc_spans(loc)
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(index)
87
- lineno = source_lineno(index)
87
+ def span_mark(lineno)
88
88
  RubyJard::Span.new(
89
89
  margin_right: 1,
90
- content: @session.current_frame.frame_line == lineno ? '' : ' ',
91
- styles: :source_line_mark
90
+ content: @frame_line == lineno ? '' : ' ',
91
+ styles: :text_selected
92
92
  )
93
93
  end
94
94
 
95
- def span_lineno(index)
96
- lineno = source_lineno(index).to_s.rjust(source_decorator.window_end.to_s.length)
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: lineno,
99
- styles: @session.current_frame.frame_line == lineno ? :source_line_mark : :source_lineno
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
- spans, _tokens = loc_decorator.decorate(loc, @session.current_frame.frame_file)
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
- def source_decorator
113
- @source_decorator ||= RubyJard::Decorators::SourceDecorator.new(
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', "#{@session.threads.length} threads"]
19
+ ['Threads', "#{@threads.length} threads"]
10
20
  end
11
21
 
12
22
  def build
13
- contexts = @session.threads.select { |c| c.thread.alive? }
14
- contexts = sort_contexts(contexts)
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(context),
22
- span_thread_id(context)
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(context)
36
+ span_thread_status(thread)
28
37
  ]
29
38
  ),
30
39
  RubyJard::Column.new(
31
40
  spans: [
32
- span_thread_name(context),
33
- span_thread_location(context)
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(context)
45
- style = thread_status_style(context.thread)
52
+ def span_mark(thread)
46
53
  RubyJard::Span.new(
47
54
  margin_right: 1,
48
- content: style == :thread_status_run ? '' : '•',
49
- styles: style
55
+ content: thread.status == 'run' ? '' : '•',
56
+ styles: thread_status_style(thread)
50
57
  )
51
58
  end
52
59
 
53
- def span_thread_id(context)
60
+ def span_thread_label(thread)
54
61
  RubyJard::Span.new(
55
- content: "Thread #{context.thread.object_id}",
56
- styles: :thread_id
62
+ content: "Thread #{thread.label}",
63
+ styles: :text_highlighted
57
64
  )
58
65
  end
59
66
 
60
- def span_thread_status(context)
67
+ def span_thread_status(thread)
61
68
  RubyJard::Span.new(
62
- content: "(#{context.thread.status})",
63
- styles: thread_status_style(context.thread)
69
+ content: "(#{thread.status})",
70
+ styles: thread_status_style(thread)
64
71
  )
65
72
  end
66
73
 
67
- def span_thread_name(context)
74
+ def span_thread_name(thread)
68
75
  RubyJard::Span.new(
69
76
  margin_right: 1,
70
- content: context.thread.name.nil? ? 'untitled' : context.thread.name,
71
- styles: :thread_name
77
+ content: thread.name.nil? ? 'untitled' : thread.name,
78
+ styles: :text_primary
72
79
  )
73
80
  end
74
81
 
75
- def span_thread_location(context)
76
- return unknown_thread_location if
77
- context.thread.backtrace_locations.nil? ||
78
- @session.current_frame.frame_location.nil?
79
-
80
- last_backtrace =
81
- if current_thread?(context)
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
- context.thread.backtrace_locations[1]
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: 'at ???',
106
- styles: :thread_location
97
+ content: path_label,
98
+ styles: :text_primary
107
99
  )
108
100
  end
109
101
 
110
- def sort_contexts(contexts)
111
- # Sort: current context first
112
- # Sort: not debug context first
113
- # Sort: not suspended context first
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
- contexts.sort do |a, b|
107
+ threads.sort do |a, b|
116
108
  [
117
109
  bool_to_int(current_thread?(a)),
118
- bool_to_int(b.thread.name.nil?),
119
- a.thread.object_id
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.thread.name.nil?),
123
- b.thread.object_id
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?(context)
133
- context.thread == Thread.current
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
- case thread.status
142
- when 'run'
143
- :thread_status_run
144
- when 'sleep'
145
- :thread_status_sleep
131
+ if thread.status == 'run'
132
+ :text_selected
146
133
  else
147
- :thread_status_other
134
+ :text_dim
148
135
  end
149
136
  end
150
137
  end