vedeu 0.1.15 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +2 -0
  3. data/README.md +116 -98
  4. data/lib/vedeu.rb +24 -11
  5. data/lib/vedeu/api/api.rb +174 -33
  6. data/lib/vedeu/api/composition.rb +2 -13
  7. data/lib/vedeu/api/helpers.rb +41 -0
  8. data/lib/vedeu/api/interface.rb +147 -34
  9. data/lib/vedeu/api/line.rb +47 -0
  10. data/lib/vedeu/api/stream.rb +41 -0
  11. data/lib/vedeu/application.rb +9 -2
  12. data/lib/vedeu/configuration.rb +66 -8
  13. data/lib/vedeu/launcher.rb +11 -0
  14. data/lib/vedeu/models/attributes/background.rb +29 -0
  15. data/lib/vedeu/models/attributes/coercions.rb +30 -0
  16. data/lib/vedeu/models/attributes/colour_translator.rb +106 -16
  17. data/lib/vedeu/models/attributes/foreground.rb +29 -0
  18. data/lib/vedeu/models/attributes/presentation.rb +15 -0
  19. data/lib/vedeu/models/colour.rb +12 -7
  20. data/lib/vedeu/models/composition.rb +23 -5
  21. data/lib/vedeu/models/geometry.rb +101 -16
  22. data/lib/vedeu/models/interface.rb +36 -28
  23. data/lib/vedeu/models/line.rb +16 -14
  24. data/lib/vedeu/models/stream.rb +17 -25
  25. data/lib/vedeu/models/style.rb +29 -0
  26. data/lib/vedeu/support/buffer.rb +36 -21
  27. data/lib/vedeu/support/buffers.rb +88 -0
  28. data/lib/vedeu/{output → support}/clear.rb +9 -2
  29. data/lib/vedeu/support/esc.rb +16 -2
  30. data/lib/vedeu/support/event.rb +104 -0
  31. data/lib/vedeu/support/events.rb +61 -0
  32. data/lib/vedeu/support/focus.rb +69 -0
  33. data/lib/vedeu/{api → support}/grid.rb +29 -25
  34. data/lib/vedeu/support/groups.rb +51 -0
  35. data/lib/vedeu/support/input.rb +5 -0
  36. data/lib/vedeu/support/log.rb +105 -0
  37. data/lib/vedeu/support/menu.rb +19 -0
  38. data/lib/vedeu/support/position.rb +7 -0
  39. data/lib/vedeu/{output → support}/render.rb +12 -6
  40. data/lib/vedeu/support/terminal.rb +21 -0
  41. data/lib/vedeu/support/trace.rb +54 -0
  42. data/lib/vedeu/{output → support}/view.rb +15 -10
  43. data/test/lib/vedeu/api/api_test.rb +55 -29
  44. data/test/lib/vedeu/api/interface_test.rb +3 -49
  45. data/test/lib/vedeu/api/line_test.rb +71 -0
  46. data/test/lib/vedeu/api/stream_test.rb +25 -0
  47. data/test/lib/vedeu/models/attributes/background_test.rb +83 -0
  48. data/test/lib/vedeu/models/attributes/coercer_test.rb +52 -0
  49. data/test/lib/vedeu/models/attributes/foreground_test.rb +83 -0
  50. data/test/lib/vedeu/models/attributes/presentation_test.rb +30 -0
  51. data/test/lib/vedeu/models/composition_test.rb +6 -6
  52. data/test/lib/vedeu/models/geometry_test.rb +34 -0
  53. data/test/lib/vedeu/models/interface_test.rb +0 -12
  54. data/test/lib/vedeu/models/line_test.rb +1 -13
  55. data/test/lib/vedeu/models/stream_test.rb +4 -50
  56. data/test/lib/vedeu/models/style_test.rb +39 -0
  57. data/test/lib/vedeu/support/buffer_test.rb +7 -3
  58. data/test/lib/vedeu/support/buffers_test.rb +15 -0
  59. data/test/lib/vedeu/{output → support}/clear_test.rb +8 -1
  60. data/test/lib/vedeu/support/esc_test.rb +2 -2
  61. data/test/lib/vedeu/support/event_test.rb +41 -0
  62. data/test/lib/vedeu/support/events_test.rb +70 -0
  63. data/test/lib/vedeu/support/focus_test.rb +114 -0
  64. data/test/lib/vedeu/support/grid_test.rb +31 -0
  65. data/test/lib/vedeu/support/groups_test.rb +65 -0
  66. data/test/lib/vedeu/{output → support}/render_test.rb +8 -1
  67. data/test/lib/vedeu/{output → support}/view_test.rb +1 -1
  68. data/test/test_helper.rb +3 -1
  69. data/vedeu.gemspec +3 -2
  70. metadata +67 -31
  71. data/lib/vedeu/api/events.rb +0 -46
  72. data/lib/vedeu/api/log.rb +0 -84
  73. data/lib/vedeu/models/attributes/attributes.rb +0 -25
  74. data/lib/vedeu/models/store.rb +0 -29
  75. data/lib/vedeu/output/buffers.rb +0 -65
  76. data/test/lib/vedeu/api/events_test.rb +0 -36
  77. data/test/lib/vedeu/api/grid_test.rb +0 -33
  78. data/test/lib/vedeu/models/attributes/attributes_test.rb +0 -39
  79. data/test/lib/vedeu/models/attributes/colour_translator_test.rb +0 -78
  80. data/test/lib/vedeu/models/store_test.rb +0 -57
  81. data/test/lib/vedeu/output/buffers_test.rb +0 -35
@@ -1,15 +1,20 @@
1
1
  module Vedeu
2
- ModeSwitch = Class.new(StandardError)
3
-
4
2
  class Application
3
+
4
+ # :nocov:
5
+ # @param options [Hash]
6
+ # @return []
5
7
  def self.start(options = {})
6
8
  new(options).start
7
9
  end
8
10
 
11
+ # @param options [Hash]
12
+ # @return [Application]
9
13
  def initialize(options = {})
10
14
  @options = options
11
15
  end
12
16
 
17
+ # @return []
13
18
  def start
14
19
  Terminal.open(mode) do
15
20
  Terminal.set_cursor_mode
@@ -78,5 +83,7 @@ module Vedeu
78
83
  mode: :raw
79
84
  }
80
85
  end
86
+ # :nocov:
87
+
81
88
  end
82
89
  end
@@ -1,41 +1,99 @@
1
1
  module Vedeu
2
2
  class Configuration
3
+
4
+ # @param args [Array]
5
+ # @return [Hash]
3
6
  def self.configure(args = [])
4
7
  new(args).configure
5
8
  end
6
9
 
10
+ # @return [Hash]
11
+ def self.options
12
+ new.options
13
+ end
14
+
15
+ # @param args [Array]
16
+ # @return [Configuration]
7
17
  def initialize(args = [])
8
- @args = args
9
- @options = {}
18
+ @_options = {}
19
+ @args = args
10
20
  end
11
21
 
22
+ # @return [Hash]
12
23
  def configure
13
24
  parser = OptionParser.new do |opts|
14
25
  opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
15
26
 
16
27
  opts.on('-1', '--run-once', 'Run application once.') do
17
- options[:interactive] = false
28
+ _options[:interactive] = false
18
29
  end
19
30
 
20
31
  opts.on('-c', '--cooked', 'Run application in cooked mode.') do
21
- options[:mode] = :cooked
32
+ _options[:mode] = :cooked
22
33
  end
23
34
 
24
35
  opts.on('-r', '--raw', 'Run application in raw mode (default).') do
25
- options[:mode] = :raw
36
+ _options[:mode] = :raw
26
37
  end
27
38
 
28
39
  opts.on('-d', '--debug', 'Run application with debugging on.') do
29
- options[:debug] = true
40
+ _options[:debug] = true
41
+ end
42
+
43
+ opts.on('-C',
44
+ '--colour-mode',
45
+ 'Run application in either `16` or `256` colour mode.') do |mode|
46
+ if ['16', '256'].include?(mode)
47
+ _options[:colour_mode] = mode
48
+
49
+ else
50
+ exit
51
+
52
+ end
30
53
  end
31
54
  end
32
55
  parser.parse!(args)
33
56
 
34
- options
57
+ _options
58
+ end
59
+
60
+ # @return [Hash]
61
+ def options
62
+ @options ||= defaults.merge!(@_options)
35
63
  end
36
64
 
37
65
  private
38
66
 
39
- attr_accessor :args, :options
67
+ attr_accessor :args, :_options
68
+
69
+ def defaults
70
+ {
71
+ colour_mode: detect_colour_mode,
72
+ debug: false,
73
+ interactive: true,
74
+ mode: :raw
75
+ }
76
+ end
77
+
78
+ def detect_colour_mode
79
+ if ENV['VEDEUTERM']
80
+ case ENV['VEDEUTERM']
81
+ when /-256color$/ then 256
82
+ when /-truecolor$/ then 16777216
83
+ else
84
+ 256
85
+ end
86
+
87
+ else
88
+ case ENV['TERM']
89
+ when /-256color$/, 'xterm' then 256
90
+ when /-color$/, 'rxvt' then 16
91
+ else
92
+ 256
93
+ end
94
+
95
+ end
96
+ end
97
+
40
98
  end
41
99
  end
@@ -1,5 +1,13 @@
1
1
  module Vedeu
2
2
  class Launcher
3
+
4
+ # :nocov:
5
+ # @param argv [Array]
6
+ # @param stdin []
7
+ # @param stdout []
8
+ # @param stderr []
9
+ # @param kernel []
10
+ # @return [Launcher]
3
11
  def initialize(argv, stdin = STDIN,
4
12
  stdout = STDOUT,
5
13
  stderr = STDERR,
@@ -12,6 +20,7 @@ module Vedeu
12
20
  @exit_code = 1
13
21
  end
14
22
 
23
+ # @return []
15
24
  def execute!
16
25
  $stdin, $stdout, $stderr = @stdin, @stdout, @stderr
17
26
 
@@ -35,5 +44,7 @@ module Vedeu
35
44
  def configuration
36
45
  Configuration.configure(argv)
37
46
  end
47
+ # :nocov:
48
+
38
49
  end
39
50
  end
@@ -0,0 +1,29 @@
1
+ module Vedeu
2
+ class Background < ColourTranslator
3
+
4
+ private
5
+
6
+ def named
7
+ ["\e[", background_codes[colour], "m"].join
8
+ end
9
+
10
+ def numbered
11
+ ["\e[48;5;", css_to_numbered, "m"].join
12
+ end
13
+
14
+ def rgb
15
+ if Terminal.colour_mode == 16777216
16
+ sprintf("\e[48;2;%s;%s;%sm", *css_to_rgb)
17
+
18
+ else
19
+ numbered
20
+
21
+ end
22
+ end
23
+
24
+ def background_codes
25
+ codes.inject({}){ |h, (k, v)| h.merge(k => v + 10) }
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ module Vedeu
2
+ module Coercions
3
+ module ClassMethods
4
+
5
+ # Produces new objects of the correct class from attributes hashes,
6
+ # ignores objects that have already been coerced.
7
+ #
8
+ # @param values [Array|Hash]
9
+ # @return [Array]
10
+ def coercer(values)
11
+ return [] if values.nil? || values.empty?
12
+
13
+ [values].flatten.map do |value|
14
+ if value.is_a?(self)
15
+ value
16
+
17
+ else
18
+ self.new(value)
19
+
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ def self.included(receiver)
26
+ receiver.extend(ClassMethods)
27
+ end
28
+
29
+ end
30
+ end
@@ -1,35 +1,125 @@
1
1
  module Vedeu
2
2
  class ColourTranslator
3
- def initialize(html_colour = '')
4
- @html_colour = html_colour
5
- end
6
3
 
7
- def background
8
- return '' unless valid?
4
+ # @param colour [String]
5
+ # @return [String]
6
+ def self.escape_sequence(colour = '')
7
+ new(colour).escape_sequence
8
+ end
9
9
 
10
- sprintf("\e[48;2;%s;%s;%sm", *translate)
10
+ # @param colour [String]
11
+ # @return [ColourTranslator]
12
+ def initialize(colour = '')
13
+ @colour = colour
11
14
  end
12
15
 
13
- def foreground
14
- return '' unless valid?
16
+ # @return [String]
17
+ def escape_sequence
18
+ if no_colour?
19
+ ''
20
+
21
+ elsif named?
22
+ named
23
+
24
+ elsif numbered?
25
+ numbered
26
+
27
+ elsif rgb?
28
+ rgb
15
29
 
16
- sprintf("\e[38;2;%s;%s;%sm", *translate)
30
+ else
31
+ ''
32
+
33
+ end
17
34
  end
18
35
 
19
36
  private
20
37
 
21
- attr_reader :html_colour
38
+ attr_reader :colour
39
+
40
+ def no_colour?
41
+ colour.nil? || colour.to_s.empty?
42
+ end
43
+
44
+ def named?
45
+ colour.is_a?(Symbol) && valid_name?
46
+ end
22
47
 
23
- def translate
48
+ def named
49
+ fail NotImplemented, 'Subclasses implement this.'
50
+ end
51
+
52
+ def valid_name?
53
+ codes.keys.include?(colour)
54
+ end
55
+
56
+ def numbered?
57
+ colour.is_a?(Fixnum) && valid_range?
58
+ end
59
+
60
+ def numbered
61
+ fail NotImplemented, 'Subclasses implement this.'
62
+ end
63
+
64
+ def valid_range?
65
+ colour >= 0 && colour <= 255
66
+ end
67
+
68
+ def rgb?
69
+ colour.is_a?(String) && valid_rgb?
70
+ end
71
+
72
+ def rgb
73
+ fail NotImplemented, 'Subclasses implement this.'
74
+ end
75
+
76
+ def valid_rgb?
77
+ colour =~ /^#([A-Fa-f0-9]{6})$/
78
+ end
79
+
80
+ def css_to_rgb
24
81
  [
25
- html_colour[1..2].to_i(16),
26
- html_colour[3..4].to_i(16),
27
- html_colour[5..6].to_i(16)
82
+ colour[1..2].to_i(16),
83
+ colour[3..4].to_i(16),
84
+ colour[5..6].to_i(16)
28
85
  ]
29
86
  end
30
87
 
31
- def valid?
32
- html_colour.is_a?(String) && html_colour =~ /^#([A-Fa-f0-9]{6})$/
88
+ def css_to_numbered
89
+ if rgb?
90
+ [16, red, green, blue].inject(:+)
91
+
92
+ elsif numbered?
93
+ colour
94
+
95
+ end
96
+ end
97
+
98
+ def red
99
+ (css_to_rgb[0] / 51) * 36
33
100
  end
101
+
102
+ def green
103
+ (css_to_rgb[1] / 51) * 6
104
+ end
105
+
106
+ def blue
107
+ (css_to_rgb[2] / 51) * 1
108
+ end
109
+
110
+ def codes
111
+ {
112
+ black: 30,
113
+ red: 31,
114
+ green: 32,
115
+ yellow: 33,
116
+ blue: 34,
117
+ magenta: 35,
118
+ cyan: 36,
119
+ white: 37,
120
+ default: 39,
121
+ }
122
+ end
123
+
34
124
  end
35
125
  end
@@ -0,0 +1,29 @@
1
+ module Vedeu
2
+ class Foreground < ColourTranslator
3
+
4
+ private
5
+
6
+ def named
7
+ ["\e[", foreground_codes[colour], "m"].join
8
+ end
9
+
10
+ def numbered
11
+ ["\e[38;5;", css_to_numbered, "m"].join
12
+ end
13
+
14
+ def rgb
15
+ if Terminal.colour_mode == 16777216
16
+ sprintf("\e[38;2;%s;%s;%sm", *css_to_rgb)
17
+
18
+ else
19
+ numbered
20
+
21
+ end
22
+ end
23
+
24
+ def foreground_codes
25
+ codes
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ module Vedeu
2
+ module Presentation
3
+
4
+ # @return [Colour]
5
+ def colour
6
+ @colour ||= Colour.new(attributes[:colour])
7
+ end
8
+
9
+ # @return [Style]
10
+ def style
11
+ @style ||= Style.new(attributes[:style])
12
+ end
13
+
14
+ end
15
+ end
@@ -1,21 +1,25 @@
1
1
  module Vedeu
2
2
  class Colour
3
- def initialize(attributes = {})
4
- @attributes = attributes
5
- end
6
3
 
7
- def attributes
8
- defaults.merge!(@attributes)
4
+ attr_reader :attributes
5
+
6
+ # @param attributes [Hash]
7
+ # @return [Colour]
8
+ def initialize(attributes = {})
9
+ @attributes = defaults.merge!(attributes)
9
10
  end
10
11
 
12
+ # @return [String]
11
13
  def foreground
12
- @foreground ||= ColourTranslator.new(attributes[:foreground]).foreground
14
+ @foreground ||= Foreground.escape_sequence(attributes[:foreground])
13
15
  end
14
16
 
17
+ # @return [String]
15
18
  def background
16
- @background ||= ColourTranslator.new(attributes[:background]).background
19
+ @background ||= Background.escape_sequence(attributes[:background])
17
20
  end
18
21
 
22
+ # @return [String]
19
23
  def to_s
20
24
  foreground + background
21
25
  end
@@ -28,5 +32,6 @@ module Vedeu
28
32
  background: ''
29
33
  }
30
34
  end
35
+
31
36
  end
32
37
  end