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.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -1
- data/CHANGELOG.md +18 -0
- data/CNAME +1 -0
- data/README.md +206 -33
- data/_config.yml +1 -0
- data/docs/_config.yml +8 -0
- data/docs/demo.png +0 -0
- data/docs/index.md +238 -0
- 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 +1 -0
- data/lib/ruby_jard.rb +3 -18
- data/lib/ruby_jard/box_drawer.rb +68 -22
- data/lib/ruby_jard/color_scheme.rb +28 -0
- data/lib/ruby_jard/color_schemes.rb +26 -0
- data/lib/ruby_jard/color_schemes/256_color_scheme.rb +64 -0
- data/lib/ruby_jard/color_schemes/deep_space_color_scheme.rb +63 -0
- data/lib/ruby_jard/column.rb +12 -6
- data/lib/ruby_jard/commands/continue_command.rb +1 -0
- data/lib/ruby_jard/commands/list_command.rb +29 -0
- data/lib/ruby_jard/commands/next_command.rb +1 -0
- data/lib/ruby_jard/commands/step_command.rb +1 -0
- data/lib/ruby_jard/commands/step_out_command.rb +1 -0
- data/lib/ruby_jard/console.rb +102 -18
- data/lib/ruby_jard/control_flow.rb +9 -8
- data/lib/ruby_jard/decorators/color_decorator.rb +46 -57
- data/lib/ruby_jard/decorators/inspection_decorator.rb +76 -0
- data/lib/ruby_jard/decorators/loc_decorator.rb +83 -107
- data/lib/ruby_jard/decorators/source_decorator.rb +1 -1
- data/lib/ruby_jard/keys.rb +1 -0
- data/lib/ruby_jard/layout.rb +9 -99
- data/lib/ruby_jard/layout_calculator.rb +151 -0
- data/lib/ruby_jard/layouts/narrow_layout.rb +41 -0
- data/lib/ruby_jard/layouts/wide_layout.rb +17 -103
- data/lib/ruby_jard/repl_processor.rb +5 -1
- data/lib/ruby_jard/repl_proxy.rb +2 -1
- data/lib/ruby_jard/row.rb +5 -5
- data/lib/ruby_jard/row_renderer.rb +108 -0
- data/lib/ruby_jard/screen.rb +20 -115
- data/lib/ruby_jard/screen_drawer.rb +8 -75
- data/lib/ruby_jard/screen_manager.rb +78 -55
- data/lib/ruby_jard/screen_renderer.rb +138 -0
- data/lib/ruby_jard/screens/backtrace_screen.rb +67 -69
- data/lib/ruby_jard/screens/menu_screen.rb +43 -38
- data/lib/ruby_jard/screens/source_screen.rb +43 -27
- data/lib/ruby_jard/screens/threads_screen.rb +91 -39
- data/lib/ruby_jard/screens/variables_screen.rb +72 -56
- data/lib/ruby_jard/session.rb +16 -0
- data/lib/ruby_jard/span.rb +8 -6
- data/lib/ruby_jard/version.rb +1 -1
- data/ruby_jard.gemspec +4 -4
- data/stylesheets/github-light.css +130 -0
- data/stylesheets/normalize.css +424 -0
- data/stylesheets/print.css +228 -0
- data/stylesheets/stylesheet.css +245 -0
- metadata +52 -21
- data/lib/ruby_jard/templates/column_template.rb +0 -17
- data/lib/ruby_jard/templates/row_template.rb +0 -22
- data/lib/ruby_jard/templates/space_template.rb +0 -15
- data/lib/ruby_jard/templates/span_template.rb +0 -25
@@ -120,7 +120,7 @@ module RubyJard
|
|
120
120
|
# Do nothing
|
121
121
|
end
|
122
122
|
|
123
|
-
def handle_key_binding_command(options)
|
123
|
+
def handle_key_binding_command(options = {})
|
124
124
|
method_name = "handle_#{options[:action]}_command"
|
125
125
|
if respond_to?(method_name, true)
|
126
126
|
send(method_name)
|
@@ -129,5 +129,9 @@ module RubyJard
|
|
129
129
|
"Fail to handle key binding `#{options[:action]}`"
|
130
130
|
end
|
131
131
|
end
|
132
|
+
|
133
|
+
def handle_list_command(_options = {})
|
134
|
+
process_commands
|
135
|
+
end
|
132
136
|
end
|
133
137
|
end
|
data/lib/ruby_jard/repl_proxy.rb
CHANGED
@@ -7,6 +7,7 @@ require 'ruby_jard/commands/next_command'
|
|
7
7
|
require 'ruby_jard/commands/step_command'
|
8
8
|
require 'ruby_jard/commands/step_out_command'
|
9
9
|
require 'ruby_jard/commands/frame_command'
|
10
|
+
require 'ruby_jard/commands/list_command'
|
10
11
|
|
11
12
|
module RubyJard
|
12
13
|
##
|
@@ -80,7 +81,7 @@ module RubyJard
|
|
80
81
|
end
|
81
82
|
|
82
83
|
def read_key
|
83
|
-
|
84
|
+
RubyJard::Console.getch(STDIN, KEYPRESS_POLLING)
|
84
85
|
end
|
85
86
|
|
86
87
|
def repl(current_binding)
|
data/lib/ruby_jard/row.rb
CHANGED
@@ -4,13 +4,13 @@ module RubyJard
|
|
4
4
|
class Row
|
5
5
|
extend Forwardable
|
6
6
|
|
7
|
-
attr_accessor :
|
7
|
+
attr_accessor :columns, :line_limit, :content
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
def initialize(row_template:, columns: [])
|
12
|
-
@row_template = row_template
|
9
|
+
def initialize(line_limit: 1, columns: [], ellipsis: true)
|
10
|
+
@content = []
|
13
11
|
@columns = columns
|
12
|
+
@ellipsis = ellipsis
|
13
|
+
@line_limit = line_limit
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyJard
|
4
|
+
##
|
5
|
+
# Generate bitmap lines from a row's data
|
6
|
+
class RowRenderer
|
7
|
+
ELLIPSIS = ' »'
|
8
|
+
|
9
|
+
def initialize(row:, width:, height:, color_scheme:)
|
10
|
+
@row = row
|
11
|
+
@width = width
|
12
|
+
@height = height
|
13
|
+
@color_decorator = RubyJard::Decorators::ColorDecorator.new(color_scheme)
|
14
|
+
end
|
15
|
+
|
16
|
+
def render
|
17
|
+
@x = 0
|
18
|
+
@y = 0
|
19
|
+
@content_map = []
|
20
|
+
|
21
|
+
original_x = 0
|
22
|
+
@row.columns.each_with_index do |column, index|
|
23
|
+
@y = 0
|
24
|
+
@x = original_x
|
25
|
+
content_width = column.width
|
26
|
+
content_width -= 1 if index < @row.columns.length - 1
|
27
|
+
render_column(column, original_x, content_width)
|
28
|
+
|
29
|
+
original_x += column.width
|
30
|
+
end
|
31
|
+
|
32
|
+
generate_bitmap
|
33
|
+
end
|
34
|
+
|
35
|
+
def render_column(column, original_x, content_width)
|
36
|
+
width = 0
|
37
|
+
lines = 1
|
38
|
+
|
39
|
+
column.spans.each do |span|
|
40
|
+
line_content = span.content
|
41
|
+
|
42
|
+
until line_content.nil? || line_content.empty?
|
43
|
+
if column.word_wrap == RubyJard::Column::WORD_WRAP_NORMAL
|
44
|
+
if content_width - width < line_content.length && width != 0
|
45
|
+
width = 0
|
46
|
+
lines += 1
|
47
|
+
@y += 1
|
48
|
+
@x = original_x
|
49
|
+
end
|
50
|
+
elsif column.word_wrap == RubyJard::Column::WORD_WRAP_BREAK_WORD
|
51
|
+
if content_width - width <= 0
|
52
|
+
width = 0
|
53
|
+
lines += 1
|
54
|
+
@y += 1
|
55
|
+
@x = original_x
|
56
|
+
end
|
57
|
+
elsif content_width - width <= 0
|
58
|
+
return
|
59
|
+
end
|
60
|
+
drawing_content = line_content[0..content_width - width - 1]
|
61
|
+
line_content = line_content[content_width - width..-1]
|
62
|
+
width += drawing_content.length
|
63
|
+
|
64
|
+
if !@row.line_limit.nil? && lines >= @row.line_limit && !line_content.nil? && !line_content.empty?
|
65
|
+
drawing_content[drawing_content.length - ELLIPSIS.length..-1] = ELLIPSIS
|
66
|
+
draw_content(drawing_content, span.styles)
|
67
|
+
return
|
68
|
+
else
|
69
|
+
draw_content(drawing_content, span.styles)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def draw_content(drawing_content, styles)
|
76
|
+
return if @y < 0 || @y >= @height
|
77
|
+
|
78
|
+
@content_map[@y] ||= []
|
79
|
+
@content_map[@y][@x] = [styles, drawing_content]
|
80
|
+
@x += drawing_content.length
|
81
|
+
end
|
82
|
+
|
83
|
+
def generate_bitmap
|
84
|
+
@row.content = []
|
85
|
+
@content_map.each do |line|
|
86
|
+
line_content = ''
|
87
|
+
pending_content = ''
|
88
|
+
|
89
|
+
cell_index = 0
|
90
|
+
while cell_index < @width
|
91
|
+
cell = line[cell_index]
|
92
|
+
if cell.nil? || cell[1].empty?
|
93
|
+
pending_content += ' '
|
94
|
+
cell_index += 1
|
95
|
+
else
|
96
|
+
line_content += @color_decorator.decorate(:background, pending_content)
|
97
|
+
line_content += @color_decorator.decorate(cell[0], cell[1])
|
98
|
+
pending_content = ''
|
99
|
+
cell_index += cell[1].length
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
line_content += @color_decorator.decorate(:background, pending_content) unless pending_content.empty?
|
104
|
+
@row.content << line_content
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/lib/ruby_jard/screen.rb
CHANGED
@@ -6,134 +6,39 @@ module RubyJard
|
|
6
6
|
# generated based on input layout specifiation, screen data, and top-left
|
7
7
|
# corner cordination.
|
8
8
|
class Screen
|
9
|
-
attr_accessor :
|
9
|
+
attr_accessor :layout, :rows, :color_scheme, :window, :cursor, :selected
|
10
10
|
|
11
|
-
def initialize(
|
11
|
+
def initialize(session: nil, layout:, color_scheme:)
|
12
12
|
@session = session || RubyJard.current_session
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
18
|
-
end
|
19
|
-
|
20
|
-
def draw(output)
|
21
|
-
calculate
|
22
|
-
drawer = RubyJard::ScreenDrawer.new(
|
23
|
-
output: output,
|
24
|
-
screen: self,
|
25
|
-
x: @x,
|
26
|
-
y: @y
|
27
|
-
)
|
28
|
-
drawer.draw
|
29
|
-
end
|
30
|
-
|
31
|
-
def data_size
|
32
|
-
raise NotImplementedError, "#{self.class} must implement #data_size method"
|
33
|
-
end
|
34
|
-
|
35
|
-
def data_window
|
36
|
-
raise NotImplementedError, "#{self.class} must implement #data_window method"
|
37
|
-
end
|
38
|
-
|
39
|
-
def calculate
|
13
|
+
@layout = layout
|
14
|
+
@color_scheme = color_scheme
|
15
|
+
@window = []
|
16
|
+
@cursor = nil
|
17
|
+
@selected = 0
|
40
18
|
@rows = []
|
41
|
-
|
42
|
-
@rows = data_window.map.with_index do |data_row, index|
|
43
|
-
create_row(row_template, data_row, index)
|
44
|
-
end
|
45
|
-
column_widths = calculate_column_widths(row_template, @rows)
|
46
|
-
fill_column_widths(@rows, column_widths)
|
19
|
+
@need_to_render = true
|
47
20
|
end
|
48
21
|
|
49
|
-
|
22
|
+
def move_down; end
|
50
23
|
|
51
|
-
def
|
52
|
-
column_widths = {}
|
53
|
-
ideal_column_width = @width / row_template.columns.length
|
54
|
-
row_template.columns.each_with_index do |_column_template, column_index|
|
55
|
-
column_widths[column_index] ||= 0
|
56
|
-
rows.each do |row|
|
57
|
-
column = row.columns[column_index]
|
58
|
-
if column.content_length > ideal_column_width
|
59
|
-
column_widths[column_index] = nil
|
60
|
-
break
|
61
|
-
elsif column.content_length > column_widths[column_index]
|
62
|
-
column_widths[column_index] = column.content_length
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
column_widths
|
67
|
-
end
|
24
|
+
def move_up; end
|
68
25
|
|
69
|
-
def
|
70
|
-
fixed_count = column_widths.length
|
71
|
-
fixed_width = column_widths.values.inject(0) do |sum, col|
|
72
|
-
col.nil? ? sum : sum + col
|
73
|
-
end
|
26
|
+
def page_up; end
|
74
27
|
|
75
|
-
|
76
|
-
total_width = 0
|
77
|
-
row.columns.each_with_index do |column, column_index|
|
78
|
-
column.width =
|
79
|
-
if column_index == row.columns.length - 1
|
80
|
-
@width - total_width
|
81
|
-
elsif column_widths[column_index].nil?
|
82
|
-
(@width - fixed_width) / fixed_count
|
83
|
-
else
|
84
|
-
column_widths[column_index]
|
85
|
-
end
|
86
|
-
total_width += column.width
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
28
|
+
def page_down; end
|
90
29
|
|
91
|
-
def
|
92
|
-
row = Row.new(row_template: row_template)
|
93
|
-
row.columns = row_template.columns.map do |column_template|
|
94
|
-
create_column(column_template, data_row, index)
|
95
|
-
end
|
96
|
-
row
|
97
|
-
end
|
30
|
+
def click(relative_x, relative_y); end
|
98
31
|
|
99
|
-
def
|
100
|
-
|
101
|
-
column.spans = column_template.spans.map do |span_template|
|
102
|
-
create_span(span_template, data_row, index)
|
103
|
-
end.flatten
|
104
|
-
column.content_length =
|
105
|
-
column.spans.map(&:content_length).inject(&:+) +
|
106
|
-
column.margin_left +
|
107
|
-
column.margin_right
|
108
|
-
column
|
32
|
+
def build
|
33
|
+
raise NotImplementedError, "#{self.class} should implement this method."
|
109
34
|
end
|
110
35
|
|
111
|
-
def
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
if respond_to?(span_content_method)
|
116
|
-
content, styles = send(span_content_method, data_row, index)
|
117
|
-
if content.nil?
|
118
|
-
span.content = ''
|
119
|
-
span.content_length = 0
|
120
|
-
elsif content.is_a?(Array)
|
121
|
-
content.each do |sub_span|
|
122
|
-
sub_span.styles += Array(styles).flatten.compact
|
123
|
-
end
|
124
|
-
return content
|
125
|
-
else
|
126
|
-
content = ' ' * span_template.margin_left + content if span_template.margin_left
|
127
|
-
content += ' ' * span_template.margin_right if span_template.margin_right
|
128
|
-
span.content = content
|
129
|
-
span.styles = Array(styles).flatten.compact
|
130
|
-
span.content_length = span.content.length
|
131
|
-
end
|
132
|
-
else
|
133
|
-
raise NotImplementedError, "#{self.class} must implement #{span_content_method} method"
|
134
|
-
end
|
36
|
+
def need_to_render?
|
37
|
+
@need_to_render == true
|
38
|
+
end
|
135
39
|
|
136
|
-
|
40
|
+
def mark_rendered!
|
41
|
+
@need_to_render = false
|
137
42
|
end
|
138
43
|
end
|
139
44
|
end
|
@@ -1,89 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RubyJard
|
4
|
-
##
|
5
|
-
# Draw a screen and its rows into the output interface.
|
6
4
|
class ScreenDrawer
|
7
|
-
|
8
|
-
|
9
|
-
ELLIPSIS = ' »'
|
10
|
-
|
11
|
-
def initialize(output:, screen:, x:, y:)
|
5
|
+
def initialize(output:, screen:, color_scheme:)
|
12
6
|
@output = output
|
13
|
-
@color_decorator = RubyJard::Decorators::ColorDecorator.new
|
14
|
-
@x = x
|
15
|
-
@y = y
|
16
|
-
@original_x = x
|
17
|
-
@original_y = y
|
18
7
|
@screen = screen
|
8
|
+
@color_decorator = RubyJard::Decorators::ColorDecorator.new(color_scheme)
|
19
9
|
end
|
20
10
|
|
21
11
|
def draw
|
22
|
-
@
|
23
|
-
|
24
|
-
|
25
|
-
@y += 1
|
26
|
-
@x = @original_x
|
12
|
+
@screen.window.each_with_index do |line, index|
|
13
|
+
RubyJard::Console.move_to(@output, @screen.layout.x, @screen.layout.y + index)
|
14
|
+
@output.print line
|
27
15
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
def draw_columns(row, columns)
|
33
|
-
columns.each do |column|
|
34
|
-
width = 0
|
35
|
-
lines = 1
|
36
|
-
column_content_width = column.width - column.margin_left - column.margin_right
|
37
|
-
@x += column.margin_left
|
38
|
-
RubyJard::Console.move_to(@output, @x, @y)
|
39
|
-
|
40
|
-
column.spans.each do |span|
|
41
|
-
line_content = span.content
|
42
|
-
|
43
|
-
until line_content.nil? || line_content.empty?
|
44
|
-
if column_content_width - width <= 0
|
45
|
-
width = 0
|
46
|
-
lines += 1
|
47
|
-
@y += 1
|
48
|
-
RubyJard::Console.move_to(@output, @x, @y)
|
49
|
-
end
|
50
|
-
drawing_content = line_content[0..column_content_width - width - 1]
|
51
|
-
line_content = line_content[column_content_width - width..-1]
|
52
|
-
width += drawing_content.length
|
53
|
-
|
54
|
-
if !row.line_limit.nil? && lines >= row.line_limit && !line_content.nil? && !line_content.empty?
|
55
|
-
drawing_content[drawing_content.length - ELLIPSIS.length..-1] = ELLIPSIS
|
56
|
-
protected_print @color_decorator.decorate(drawing_content, *span.styles)
|
57
|
-
break
|
58
|
-
else
|
59
|
-
protected_print @color_decorator.decorate(drawing_content, *span.styles)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
@x += column_content_width + column.margin_right
|
16
|
+
(@screen.window.length..@screen.layout.height - 1).each do |index|
|
17
|
+
RubyJard::Console.move_to(@output, @screen.layout.x, @screen.layout.y + index)
|
18
|
+
@output.print @color_decorator.decorate(:background, ' ' * @screen.layout.width)
|
64
19
|
end
|
65
20
|
end
|
66
|
-
|
67
|
-
def protected_print(content)
|
68
|
-
# TODO: currently, only row overflow is detected. Definitely should handle column overflow
|
69
|
-
return if @y < @original_y || @y > @original_y + @screen.height - 1
|
70
|
-
|
71
|
-
@output.print content
|
72
|
-
end
|
73
|
-
|
74
|
-
def default_frame_styles
|
75
|
-
{
|
76
|
-
style: {
|
77
|
-
fg: :white
|
78
|
-
},
|
79
|
-
border: {
|
80
|
-
bottom_left: false,
|
81
|
-
bottom_right: false,
|
82
|
-
bottom: false,
|
83
|
-
left: :line,
|
84
|
-
right: false
|
85
|
-
}
|
86
|
-
}
|
87
|
-
end
|
88
21
|
end
|
89
22
|
end
|
@@ -6,11 +6,24 @@ require 'ruby_jard/decorators/color_decorator'
|
|
6
6
|
require 'ruby_jard/decorators/path_decorator'
|
7
7
|
require 'ruby_jard/decorators/loc_decorator'
|
8
8
|
require 'ruby_jard/decorators/source_decorator'
|
9
|
+
require 'ruby_jard/decorators/inspection_decorator'
|
9
10
|
|
10
11
|
require 'ruby_jard/screen'
|
12
|
+
require 'ruby_jard/screens'
|
13
|
+
|
14
|
+
require 'ruby_jard/color_scheme'
|
15
|
+
require 'ruby_jard/color_schemes'
|
16
|
+
require 'ruby_jard/color_schemes/deep_space_color_scheme'
|
17
|
+
require 'ruby_jard/color_schemes/256_color_scheme'
|
18
|
+
|
19
|
+
require 'ruby_jard/row'
|
20
|
+
require 'ruby_jard/column'
|
21
|
+
require 'ruby_jard/span'
|
22
|
+
require 'ruby_jard/row_renderer'
|
23
|
+
require 'ruby_jard/screen_renderer'
|
11
24
|
require 'ruby_jard/box_drawer'
|
12
25
|
require 'ruby_jard/screen_drawer'
|
13
|
-
|
26
|
+
|
14
27
|
require 'ruby_jard/screens/source_screen'
|
15
28
|
require 'ruby_jard/screens/backtrace_screen'
|
16
29
|
require 'ruby_jard/screens/threads_screen'
|
@@ -19,16 +32,11 @@ require 'ruby_jard/screens/menu_screen'
|
|
19
32
|
|
20
33
|
require 'ruby_jard/templates/layout_template'
|
21
34
|
require 'ruby_jard/templates/screen_template'
|
22
|
-
require 'ruby_jard/templates/row_template'
|
23
|
-
require 'ruby_jard/templates/column_template'
|
24
|
-
require 'ruby_jard/templates/span_template'
|
25
|
-
require 'ruby_jard/templates/space_template'
|
26
35
|
|
27
36
|
require 'ruby_jard/layouts/wide_layout'
|
37
|
+
require 'ruby_jard/layouts/narrow_layout'
|
28
38
|
require 'ruby_jard/layout'
|
29
|
-
require 'ruby_jard/
|
30
|
-
require 'ruby_jard/column'
|
31
|
-
require 'ruby_jard/span'
|
39
|
+
require 'ruby_jard/layout_calculator'
|
32
40
|
|
33
41
|
module RubyJard
|
34
42
|
##
|
@@ -59,7 +67,7 @@ module RubyJard
|
|
59
67
|
return if started?
|
60
68
|
|
61
69
|
RubyJard::Console.start_alternative_terminal(@output)
|
62
|
-
RubyJard::Console.
|
70
|
+
RubyJard::Console.clear_screen(@output)
|
63
71
|
|
64
72
|
def $stdout.write(string)
|
65
73
|
if !RubyJard::ScreenManager.updating? && RubyJard::ScreenManager.started?
|
@@ -86,9 +94,9 @@ module RubyJard
|
|
86
94
|
@started = false
|
87
95
|
|
88
96
|
RubyJard::Console.stop_alternative_terminal(@output)
|
89
|
-
RubyJard::Console.cooked!
|
90
|
-
RubyJard::Console.
|
91
|
-
RubyJard::Console.
|
97
|
+
RubyJard::Console.cooked!
|
98
|
+
RubyJard::Console.enable_echo!
|
99
|
+
RubyJard::Console.enable_cursor!
|
92
100
|
|
93
101
|
unless @output_storage.string.empty?
|
94
102
|
@output.puts ''
|
@@ -102,25 +110,35 @@ module RubyJard
|
|
102
110
|
start unless started?
|
103
111
|
@updating = true
|
104
112
|
|
105
|
-
RubyJard::Console.
|
106
|
-
clear_screen
|
113
|
+
RubyJard::Console.disable_cursor!
|
107
114
|
width, height = RubyJard::Console.screen_size(@output)
|
108
|
-
|
109
|
-
|
110
|
-
|
115
|
+
|
116
|
+
@layouts = calculate_layouts(width, height)
|
117
|
+
@screens = build_screens(@layouts)
|
118
|
+
draw_box(@screens)
|
119
|
+
draw_screens(@screens)
|
120
|
+
|
121
|
+
RubyJard::Console.move_to(@output, 0, total_screen_height(@layouts) + 1)
|
122
|
+
RubyJard::Console.clear_screen_to_end(@output)
|
123
|
+
|
111
124
|
draw_debug(width, height)
|
112
125
|
rescue StandardError => e
|
113
|
-
clear_screen
|
126
|
+
RubyJard::Console.clear_screen(@output)
|
114
127
|
draw_error(e, height)
|
115
128
|
ensure
|
116
129
|
# You don't want to mess up previous user TTY no matter happens
|
117
|
-
RubyJard::Console.cooked!
|
118
|
-
RubyJard::Console.
|
119
|
-
RubyJard::Console.
|
130
|
+
RubyJard::Console.cooked!
|
131
|
+
RubyJard::Console.enable_echo!
|
132
|
+
RubyJard::Console.enable_cursor!
|
120
133
|
@updating = false
|
121
134
|
end
|
122
135
|
|
136
|
+
def scroll; end
|
137
|
+
|
138
|
+
def click; end
|
139
|
+
|
123
140
|
def draw_error(exception, height = 0)
|
141
|
+
@output.print RubyJard::Decorators::ColorDecorator::CSI_RESET
|
124
142
|
@output.puts '--- Error ---'
|
125
143
|
@output.puts "Internal error from Jard. I'm sorry to mess up your debugging experience."
|
126
144
|
@output.puts 'It would be great if you can submit an issue in https://github.com/nguyenquangminh0711/ruby_jard/issues'
|
@@ -129,52 +147,62 @@ module RubyJard
|
|
129
147
|
if height == 0
|
130
148
|
@output.puts exception.backtrace
|
131
149
|
else
|
132
|
-
@output.puts exception.backtrace.first(
|
150
|
+
@output.puts exception.backtrace.first(10)
|
133
151
|
end
|
134
152
|
@output.puts '-------------'
|
135
153
|
end
|
136
154
|
|
137
|
-
|
138
155
|
private
|
139
156
|
|
140
157
|
def calculate_layouts(width, height)
|
141
158
|
layout = pick_layout(width, height)
|
142
|
-
RubyJard::
|
143
|
-
|
159
|
+
RubyJard::LayoutCalculator.calculate(
|
160
|
+
layout_template: layout,
|
144
161
|
width: width, height: height,
|
145
162
|
x: 0, y: 0
|
146
163
|
)
|
147
164
|
end
|
148
165
|
|
166
|
+
def build_screens(layouts)
|
167
|
+
layouts.map do |layout|
|
168
|
+
screen_class = fetch_screen(layout.template.screen)
|
169
|
+
screen = screen_class.new(
|
170
|
+
layout: layout,
|
171
|
+
color_scheme: pick_color_scheme
|
172
|
+
)
|
173
|
+
screen.build
|
174
|
+
render_screen(screen)
|
175
|
+
screen
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
149
179
|
def draw_box(screens)
|
150
180
|
RubyJard::BoxDrawer.new(
|
151
181
|
output: @output,
|
152
|
-
screens: screens
|
182
|
+
screens: screens,
|
183
|
+
color_scheme: pick_color_scheme
|
153
184
|
).draw
|
154
185
|
end
|
155
186
|
|
156
|
-
def draw_screens(
|
157
|
-
screens = screen_layouts.map do |screen_template, width, height, x, y|
|
158
|
-
screen = fetch_screen(screen_template.screen)
|
159
|
-
screen&.new(
|
160
|
-
screen_template: screen_template,
|
161
|
-
width: width, height: height,
|
162
|
-
x: x, y: y
|
163
|
-
)
|
164
|
-
end
|
165
|
-
draw_box(screens)
|
166
|
-
adjust_screen_contents(screens)
|
187
|
+
def draw_screens(screens)
|
167
188
|
screens.each do |screen|
|
168
|
-
|
189
|
+
RubyJard::ScreenDrawer.new(
|
190
|
+
output: @output,
|
191
|
+
screen: screen,
|
192
|
+
color_scheme: pick_color_scheme
|
193
|
+
).draw
|
169
194
|
end
|
170
195
|
end
|
171
196
|
|
172
|
-
def
|
173
|
-
|
174
|
-
|
197
|
+
def render_screen(screen)
|
198
|
+
RubyJard::ScreenRenderer.new(
|
199
|
+
screen: screen,
|
200
|
+
color_scheme: pick_color_scheme
|
201
|
+
).render
|
175
202
|
end
|
176
203
|
|
177
204
|
def draw_debug(_width, height)
|
205
|
+
@output.print RubyJard::Decorators::ColorDecorator::CSI_RESET
|
178
206
|
unless RubyJard.debug_info.empty?
|
179
207
|
@output.puts '--- Debug ---'
|
180
208
|
RubyJard.debug_info.first(height - 2).each do |line|
|
@@ -185,24 +213,14 @@ module RubyJard
|
|
185
213
|
RubyJard.clear_debug
|
186
214
|
end
|
187
215
|
|
188
|
-
def adjust_screen_contents(screens)
|
189
|
-
# After drawing the box, screen sizes should be updated to reflect content-only area
|
190
|
-
screens.each do |screen|
|
191
|
-
screen.width -= 2
|
192
|
-
screen.height -= 2
|
193
|
-
screen.x += 1
|
194
|
-
screen.y += 1
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
def clear_screen
|
199
|
-
RubyJard::Console.clear_screen(@output)
|
200
|
-
end
|
201
|
-
|
202
216
|
def fetch_screen(name)
|
203
217
|
RubyJard::Screens[name]
|
204
218
|
end
|
205
219
|
|
220
|
+
def total_screen_height(layouts)
|
221
|
+
layouts.map { |layout| layout.y + layout.height }.max
|
222
|
+
end
|
223
|
+
|
206
224
|
def pick_layout(width, height)
|
207
225
|
RubyJard::DEFAULT_LAYOUT_TEMPLATES.each do |template|
|
208
226
|
matched = true
|
@@ -218,5 +236,10 @@ module RubyJard
|
|
218
236
|
end
|
219
237
|
RubyJard::DEFAULT_LAYOUT_TEMPLATES.first
|
220
238
|
end
|
239
|
+
|
240
|
+
def pick_color_scheme
|
241
|
+
# TODO: Fallback to a default color scheme if not found
|
242
|
+
RubyJard::ColorSchemes[RubyJard::DEFAULT_COLOR_SCHEME].new
|
243
|
+
end
|
221
244
|
end
|
222
245
|
end
|