terminal-layout 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 80aa4a0e91137ff86176dcbadddd0b409704d3e1
4
- data.tar.gz: 5b959060b022e65741abdca373a33713055c34c8
3
+ metadata.gz: 3ed9ef7985d3a6245c22719a1d3ff99bfe281ed3
4
+ data.tar.gz: c18265ddc6660e6112dfed6248ea845d6419d02d
5
5
  SHA512:
6
- metadata.gz: f0cf393e5f454b12b9d3a4e205d00ceafcdc8c1dea90717a12747b67900e213668ff19d614d7d29b8a190d096693cd560ace32261b83b4921d045d81d9e9bfd0
7
- data.tar.gz: f3ffaf2df0f703a28055eeff39c92d82653ffb01bfeafca2b292331ad2bc97f41ff04fee59ba2f7817780e6657c96a8f5e6b3721cb87f931ce9f0462cb4719fb
6
+ metadata.gz: 63784d51ef8e26f6eb877564c975a6fd6ce9ca6deba51f8cc78275a9c35c3d6ff7a5e37bae75035c8c14421951a9f7d0c00fc969d0721620c12da6db6b027f6e
7
+ data.tar.gz: 8d85eecd9132e6596faa48d48c82e6e92992fb835c2411e96ca784f6daab09d66f5de9efd6aa597aa0335db786c0802e339c9fe55eb03c4eb16076fd6e5fce13
@@ -1 +1 @@
1
- 2.2.3
1
+ 2.3.1
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- terminal-layout (0.4.2)
4
+ terminal-layout (0.4.3)
5
5
  ansi_string (~> 0.1)
6
6
  highline (~> 1.7, >= 1.7.8)
7
7
  ruby-terminfo (~> 0.1.1)
@@ -12,43 +12,42 @@ GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
14
  ansi_string (0.1.0)
15
- byebug (5.0.0)
16
- columnize (= 0.9.0)
17
- coderay (1.1.0)
18
- columnize (0.9.0)
15
+ byebug (9.0.5)
16
+ coderay (1.1.1)
19
17
  diff-lcs (1.2.5)
20
18
  highline (1.7.8)
21
19
  method_source (0.8.2)
22
- pry (0.10.1)
20
+ pry (0.10.3)
23
21
  coderay (~> 1.1.0)
24
22
  method_source (~> 0.8.1)
25
23
  slop (~> 3.4)
26
- pry-byebug (3.2.0)
27
- byebug (~> 5.0)
24
+ pry-byebug (3.4.0)
25
+ byebug (~> 9.0)
28
26
  pry (~> 0.10)
29
- rake (10.4.2)
30
- rspec (3.3.0)
31
- rspec-core (~> 3.3.0)
32
- rspec-expectations (~> 3.3.0)
33
- rspec-mocks (~> 3.3.0)
34
- rspec-core (3.3.1)
35
- rspec-support (~> 3.3.0)
36
- rspec-expectations (3.3.0)
27
+ rake (10.5.0)
28
+ rspec (3.5.0)
29
+ rspec-core (~> 3.5.0)
30
+ rspec-expectations (~> 3.5.0)
31
+ rspec-mocks (~> 3.5.0)
32
+ rspec-core (3.5.1)
33
+ rspec-support (~> 3.5.0)
34
+ rspec-expectations (3.5.0)
37
35
  diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.3.0)
39
- rspec-mocks (3.3.1)
36
+ rspec-support (~> 3.5.0)
37
+ rspec-mocks (3.5.0)
40
38
  diff-lcs (>= 1.2.0, < 2.0)
41
- rspec-support (~> 3.3.0)
42
- rspec-support (3.3.0)
39
+ rspec-support (~> 3.5.0)
40
+ rspec-support (3.5.0)
43
41
  ruby-terminfo (0.1.1)
44
42
  ruby-termios (0.9.6)
45
43
  slop (3.6.0)
46
- term-ansicolor (1.3.0)
44
+ term-ansicolor (1.3.2)
47
45
  tins (~> 1.0)
48
- tins (1.3.5)
49
- treefell (0.3.0)
46
+ tins (1.10.2)
47
+ treefell (0.3.1)
50
48
  ansi_string (~> 0.1)
51
- term-ansicolor (~> 1.3)
49
+ term-ansicolor (~> 1.3.2)
50
+ tins (= 1.10.2)
52
51
 
53
52
  PLATFORMS
54
53
  ruby
@@ -62,4 +61,4 @@ DEPENDENCIES
62
61
  terminal-layout!
63
62
 
64
63
  BUNDLED WITH
65
- 1.11.2
64
+ 1.12.5
@@ -1,32 +1,13 @@
1
1
  require 'ostruct'
2
2
  require 'ansi_string'
3
3
  require 'treefell'
4
+ require 'terminal_layout/event_emitter'
5
+ require 'terminal_layout/renderer'
4
6
 
5
7
  module TerminalLayout
6
8
  Dimension = Struct.new(:width, :height)
7
9
  Position = Struct.new(:x, :y)
8
10
 
9
- module EventEmitter
10
- def _callbacks
11
- @_callbacks ||= Hash.new { |h, k| h[k] = [] }
12
- end
13
-
14
- def on(type, *args, &blk)
15
- _callbacks[type] << blk
16
- self
17
- end
18
-
19
- def unsubscribe
20
- _callbacks.clear
21
- end
22
-
23
- def emit(type, *args)
24
- _callbacks[type].each do |blk|
25
- blk.call(*args)
26
- end
27
- end
28
- end
29
-
30
11
  class RenderObject
31
12
  include EventEmitter
32
13
 
@@ -137,7 +118,6 @@ module TerminalLayout
137
118
  end
138
119
 
139
120
  def layout
140
- Treefell['render'].puts "layout #{self.inspect}"
141
121
  self.children = []
142
122
  @current_x = 0
143
123
  @current_y = 0
@@ -153,7 +133,6 @@ module TerminalLayout
153
133
  end
154
134
 
155
135
  children2crawl.each do |cbox|
156
- Treefell['render'].puts "layout crawling children #{cbox.inspect}"
157
136
  if cbox.display == :float
158
137
  next if cbox.width.to_i == 0
159
138
 
@@ -205,7 +184,6 @@ module TerminalLayout
205
184
  loop do
206
185
  partial_content = cbox.content[content_i...(content_i + available_width)]
207
186
  chars_needed = partial_content.length
208
- Treefell['render'].puts "laying out inline #{cbox.name} @current_x=#{@current_x} @current_y=#{@current_y} x=#{x} y=#{y}"
209
187
  self.children << render_object_for(
210
188
  cbox,
211
189
  content:partial_content,
@@ -250,7 +228,6 @@ module TerminalLayout
250
228
  child.box.computed[:x] += x
251
229
  child.box.computed[:y] += y
252
230
  end
253
- Treefell['render'].puts "laid out box=#{box.name} render-object=#{self.children}"
254
231
 
255
232
  self.children
256
233
  end
@@ -507,170 +484,10 @@ module TerminalLayout
507
484
  # spans multiple lines. We do not want to update the x/y position(s)
508
485
  # in this instance. We want to keep the original starting x/y.
509
486
  if style[:y] && style[:y] > 0
510
- Treefell['render'].puts "update_computed received a y > 0. Removing Y from update."
511
487
  style = style.dup.delete_if { |k,_| [:x, :y].include?(k) }
512
488
  end
513
489
  @computed.merge!(style)
514
490
  end
515
491
  end
516
492
 
517
- require 'terminfo'
518
- require 'termios'
519
- require 'highline/system_extensions'
520
- class TerminalRenderer
521
- include HighLine::SystemExtensions
522
- include EventEmitter
523
-
524
- attr_reader :term_info
525
-
526
- def initialize(output: $stdout)
527
- @output = output
528
- @term_info = TermInfo.new ENV["TERM"], @output
529
- @previously_printed_lines = []
530
- @x, @y = 0, 0
531
- end
532
-
533
- def render_cursor(input_box)
534
- Treefell['render'].puts "render cursor at box=#{input_box.inspect} computed=#{input_box.computed.inspect}"
535
-
536
- move_up_n_rows @y
537
- move_to_beginning_of_row
538
-
539
- position = input_box.position
540
-
541
- cursor_position = input_box.cursor_position
542
- cursor_x = cursor_position.x
543
- cursor_y = cursor_position.y
544
-
545
- relative_position_on_row = position
546
- initial_offset_x = input_box.computed[:x] + (input_box.computed[:y] * terminal_width)
547
- cursor_x = 0
548
- cursor_y = 0
549
-
550
- absolute_position_on_row = relative_position_on_row + initial_offset_x
551
- loop do
552
- if absolute_position_on_row >= terminal_width
553
- # reset offset
554
- initial_offset_x = 0
555
-
556
- absolute_position_on_row -= terminal_width
557
-
558
- # move down a line
559
- cursor_y += 1
560
- else
561
- # we fit on the current line
562
- cursor_x = absolute_position_on_row
563
- break
564
- end
565
- end
566
-
567
- if @y < cursor_y
568
- # moving backwards
569
- move_up_n_rows(@y - cursor_y)
570
- elsif @y > cursor_y
571
- # moving forwards
572
- move_down_n_rows(cursor_y - @y)
573
- end
574
-
575
- move_down_n_rows cursor_y
576
- move_to_beginning_of_row
577
- move_right_n_characters cursor_x
578
-
579
- @x = cursor_x
580
- @y = cursor_y
581
-
582
- Treefell['render'].puts "rendering cursor at x=#{@x} y=#{@y}"
583
-
584
- if input_box.style[:cursor] == 'none'
585
- @output.print @term_info.control_string "civis"
586
- else
587
- @output.print @term_info.control_string "cnorm"
588
- end
589
- end
590
-
591
- def render(object, reset: false)
592
- dumb_render(object, reset: reset)
593
- end
594
-
595
- def find_top_of_tree(object)
596
- loop do
597
- break unless object.parent
598
- object = object.parent
599
- end
600
- object
601
- end
602
-
603
- def dumb_render(object, reset: false)
604
- if reset
605
- @y = 0
606
- @previously_printed_lines.clear
607
- end
608
- @output.print @term_info.control_string "civis"
609
- move_up_n_rows @y
610
- move_to_beginning_of_row
611
-
612
- object = find_top_of_tree(object)
613
-
614
- object_width = object.width
615
-
616
- rendered_content = object.render
617
- printable_content = rendered_content.sub(/\s*\Z/m, '')
618
-
619
- printable_lines = printable_content.split(/\n/).each_with_object([]) do |line, results|
620
- if line.empty?
621
- results << line
622
- else
623
- results.concat line.scan(/.{1,#{terminal_width}}/)
624
- end
625
- end
626
-
627
- printable_lines.zip(@previously_printed_lines) do |new_line, previous_line|
628
- if new_line != previous_line
629
- # be sure to reset the terminal at the outset of every line
630
- # because we don't know what state the previous line ended in
631
- line2print = "#{new_line}\e[0m"
632
- term_info.control "el"
633
- move_to_beginning_of_row
634
- term_info.control "el"
635
- Treefell['render'].puts "printing line=#{line2print.inspect}"
636
- @output.puts line2print
637
- else
638
- move_down_n_rows 1
639
- end
640
- end
641
- move_to_beginning_of_row
642
- clear_screen_down
643
-
644
- # calculate lines drawn so we know where we are
645
- lines_drawn = (printable_content.length / object_width.to_f).ceil
646
- @y = lines_drawn
647
-
648
- input_box = object.box.find_child_of_type(InputBox) do |box|
649
- box.focused?
650
- end
651
- render_cursor(input_box)
652
-
653
- @previously_printed_lines = printable_lines
654
- end
655
-
656
- def clear_to_beginning_of_line ; term_info.control "el1" ; end
657
- def clear_screen ; term_info.control "clear" ; end
658
- def clear_screen_down ; term_info.control "ed" ; end
659
- def move_to_beginning_of_row ; move_to_column 0 ; end
660
- def move_left ; move_left_n_characters 1 ; end
661
- def move_left_n_characters(n) ; n.times { term_info.control "cub1" } ; end
662
- def move_right_n_characters(n) ; n.times { term_info.control "cuf1" } ; end
663
- def move_to_column_and_row(column, row) ; term_info.control "cup", column, row ; end
664
- def move_to_column(n) ; term_info.control "hpa", n ; end
665
- def move_up_n_rows(n) ; n.times { term_info.control "cuu1" } ; end
666
- def move_down_n_rows(n) ; n.times { term_info.control "cud1" } ; end
667
-
668
- def terminal_width
669
- terminal_size[0]
670
- end
671
-
672
- def terminal_height
673
- terminal_size[1]
674
- end
675
- end
676
493
  end
@@ -0,0 +1,22 @@
1
+ module TerminalLayout
2
+ module EventEmitter
3
+ def _callbacks
4
+ @_callbacks ||= Hash.new { |h, k| h[k] = [] }
5
+ end
6
+
7
+ def on(type, *args, &blk)
8
+ _callbacks[type] << blk
9
+ self
10
+ end
11
+
12
+ def unsubscribe
13
+ _callbacks.clear
14
+ end
15
+
16
+ def emit(type, *args)
17
+ _callbacks[type].each do |blk|
18
+ blk.call(*args)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,178 @@
1
+ require 'terminfo'
2
+ require 'termios'
3
+ require 'highline/system_extensions'
4
+
5
+ module TerminalLayout
6
+ class Renderer
7
+ include HighLine::SystemExtensions
8
+ include EventEmitter
9
+
10
+ attr_reader :term_info
11
+
12
+ def initialize(output: $stdout)
13
+ @output = output
14
+ @term_info = TermInfo.new ENV["TERM"], @output
15
+ @previously_printed_lines = []
16
+ @x, @y = 0, 0
17
+ end
18
+
19
+ def render_cursor(input_box)
20
+ Treefell['render'].puts %|\nCURSOR RENDER: #{self.class}##{__callee__} caller=#{caller[0..5].join("\n")}}|
21
+ move_up_n_rows @y
22
+ move_to_beginning_of_row
23
+
24
+ position = input_box.position
25
+
26
+ cursor_position = input_box.cursor_position
27
+ cursor_x = cursor_position.x
28
+ cursor_y = cursor_position.y
29
+
30
+ relative_position_on_row = position
31
+ initial_offset_x = input_box.computed[:x] + (input_box.computed[:y] * terminal_width)
32
+ cursor_x = 0
33
+ cursor_y = 0
34
+
35
+ absolute_position_on_row = relative_position_on_row + initial_offset_x
36
+ loop do
37
+ if absolute_position_on_row >= terminal_width
38
+ # reset offset
39
+ initial_offset_x = 0
40
+
41
+ absolute_position_on_row -= terminal_width
42
+
43
+ # move down a line
44
+ cursor_y += 1
45
+ else
46
+ # we fit on the current line
47
+ cursor_x = absolute_position_on_row
48
+ break
49
+ end
50
+ end
51
+
52
+ if @y < cursor_y
53
+ # moving backwards
54
+ move_up_n_rows(@y - cursor_y)
55
+ elsif @y > cursor_y
56
+ # moving forwards
57
+ move_down_n_rows(cursor_y - @y)
58
+ end
59
+
60
+ move_down_n_rows cursor_y
61
+ move_to_beginning_of_row
62
+ move_right_n_characters cursor_x
63
+
64
+ @x = cursor_x
65
+ @y = cursor_y
66
+
67
+ if input_box.style[:cursor] == 'none'
68
+ @output.print @term_info.control_string "civis"
69
+ else
70
+ @output.print @term_info.control_string "cnorm"
71
+ end
72
+ end
73
+
74
+ def render(object, reset: false)
75
+ dumb_render(object, reset: reset)
76
+ end
77
+
78
+ def find_top_of_tree(object)
79
+ loop do
80
+ break unless object.parent
81
+ object = object.parent
82
+ end
83
+ object
84
+ end
85
+
86
+ def fullzip(a, b, &blk)
87
+ results = if a.length >= b.length
88
+ a.zip(b)
89
+ else
90
+ b.zip(a).map(&:reverse)
91
+ end
92
+ if block_given?
93
+ results.each { |*args| blk.call(*args) }
94
+ else
95
+ results
96
+ end
97
+ end
98
+
99
+ def dumb_render(object, reset: false)
100
+ Treefell['render'].puts %|\nDUMB RENDER: #{self.class}##{__callee__} reset=#{reset} caller=#{caller[0..5].join("\n")}}|
101
+ if reset
102
+ @y = 0
103
+ @previously_printed_lines.clear
104
+ else
105
+ move_up_n_rows @y
106
+ move_to_beginning_of_row
107
+ @y = 0
108
+ end
109
+ @output.print @term_info.control_string "civis"
110
+
111
+ object = find_top_of_tree(object)
112
+
113
+ object_width = object.width
114
+
115
+ rendered_content = object.render
116
+ printable_content = rendered_content.sub(/\s*\Z/m, '')
117
+ printable_lines = printable_content.split(/\n/).each_with_object([]) do |line, results|
118
+ if line.empty?
119
+ results << line
120
+ else
121
+ results.concat line.scan(/.{1,#{terminal_width}}/)
122
+ end
123
+ end
124
+
125
+ i = 0
126
+ fullzip(printable_lines, @previously_printed_lines) do |new_line, previous_line|
127
+ i += 1
128
+ if new_line && new_line != previous_line
129
+ # be sure to reset the terminal at the outset of every line
130
+ # because we don't know what state the previous line ended in
131
+ line2print = "#{new_line}\e[0m"
132
+ term_info.control "el"
133
+ move_to_beginning_of_row
134
+ term_info.control "el"
135
+ @output.puts line2print
136
+ move_to_beginning_of_row
137
+ elsif i <= printable_lines.length
138
+ move_down_n_rows 1
139
+ end
140
+ end
141
+
142
+ move_to_beginning_of_row
143
+ clear_screen_down
144
+
145
+ # calculate lines drawn so we know where we are
146
+ lines_drawn = (printable_content.length / object_width.to_f).ceil
147
+ @y = lines_drawn
148
+
149
+ input_box = object.box.find_child_of_type(InputBox) do |box|
150
+ box.focused?
151
+ end
152
+ render_cursor(input_box)
153
+
154
+ @previously_printed_lines = printable_lines
155
+ end
156
+
157
+ def clear_to_beginning_of_line ; term_info.control "el1" ; end
158
+ def clear_screen ; term_info.control "clear" ; end
159
+ def clear_screen_down ; term_info.control "ed" ; end
160
+ def move_to_beginning_of_row ; move_to_column 0 ; end
161
+ def move_left ; move_left_n_characters 1 ; end
162
+ def move_left_n_characters(n) ; n.times { term_info.control "cub1" } ; end
163
+ def move_right_n_characters(n) ; n.times { term_info.control "cuf1" } ; end
164
+ def move_to_column_and_row(column, row) ; term_info.control "cup", column, row ; end
165
+ def move_to_column(n) ; term_info.control "hpa", n ; end
166
+ def move_up_n_rows(n) ; n.times { term_info.control "cuu1" } ; end
167
+ def move_down_n_rows(n) ; n.times { term_info.control "cud1" } ; end
168
+
169
+ def terminal_width
170
+ terminal_size[0]
171
+ end
172
+
173
+ def terminal_height
174
+ terminal_size[1]
175
+ end
176
+ end
177
+
178
+ end
@@ -1,3 +1,3 @@
1
1
  module TerminalLayout
2
- VERSION = "0.4.2"
2
+ VERSION = "0.4.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terminal-layout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zach Dennis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-01 00:00:00.000000000 Z
11
+ date: 2016-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ansi_string
@@ -145,6 +145,8 @@ files:
145
145
  - block-flow.rb
146
146
  - lib/tasks/gem.rake
147
147
  - lib/terminal_layout.rb
148
+ - lib/terminal_layout/event_emitter.rb
149
+ - lib/terminal_layout/renderer.rb
148
150
  - lib/terminal_layout/version.rb
149
151
  - spec/spec_helper.rb
150
152
  - spec/terminal_layout_spec.rb
@@ -170,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
170
172
  version: '0'
171
173
  requirements: []
172
174
  rubyforge_project:
173
- rubygems_version: 2.4.5.1
175
+ rubygems_version: 2.5.1
174
176
  signing_key:
175
177
  specification_version: 4
176
178
  summary: A terminal layout manager