ruby_jard 0.2.0 → 0.2.1

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/CHANGELOG.md +18 -0
  4. data/CNAME +1 -0
  5. data/README.md +206 -33
  6. data/_config.yml +1 -0
  7. data/docs/_config.yml +8 -0
  8. data/docs/demo.png +0 -0
  9. data/docs/index.md +238 -0
  10. data/docs/logo.jpg +0 -0
  11. data/docs/screen-backtrace.png +0 -0
  12. data/docs/screen-repl.png +0 -0
  13. data/docs/screen-source.png +0 -0
  14. data/docs/screen-threads.png +0 -0
  15. data/docs/screen-variables.png +0 -0
  16. data/images/bg_hr.png +0 -0
  17. data/images/blacktocat.png +0 -0
  18. data/images/body-bg.jpg +0 -0
  19. data/images/download-button.png +0 -0
  20. data/images/github-button.png +0 -0
  21. data/images/header-bg.jpg +0 -0
  22. data/images/highlight-bg.jpg +0 -0
  23. data/images/icon_download.png +0 -0
  24. data/images/sidebar-bg.jpg +0 -0
  25. data/images/sprite_download.png +0 -0
  26. data/javascripts/main.js +1 -0
  27. data/lib/ruby_jard.rb +3 -18
  28. data/lib/ruby_jard/box_drawer.rb +68 -22
  29. data/lib/ruby_jard/color_scheme.rb +28 -0
  30. data/lib/ruby_jard/color_schemes.rb +26 -0
  31. data/lib/ruby_jard/color_schemes/256_color_scheme.rb +64 -0
  32. data/lib/ruby_jard/color_schemes/deep_space_color_scheme.rb +63 -0
  33. data/lib/ruby_jard/column.rb +12 -6
  34. data/lib/ruby_jard/commands/continue_command.rb +1 -0
  35. data/lib/ruby_jard/commands/list_command.rb +29 -0
  36. data/lib/ruby_jard/commands/next_command.rb +1 -0
  37. data/lib/ruby_jard/commands/step_command.rb +1 -0
  38. data/lib/ruby_jard/commands/step_out_command.rb +1 -0
  39. data/lib/ruby_jard/console.rb +102 -18
  40. data/lib/ruby_jard/control_flow.rb +9 -8
  41. data/lib/ruby_jard/decorators/color_decorator.rb +46 -57
  42. data/lib/ruby_jard/decorators/inspection_decorator.rb +76 -0
  43. data/lib/ruby_jard/decorators/loc_decorator.rb +83 -107
  44. data/lib/ruby_jard/decorators/source_decorator.rb +1 -1
  45. data/lib/ruby_jard/keys.rb +1 -0
  46. data/lib/ruby_jard/layout.rb +9 -99
  47. data/lib/ruby_jard/layout_calculator.rb +151 -0
  48. data/lib/ruby_jard/layouts/narrow_layout.rb +41 -0
  49. data/lib/ruby_jard/layouts/wide_layout.rb +17 -103
  50. data/lib/ruby_jard/repl_processor.rb +5 -1
  51. data/lib/ruby_jard/repl_proxy.rb +2 -1
  52. data/lib/ruby_jard/row.rb +5 -5
  53. data/lib/ruby_jard/row_renderer.rb +108 -0
  54. data/lib/ruby_jard/screen.rb +20 -115
  55. data/lib/ruby_jard/screen_drawer.rb +8 -75
  56. data/lib/ruby_jard/screen_manager.rb +78 -55
  57. data/lib/ruby_jard/screen_renderer.rb +138 -0
  58. data/lib/ruby_jard/screens/backtrace_screen.rb +67 -69
  59. data/lib/ruby_jard/screens/menu_screen.rb +43 -38
  60. data/lib/ruby_jard/screens/source_screen.rb +43 -27
  61. data/lib/ruby_jard/screens/threads_screen.rb +91 -39
  62. data/lib/ruby_jard/screens/variables_screen.rb +72 -56
  63. data/lib/ruby_jard/session.rb +16 -0
  64. data/lib/ruby_jard/span.rb +8 -6
  65. data/lib/ruby_jard/version.rb +1 -1
  66. data/ruby_jard.gemspec +4 -4
  67. data/stylesheets/github-light.css +130 -0
  68. data/stylesheets/normalize.css +424 -0
  69. data/stylesheets/print.css +228 -0
  70. data/stylesheets/stylesheet.css +245 -0
  71. metadata +52 -21
  72. data/lib/ruby_jard/templates/column_template.rb +0 -17
  73. data/lib/ruby_jard/templates/row_template.rb +0 -22
  74. data/lib/ruby_jard/templates/space_template.rb +0 -15
  75. data/lib/ruby_jard/templates/span_template.rb +0 -25
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ console.log('This would be the main JS file.');
@@ -41,8 +41,10 @@ require 'ruby_jard/version'
41
41
  module RubyJard
42
42
  class Error < StandardError; end
43
43
 
44
+ DEFAULT_COLOR_SCHEME = '256'
44
45
  DEFAULT_LAYOUT_TEMPLATES = [
45
- RubyJard::Layouts::WideLayout
46
+ RubyJard::Layouts::WideLayout,
47
+ RubyJard::Layouts::NarrowLayout
46
48
  ].freeze
47
49
 
48
50
  def self.current_session
@@ -95,20 +97,3 @@ module Kernel
95
97
  RubyJard.current_session.attach
96
98
  end
97
99
  end
98
-
99
- ##
100
- # Globally configure Byebug. Byebug doesn't allow configuration by instance.
101
- # So, I have no choice.
102
- # TODO: Byebug autoloaded configuration may override those values.
103
- Byebug::Setting[:autolist] = false
104
- Byebug::Setting[:autoirb] = false
105
- Byebug::Setting[:autopry] = false
106
- Byebug::Context.processor = RubyJard::ReplProcessor
107
- # Exclude all files in Ruby Jard source code from the stacktrace.
108
- Byebug::Context.ignored_files = Byebug::Context.all_files + Dir.glob(
109
- File.join(
110
- File.expand_path(__dir__, '../lib'),
111
- '**',
112
- '*.rb'
113
- )
114
- )
@@ -45,10 +45,10 @@ module RubyJard
45
45
  [BOTTOM_RIGHT, BOTTOM_LEFT] => '┴'
46
46
  }.freeze
47
47
 
48
- def initialize(output:, screens:)
48
+ def initialize(output:, screens:, color_scheme:)
49
49
  @output = output
50
50
  @screens = screens
51
- @color_decorator = RubyJard::Decorators::ColorDecorator.new
51
+ @color_decorator = RubyJard::Decorators::ColorDecorator.new(color_scheme)
52
52
  end
53
53
 
54
54
  def draw
@@ -63,17 +63,26 @@ module RubyJard
63
63
  def draw_basic_lines
64
64
  # Exclude the corners
65
65
  @screens.each do |screen|
66
- RubyJard::Console.move_to(@output, screen.x + 1, screen.y)
67
- @output.print HORIZONTAL_LINE * (screen.width - 2)
66
+ RubyJard::Console.move_to(
67
+ @output,
68
+ screen.layout.box_x + 1,
69
+ screen.layout.box_y
70
+ )
71
+ @output.print colorize_border(HORIZONTAL_LINE * (screen.layout.box_width - 2))
68
72
 
69
- RubyJard::Console.move_to(@output, screen.x + 1, screen.y + screen.height - 1)
70
- @output.print HORIZONTAL_LINE * (screen.width - 2)
73
+ RubyJard::Console.move_to(
74
+ @output,
75
+ screen.layout.box_x + 1,
76
+ screen.layout.box_y + screen.layout.box_height - 1
77
+ )
78
+ @output.print colorize_border(HORIZONTAL_LINE * (screen.layout.box_width - 2))
71
79
 
72
- (screen.y + 1..screen.y + screen.height - 2).each do |moving_y|
73
- RubyJard::Console.move_to(@output, screen.x, moving_y)
74
- @output.print VERTICAL_LINE
75
- RubyJard::Console.move_to(@output, screen.x + screen.width - 1, moving_y)
76
- @output.print VERTICAL_LINE
80
+ (screen.layout.box_y + 1..screen.layout.box_y + screen.layout.box_height - 2).each do |moving_y|
81
+ RubyJard::Console.move_to(@output, screen.layout.box_x, moving_y)
82
+ @output.print colorize_border(VERTICAL_LINE)
83
+
84
+ RubyJard::Console.move_to(@output, screen.layout.box_x + screen.layout.box_width - 1, moving_y)
85
+ @output.print colorize_border(VERTICAL_LINE)
77
86
  end
78
87
  end
79
88
  end
@@ -85,12 +94,12 @@ module RubyJard
85
94
 
86
95
  case ids.length
87
96
  when 1
88
- @output.print NORMALS_CORNERS[ids.first]
97
+ @output.print colorize_border(NORMALS_CORNERS[ids.first])
89
98
  when 2
90
99
  ids = ids.sort
91
- @output.print OVERLAPPED_CORNERS[ids]
100
+ @output.print colorize_border(OVERLAPPED_CORNERS[ids])
92
101
  else
93
- @output.print CROSS_CORNER
102
+ @output.print colorize_border(CROSS_CORNER)
94
103
  end
95
104
  end
96
105
  end
@@ -99,20 +108,53 @@ module RubyJard
99
108
  def draw_titles
100
109
  @screens.each do |screen|
101
110
  next unless screen.respond_to?(:title)
102
- RubyJard::Console.move_to(@output, screen.x + 2, screen.y)
103
- @output.print ' '
104
- @output.print @color_decorator.decorate(screen.title, :bright_yellow, :bold)
105
- @output.print ' '
111
+
112
+ RubyJard::Console.move_to(@output, screen.layout.box_x + 1, screen.layout.box_y)
113
+ total_length = 0
114
+ title_parts = Array(screen.title)
115
+ title_parts.each_with_index do |title_part, index|
116
+ if index == 0
117
+ @output.print @color_decorator.decorate(:title, " #{title_part} ")
118
+ else
119
+ @output.print @color_decorator.decorate(:title_secondary, " #{title_part} ")
120
+ end
121
+ total_length += title_part.length + 2
122
+ end
123
+ title_background = screen.layout.box_width - total_length - 2
124
+ @output.print @color_decorator.decorate(
125
+ :title_background,
126
+ ' ' * (title_background < 0 ? 0 : title_background)
127
+ )
106
128
  end
107
129
  end
108
130
 
109
131
  def calculate_corners
110
132
  corners = {}
111
133
  @screens.each do |screen|
112
- mark_corner(corners, screen.x, screen.y, TOP_LEFT)
113
- mark_corner(corners, screen.x + screen.width - 1, screen.y, TOP_RIGHT)
114
- mark_corner(corners, screen.x + screen.width - 1, screen.y + screen.height - 1, BOTTOM_RIGHT)
115
- mark_corner(corners, screen.x, screen.y + screen.height - 1, BOTTOM_LEFT)
134
+ mark_corner(
135
+ corners,
136
+ screen.layout.box_x,
137
+ screen.layout.box_y,
138
+ TOP_LEFT
139
+ )
140
+ mark_corner(
141
+ corners,
142
+ screen.layout.box_x + screen.layout.box_width - 1,
143
+ screen.layout.box_y,
144
+ TOP_RIGHT
145
+ )
146
+ mark_corner(
147
+ corners,
148
+ screen.layout.box_x + screen.layout.box_width - 1,
149
+ screen.layout.box_y + screen.layout.box_height - 1,
150
+ BOTTOM_RIGHT
151
+ )
152
+ mark_corner(
153
+ corners,
154
+ screen.layout.box_x,
155
+ screen.layout.box_y + screen.layout.box_height - 1,
156
+ BOTTOM_LEFT
157
+ )
116
158
  end
117
159
  corners
118
160
  end
@@ -122,5 +164,9 @@ module RubyJard
122
164
  corners[x][y] ||= []
123
165
  corners[x][y] << id unless corners[x][y].include?(id)
124
166
  end
167
+
168
+ def colorize_border(content)
169
+ @color_decorator.decorate(:border, content)
170
+ end
125
171
  end
126
172
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyJard
4
+ ##
5
+ # Abstract class of all color scheme.
6
+ class ColorScheme
7
+ def initialize(styles: self.class.const_get(:STYLES))
8
+ @styles = {}
9
+ styles.each do |element, element_styles|
10
+ update(element, element_styles)
11
+ end
12
+ end
13
+
14
+ ##
15
+ # Fetch the styles for a particular element defined in the scheme.
16
+ # This method returns an array of two or more elements:
17
+ # - First element is foreground color
18
+ # - Second element is background color
19
+ # - The rest is decorating items, such as underline, italic
20
+ def styles_for(element)
21
+ @styles[element].dup
22
+ end
23
+
24
+ def update(element, styles)
25
+ @styles[element] = styles
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyJard
4
+ ##
5
+ # Color scheme registry.
6
+ module ColorSchemes
7
+ class << self
8
+ def color_scheme_registry
9
+ @color_scheme_registry ||= {}
10
+ end
11
+
12
+ def add_color_scheme(name, color_scheme_class)
13
+ unless color_scheme_class < RubyJard::ColorScheme
14
+ raise RubyJard::Error, "#{color_scheme_class} must implement, and inherit from #{RubyJard::ColorScheme}"
15
+ end
16
+
17
+ color_scheme_registry[name] = color_scheme_class
18
+ end
19
+
20
+ def [](name)
21
+ color_scheme_registry[name]
22
+ end
23
+ alias get []
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyJard
4
+ module ColorSchemes
5
+ class X256ColorScheme < ColorScheme
6
+ # Basic 256 colors that nearly all terminal supports. Just for backward-compatibility
7
+ # https://en.wikipedia.org/wiki/ANSI_escape_code
8
+ GRAY1 = '234'
9
+ GRAY2 = '238'
10
+ GRAY3 = '241'
11
+ GRAY4 = '245'
12
+ GRAY5 = '249'
13
+ WHITE = '15'
14
+ RED = '167'
15
+ GREEN = '40'
16
+ DARK_GREEN = '34'
17
+ YELLOW = '184'
18
+ BLUE = '75'
19
+ PURPLE = '177'
20
+ CYAN = '50'
21
+ ORANGE = '208'
22
+ PINK = '206'
23
+
24
+ BACKGROUND = nil
25
+ STYLES = {
26
+ background: [WHITE, BACKGROUND],
27
+ border: [GRAY2, BACKGROUND],
28
+ title: [GRAY1, BLUE],
29
+ title_highlighted: [GRAY1, ORANGE],
30
+ title_secondary: [WHITE, GRAY3],
31
+ title_background: [WHITE, GRAY2],
32
+ control_buttons: [GRAY4, BACKGROUND],
33
+ thread_id: [BLUE, BACKGROUND],
34
+ thread_name: [WHITE, BACKGROUND],
35
+ thread_status_run: [GREEN, BACKGROUND],
36
+ thread_status_sleep: [GRAY4, BACKGROUND],
37
+ thread_status_other: [GRAY4, BACKGROUND],
38
+ thread_location: [GRAY5, BACKGROUND],
39
+ frame_id: [GRAY4, BACKGROUND],
40
+ frame_id_highlighted: [GREEN, BACKGROUND],
41
+ frame_location: [GRAY5, BACKGROUND],
42
+ variable_mark: [GRAY4, BACKGROUND],
43
+ variable_mark_inline: [GREEN, BACKGROUND],
44
+ variable_size: [GRAY5, BACKGROUND],
45
+ variable_inspection: [GRAY4, BACKGROUND],
46
+ variable_assignment: [WHITE, BACKGROUND],
47
+ source_line_mark: [GREEN, BACKGROUND],
48
+ source_lineno: [GRAY4, BACKGROUND],
49
+ keyword: [BLUE, BACKGROUND],
50
+ method: [YELLOW, BACKGROUND],
51
+ comment: [GRAY4, BACKGROUND],
52
+ literal: [RED, BACKGROUND],
53
+ string: [DARK_GREEN, BACKGROUND],
54
+ local_variable: [PURPLE, BACKGROUND],
55
+ instance_variable: [PURPLE, BACKGROUND],
56
+ constant: [BLUE, BACKGROUND],
57
+ normal_token: [GRAY5, BACKGROUND],
58
+ object: [CYAN, BACKGROUND]
59
+ }.freeze
60
+ end
61
+ end
62
+ end
63
+
64
+ RubyJard::ColorSchemes.add_color_scheme('256', RubyJard::ColorSchemes::X256ColorScheme)
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyJard
4
+ module ColorSchemes
5
+ class DeepSpaceColorScheme < ColorScheme
6
+ # Shameless copy from https://github.com/tyrannicaltoucan/vim-deep-space/blob/master/colors/deep-space.vim
7
+ GRAY1 = '#1b202a'
8
+ GRAY2 = '#232936'
9
+ GRAY3 = '#323c4d'
10
+ GRAY4 = '#51617d'
11
+ GRAY5 = '#9aa7bd'
12
+ WHITE = '#fff'
13
+ RED = '#b15e7c'
14
+ GREEN = '#96f08d'
15
+ DARK_GREEN = '#709d6c'
16
+ YELLOW = '#e8cb6b'
17
+ BLUE = '#78b5ff'
18
+ PURPLE = '#b08aed'
19
+ CYAN = '#56adb7'
20
+ ORANGE = '#f28d5e'
21
+ PINK = '#c47ebd'
22
+
23
+ BACKGROUND = GRAY1
24
+ STYLES = {
25
+ background: [WHITE, BACKGROUND],
26
+ border: [GRAY3, BACKGROUND],
27
+ title: [GRAY2, BLUE],
28
+ title_highlighted: [GRAY2, ORANGE],
29
+ title_secondary: [WHITE, GRAY3],
30
+ title_background: [WHITE, GRAY2],
31
+ control_buttons: [GRAY4, BACKGROUND],
32
+ thread_id: [BLUE, BACKGROUND],
33
+ thread_name: [WHITE, BACKGROUND],
34
+ thread_status_run: [GREEN, BACKGROUND],
35
+ thread_status_sleep: [GRAY4, BACKGROUND],
36
+ thread_status_other: [GRAY4, BACKGROUND],
37
+ thread_location: [GRAY5, BACKGROUND],
38
+ frame_id: [GRAY4, BACKGROUND],
39
+ frame_id_highlighted: [GREEN, BACKGROUND],
40
+ frame_location: [GRAY5, BACKGROUND],
41
+ variable_mark: [GRAY4, BACKGROUND],
42
+ variable_mark_inline: [GREEN, BACKGROUND],
43
+ variable_size: [GRAY5, BACKGROUND],
44
+ variable_inspection: [GRAY4, BACKGROUND],
45
+ variable_assignment: [WHITE, BACKGROUND],
46
+ source_line_mark: [GREEN, BACKGROUND],
47
+ source_lineno: [GRAY4, BACKGROUND],
48
+ keyword: [BLUE, BACKGROUND],
49
+ method: [YELLOW, BACKGROUND],
50
+ comment: [GRAY4, BACKGROUND],
51
+ literal: [RED, BACKGROUND],
52
+ string: [DARK_GREEN, BACKGROUND],
53
+ local_variable: [PURPLE, BACKGROUND],
54
+ instance_variable: [PURPLE, BACKGROUND],
55
+ constant: [BLUE, BACKGROUND],
56
+ normal_token: [GRAY5, BACKGROUND],
57
+ object: [CYAN, BACKGROUND]
58
+ }.freeze
59
+ end
60
+ end
61
+ end
62
+
63
+ RubyJard::ColorSchemes.add_color_scheme('deep-space', RubyJard::ColorSchemes::DeepSpaceColorScheme)
@@ -2,17 +2,23 @@
2
2
 
3
3
  module RubyJard
4
4
  class Column
5
+ # Only break at breakable word
6
+ # | this_is_a <endline> |
7
+ # | really_long_content |
8
+ WORD_WRAP_NORMAL = :normal
9
+ # Break the word, and move the rest to the next line
10
+ # | this_is_a really_lon|
11
+ # | g_content |
12
+ WORD_WRAP_BREAK_WORD = :break_word
5
13
  extend Forwardable
6
14
 
7
- attr_accessor :column_template, :spans, :content_length, :width
15
+ attr_accessor :spans, :content_length, :width, :word_wrap
8
16
 
9
- def_delegators :@column_template, :margin_left, :margin_right
10
-
11
- def initialize(column_template:)
12
- @column_template = column_template
13
- @spans = []
17
+ def initialize(spans: [], word_wrap: WORD_WRAP_NORMAL)
18
+ @spans = spans
14
19
  @width = 0
15
20
  @content_length = 0
21
+ @word_wrap = word_wrap
16
22
  end
17
23
  end
18
24
  end
@@ -26,3 +26,4 @@ module RubyJard
26
26
  end
27
27
 
28
28
  Pry::Commands.add_command(RubyJard::Commands::ContinueCommand)
29
+ Pry::Commands.alias_command 'c', 'continue'
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyJard
4
+ module Commands
5
+ # Command used to explore stacktrace.
6
+ class ListCommand < Pry::ClassCommand
7
+ group 'RubyJard'
8
+ description 'Refresh the current UI'
9
+
10
+ match 'list'
11
+
12
+ banner <<-BANNER
13
+ Usage:
14
+ - list
15
+ - l
16
+
17
+ Refresh the current UI.
18
+
19
+ BANNER
20
+
21
+ def process
22
+ RubyJard::ControlFlow.dispatch(:list)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ Pry::Commands.add_command(RubyJard::Commands::ListCommand)
29
+ Pry::Commands.alias_command 'l', 'list'