vedeu 0.1.18 → 0.1.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +5 -0
  3. data/Dockerfile +40 -0
  4. data/README.md +7 -30
  5. data/docs/api.md +79 -0
  6. data/docs/events.md +121 -0
  7. data/lib/vedeu.rb +61 -18
  8. data/lib/vedeu/api/api.rb +73 -53
  9. data/lib/vedeu/api/composition.rb +4 -1
  10. data/lib/vedeu/api/defined.rb +35 -0
  11. data/lib/vedeu/api/helpers.rb +20 -15
  12. data/lib/vedeu/api/interface.rb +17 -12
  13. data/lib/vedeu/api/line.rb +20 -12
  14. data/lib/vedeu/api/stream.rb +3 -0
  15. data/lib/vedeu/application.rb +34 -1
  16. data/lib/vedeu/configuration.rb +15 -3
  17. data/lib/vedeu/input/input.rb +77 -0
  18. data/lib/vedeu/launcher.rb +7 -0
  19. data/lib/vedeu/models/attributes/background.rb +15 -2
  20. data/lib/vedeu/models/attributes/coercions.rb +18 -3
  21. data/lib/vedeu/models/attributes/colour_translator.rb +23 -17
  22. data/lib/vedeu/models/attributes/foreground.rb +10 -2
  23. data/lib/vedeu/models/attributes/presentation.rb +62 -0
  24. data/lib/vedeu/models/colour.rb +7 -3
  25. data/lib/vedeu/models/composition.rb +17 -19
  26. data/lib/vedeu/models/geometry.rb +13 -5
  27. data/lib/vedeu/models/interface.rb +35 -19
  28. data/lib/vedeu/models/line.rb +24 -8
  29. data/lib/vedeu/models/stream.rb +13 -7
  30. data/lib/vedeu/models/style.rb +17 -7
  31. data/lib/vedeu/{support → output}/clear.rb +14 -0
  32. data/lib/vedeu/output/compositor.rb +77 -0
  33. data/lib/vedeu/output/refresh.rb +129 -0
  34. data/lib/vedeu/{support → output}/render.rb +49 -13
  35. data/lib/vedeu/{support → output}/view.rb +15 -8
  36. data/lib/vedeu/repositories/buffers.rb +181 -0
  37. data/lib/vedeu/{support → repositories}/events.rb +16 -6
  38. data/lib/vedeu/repositories/focus.rb +109 -0
  39. data/lib/vedeu/repositories/groups.rb +76 -0
  40. data/lib/vedeu/repositories/interfaces.rb +74 -0
  41. data/lib/vedeu/support/common.rb +20 -0
  42. data/lib/vedeu/support/cursor.rb +77 -0
  43. data/lib/vedeu/support/esc.rb +181 -46
  44. data/lib/vedeu/support/event.rb +22 -4
  45. data/lib/vedeu/support/grid.rb +10 -3
  46. data/lib/vedeu/support/log.rb +14 -1
  47. data/lib/vedeu/support/menu.rb +51 -12
  48. data/lib/vedeu/support/position.rb +9 -0
  49. data/lib/vedeu/support/terminal.rb +49 -15
  50. data/lib/vedeu/support/trace.rb +11 -4
  51. data/test/integration/defining_interfaces_test.rb +27 -0
  52. data/test/integration/views/basic_view_test.rb +767 -0
  53. data/test/lib/vedeu/api/api_test.rb +32 -37
  54. data/test/lib/vedeu/api/composition_test.rb +23 -61
  55. data/test/lib/vedeu/api/defined_test.rb +49 -0
  56. data/test/lib/vedeu/api/helpers_test.rb +91 -0
  57. data/test/lib/vedeu/api/interface_test.rb +136 -688
  58. data/test/lib/vedeu/api/line_test.rb +28 -32
  59. data/test/lib/vedeu/application_test.rb +6 -0
  60. data/test/lib/vedeu/configuration_test.rb +8 -4
  61. data/test/lib/vedeu/{support → input}/input_test.rb +9 -0
  62. data/test/lib/vedeu/launcher_test.rb +6 -0
  63. data/test/lib/vedeu/models/attributes/{coercer_test.rb → coercions_test.rb} +11 -10
  64. data/test/lib/vedeu/models/attributes/colour_translator_test.rb +13 -0
  65. data/test/lib/vedeu/models/attributes/presentation_test.rb +30 -0
  66. data/test/lib/vedeu/models/colour_test.rb +8 -0
  67. data/test/lib/vedeu/models/composition_test.rb +208 -200
  68. data/test/lib/vedeu/models/geometry_test.rb +39 -0
  69. data/test/lib/vedeu/models/interface_test.rb +11 -1
  70. data/test/lib/vedeu/models/line_test.rb +8 -1
  71. data/test/lib/vedeu/models/stream_test.rb +35 -0
  72. data/test/lib/vedeu/models/style_test.rb +8 -0
  73. data/test/lib/vedeu/{support → output}/clear_test.rb +1 -1
  74. data/test/lib/vedeu/output/compositor_test.rb +64 -0
  75. data/test/lib/vedeu/output/refresh_test.rb +48 -0
  76. data/test/lib/vedeu/{support → output}/render_test.rb +36 -0
  77. data/test/lib/vedeu/{support → output}/view_test.rb +0 -0
  78. data/test/lib/vedeu/repositories/buffers_test.rb +48 -0
  79. data/test/lib/vedeu/{support → repositories}/events_test.rb +0 -0
  80. data/test/lib/vedeu/repositories/focus_test.rb +74 -0
  81. data/test/lib/vedeu/repositories/groups_test.rb +66 -0
  82. data/test/lib/vedeu/repositories/interfaces_test.rb +6 -0
  83. data/test/lib/vedeu/support/common_test.rb +6 -0
  84. data/test/lib/vedeu/support/cursor_test.rb +79 -0
  85. data/test/lib/vedeu/support/log_test.rb +6 -0
  86. data/test/lib/vedeu/support/terminal_test.rb +6 -28
  87. data/test/lib/vedeu/support/trace_test.rb +6 -0
  88. data/test/test_helper.rb +37 -0
  89. data/vedeu.gemspec +1 -1
  90. metadata +65 -33
  91. data/bin/log +0 -13
  92. data/lib/vedeu/support/buffer.rb +0 -69
  93. data/lib/vedeu/support/buffers.rb +0 -106
  94. data/lib/vedeu/support/focus.rb +0 -83
  95. data/lib/vedeu/support/groups.rb +0 -61
  96. data/lib/vedeu/support/input.rb +0 -67
  97. data/test/lib/vedeu/support/buffer_test.rb +0 -83
  98. data/test/lib/vedeu/support/buffers_test.rb +0 -15
  99. data/test/lib/vedeu/support/focus_test.rb +0 -114
  100. data/test/lib/vedeu/support/groups_test.rb +0 -65
@@ -0,0 +1,77 @@
1
+ module Vedeu
2
+
3
+ # Captures input from the user via {Vedeu::Terminal#input} and translates
4
+ # special characters into symbols.
5
+ #
6
+ # @api private
7
+ class Input
8
+
9
+ # @return [String|Symbol]
10
+ def self.capture
11
+ new.capture
12
+ end
13
+
14
+ # Returns a new instance of Input.
15
+ #
16
+ # @return [Input]
17
+ def initialize; end
18
+
19
+ # @return []
20
+ def capture
21
+ Vedeu.trigger(:_keypress_, keypress)
22
+ end
23
+
24
+ private
25
+
26
+ # @api private
27
+ # @return [String]
28
+ def input
29
+ @_input ||= Terminal.input
30
+ end
31
+
32
+ # @api private
33
+ # @return [String|Symbol]
34
+ def keypress
35
+ key = input
36
+
37
+ specials.fetch(key, key)
38
+ end
39
+
40
+ # @api private
41
+ # @return [Hash]
42
+ def specials
43
+ {
44
+ "\r" => :enter,
45
+ "\t" => :tab,
46
+ "\e" => :escape,
47
+ "\e[A" => :up,
48
+ "\e[B" => :down,
49
+ "\e[C" => :right,
50
+ "\e[D" => :left,
51
+ "\e[5~" => :page_up,
52
+ "\e[6~" => :page_down,
53
+ "\e[H" => :home,
54
+ "\e[3~" => :delete,
55
+ "\e[F" => :end,
56
+ "\e[Z" => :shift_tab,
57
+ "\eOP" => :f1,
58
+ "\eOQ" => :f2,
59
+ "\eOR" => :f3,
60
+ "\eOS" => :f4,
61
+ "\e[15~" => :f5,
62
+ "\e[17~" => :f6,
63
+ "\e[18~" => :f7,
64
+ "\e[19~" => :f8,
65
+ "\e[20~" => :f9,
66
+ "\e[21~" => :f10,
67
+ "\e[23~" => :f11,
68
+ "\e[24~" => :f12,
69
+ "\e[1;2P" => :print_screen,
70
+ "\e[1;2Q" => :scroll_lock,
71
+ "\e[1;2R" => :pause_break,
72
+ "\u007F" => :backspace,
73
+ }
74
+ end
75
+
76
+ end
77
+ end
@@ -1,4 +1,11 @@
1
1
  module Vedeu
2
+
3
+ # This class ensures that STDIN, STDOUT and STDERR point to the correct
4
+ # places. It also handles the initial configuration of the application,
5
+ # the starting of the application, the handling of uncaught exceptions and
6
+ # finally the exiting of the application with the correct exit code.
7
+ #
8
+ # @api public
2
9
  class Launcher
3
10
 
4
11
  # :nocov:
@@ -1,18 +1,28 @@
1
1
  module Vedeu
2
+
3
+ # The class represents one half (the other, can be found at
4
+ # {Vedeu::Foreground}) of a terminal colour escape sequence.
5
+ #
6
+ # @api private
2
7
  class Background < ColourTranslator
3
8
 
4
9
  private
5
10
 
11
+ # Returns an escape sequence for a named background colour.
12
+ #
13
+ # Valid names are: `:black`, `:red`, `:green`, `:yellow`, `:blue`,
14
+ # `:magenta`, `:cyan`, `:white` and `:default`.
15
+ #
6
16
  # @api private
7
17
  # @return [String]
8
18
  def named
9
- ["\e[", background_codes[colour], "m"].join
19
+ ["\e[", background_codes[colour], 'm'].join
10
20
  end
11
21
 
12
22
  # @api private
13
23
  # @return [String]
14
24
  def numbered
15
- ["\e[48;5;", css_to_numbered, "m"].join
25
+ ["\e[48;5;", css_to_numbered, 'm'].join
16
26
  end
17
27
 
18
28
  # @api private
@@ -27,6 +37,9 @@ module Vedeu
27
37
  end
28
38
  end
29
39
 
40
+ # Produces the background named colour escape sequence hash from the
41
+ # foreground escape sequence hash.
42
+ #
30
43
  # @api private
31
44
  # @return [Hash]
32
45
  def background_codes
@@ -1,27 +1,42 @@
1
1
  module Vedeu
2
+
3
+ # Provides means to convert attributes into the correct model.
4
+ #
5
+ # @api private
2
6
  module Coercions
7
+
8
+ # Contains class methods which are accessible as such to classes and modules
9
+ # which include {Vedeu::Coercions}.
3
10
  module ClassMethods
4
11
 
12
+ include Vedeu::Common
13
+
5
14
  # Produces new objects of the correct class from attributes hashes,
6
15
  # ignores objects that have already been coerced.
16
+ # When provided with a parent argument, will allow the new object
17
+ # to know the colour and style of its parent.
7
18
  #
8
19
  # @param values [Array|Hash]
20
+ # @param parent [Hash|Nil]
9
21
  # @return [Array]
10
- def coercer(values)
11
- return [] if values.nil? || values.empty?
22
+ def coercer(values, parent = nil)
23
+ return [] unless defined_value?(values)
12
24
 
13
25
  [values].flatten.map do |value|
14
26
  if value.is_a?(self)
15
27
  value
16
28
 
17
29
  else
18
- self.new(value)
30
+ self.new(value.merge!({ parent: parent }))
19
31
 
20
32
  end
21
33
  end
22
34
  end
23
35
  end
24
36
 
37
+ # Whenever this module {Vedeu::Coercions} is included in another class or
38
+ # module, make its methods into class methods, so they may be called
39
+ # directly.
25
40
  def self.included(receiver)
26
41
  receiver.extend(ClassMethods)
27
42
  end
@@ -1,30 +1,36 @@
1
1
  module Vedeu
2
+
3
+ # Convert a CSS/HTML colour string into a terminal escape sequence.
4
+ #
5
+ # If provided with an empty value or a string it cannot convert, it will
6
+ # return an empty string.
7
+ #
8
+ # When provided with a named colour, uses the terminal's value for that
9
+ # colour. If a theme is being used with the terminal, which overrides the
10
+ # defaults, then the theme's colour will be used. The recognised names are:
11
+ # :black, :red, :green, :yellow, :blue, :magenta, :cyan, :white, :default.
12
+ #
13
+ # When a number between 0 and 255 is provided, Vedeu will use the terminal
14
+ # colour corresponding with that colour. TODO: Create chart.
15
+ #
16
+ # Finally, when provided a CSS/HTML colour string e.g. '#ff0000', Vedeu will
17
+ # translate that to the 8-bit escape sequence or if you have a capable
18
+ # terminal and the `VEDEU_TERM=xterm-truecolor` environment variable set,
19
+ # a 24-bit representation.
20
+ #
21
+ # @api private
2
22
  class ColourTranslator
3
23
 
4
24
  # Convert a CSS/HTML colour string into a terminal escape sequence.
5
25
  #
6
- # If provided with an empty value or a string it cannot convert, it will
7
- # return an empty string.
8
- #
9
- # When provided with a named colour, uses the terminal's value for that
10
- # colour. If a theme is being used with the terminal, which overrides the
11
- # defaults, then the theme's colour will be used. The recognised names are:
12
- # :black, :red, :green, :yellow, :blue, :magenta, :cyan, :white, :default.
13
- #
14
- # When a number between 0 and 255 is provided, Vedeu will use the terminal
15
- # colour corresponding with that colour. TODO: Create chart.
16
- #
17
- # Finally, when provided a CSS/HTML colour string e.g. '#ff0000', Vedeu will
18
- # translate that to the 8-bit escape sequence or if you have a capable
19
- # terminal and the `VEDEU_TERM=xterm-truecolor` environment variable set,
20
- # a 24-bit representation.
21
- #
22
26
  # @param colour [String]
23
27
  # @return [String]
24
28
  def self.escape_sequence(colour = '')
25
29
  new(colour).escape_sequence
26
30
  end
27
31
 
32
+ # Return a new instance of ColourTranslator.
33
+ #
28
34
  # @param colour [String]
29
35
  # @return [ColourTranslator]
30
36
  def initialize(colour = '')
@@ -32,7 +38,7 @@ module Vedeu
32
38
  end
33
39
 
34
40
  # @return [String]
35
- # @see Vedeu::ColourTranslator.escape_sequence
41
+ # @see Vedeu::ColourTranslator
36
42
  def escape_sequence
37
43
  if no_colour?
38
44
  ''
@@ -1,4 +1,9 @@
1
1
  module Vedeu
2
+
3
+ # The class represents one half (the other, can be found at
4
+ # {Vedeu::Background}) of a terminal colour escape sequence.
5
+ #
6
+ # @api private
2
7
  class Foreground < ColourTranslator
3
8
 
4
9
  private
@@ -6,13 +11,13 @@ module Vedeu
6
11
  # @api private
7
12
  # @return [String]
8
13
  def named
9
- ["\e[", foreground_codes[colour], "m"].join
14
+ ["\e[", foreground_codes[colour], 'm'].join
10
15
  end
11
16
 
12
17
  # @api private
13
18
  # @return [String]
14
19
  def numbered
15
- ["\e[38;5;", css_to_numbered, "m"].join
20
+ ["\e[38;5;", css_to_numbered, 'm'].join
16
21
  end
17
22
 
18
23
  # @api private
@@ -27,6 +32,9 @@ module Vedeu
27
32
  end
28
33
  end
29
34
 
35
+ # Produces the foreground named colour escape sequence hash from
36
+ # {Vedeu::ColourTranslator#codes}
37
+ #
30
38
  # @api private
31
39
  # @return [Hash]
32
40
  def foreground_codes
@@ -1,15 +1,77 @@
1
1
  module Vedeu
2
+
3
+ # This module allows the sharing of presentation concerns between the models:
4
+ # Interface, Line and Stream.
5
+ #
6
+ # @api private
2
7
  module Presentation
3
8
 
9
+ # Returns the colour attributes of the receiving class.
10
+ #
11
+ # @return [Hash]
12
+ def view_attributes
13
+ {
14
+ colour: attributes[:colour],
15
+ style: attributes[:style],
16
+ }
17
+ end
18
+
19
+ # Returns a new Colour instance.
20
+ #
4
21
  # @return [Colour]
5
22
  def colour
6
23
  @colour ||= Colour.new(attributes[:colour])
7
24
  end
8
25
 
26
+ # Returns a new Style instance.
27
+ #
9
28
  # @return [Style]
10
29
  def style
11
30
  @style ||= Style.new(attributes[:style])
12
31
  end
13
32
 
33
+ # Converts the colours and styles to escape sequences, and if the parent
34
+ # model has previously set the colour and style, reverts back to that for
35
+ # consistent formatting.
36
+ #
37
+ # @return [String]
38
+ def to_s
39
+ render_colour do
40
+ render_style do
41
+ data
42
+ end
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ # @api private
49
+ # @return [String]
50
+ def render_colour(&block)
51
+ [ colour.to_s, yield, parent_colour ].join
52
+ end
53
+
54
+ # @api private
55
+ # @return [String]
56
+ def render_style(&block)
57
+ [ style.to_s, yield, parent_style ].join
58
+ end
59
+
60
+ # @api private
61
+ # @return [String]
62
+ def parent_colour
63
+ return '' if parent.nil?
64
+
65
+ Colour.new(parent[:colour]).to_s
66
+ end
67
+
68
+ # @api private
69
+ # @return [String]
70
+ def parent_style
71
+ return '' if parent.nil?
72
+
73
+ Style.new(parent[:style]).to_s
74
+ end
75
+
14
76
  end
15
77
  end
@@ -1,11 +1,15 @@
1
1
  module Vedeu
2
+
3
+ # Provides a container for terminal escape sequences controlling the
4
+ # foreground and background colours of a character or collection of
5
+ # characters.
6
+ #
7
+ # @api private
2
8
  class Colour
3
9
 
4
10
  attr_reader :attributes
5
11
 
6
- # Initialises a new Colour object which is a container terminal escape
7
- # sequences controlling the foreground and background colour of a
8
- # character or collection of characters.
12
+ # Returns a new instance of Colour.
9
13
  #
10
14
  # @param attributes [Hash]
11
15
  # @return [Colour]
@@ -1,10 +1,11 @@
1
1
  module Vedeu
2
+
3
+ # A composition is a collection of interfaces.
2
4
  class Composition
3
5
 
4
6
  attr_reader :attributes
5
7
 
6
- # Builds a new composition, which is a collection of interfaces, ready to be
7
- # rendered to the screen.
8
+ # Builds a new composition, ready to be rendered to the screen.
8
9
  #
9
10
  # @param attributes [Hash]
10
11
  # @param block [Proc]
@@ -13,6 +14,8 @@ module Vedeu
13
14
  new(attributes, &block).attributes
14
15
  end
15
16
 
17
+ # Returns a new instance of Composition.
18
+ #
16
19
  # @param attributes [Hash]
17
20
  # @param block [Proc]
18
21
  # @return [Composition]
@@ -26,30 +29,23 @@ module Vedeu
26
29
  end
27
30
  end
28
31
 
29
- # Returns a collection of interface attributes associated with this
30
- # composition.
32
+ # Returns a collection of interfaces associated with this composition.
31
33
  #
32
34
  # @return [Array]
33
35
  def interfaces
34
- @interfaces ||= if attributes[:interfaces].nil? || attributes[:interfaces].empty?
35
- []
36
-
37
- else
38
- [ attributes[:interfaces] ].flatten.map do |attrs|
39
- stored = Buffers.retrieve_attributes(attrs[:name])
40
-
41
- combined = stored.merge(attrs) do |key, s, a|
42
- key == :lines && s.empty? ? a : s
43
- end
44
-
45
- Interface.new(combined)
46
- end
36
+ @interfaces ||= Interface.coercer(attributes[:interfaces])
37
+ end
47
38
 
48
- end
39
+ # Returns the view attributes for a Composition, which will always be none,
40
+ # as a composition is a merely a collection of interfaces.
41
+ #
42
+ # @return [Hash]
43
+ def view_attributes
44
+ {}
49
45
  end
50
46
 
51
47
  # Returns the complete escape sequence which this composition renders to.
52
- # This is used by {Terminal.output} to draw the view.
48
+ # This is used by {Vedeu::Terminal.output} to draw the view.
53
49
  #
54
50
  # @return [String]
55
51
  def to_s
@@ -58,6 +54,8 @@ module Vedeu
58
54
 
59
55
  private
60
56
 
57
+ # The default values for a new instance of Composition.
58
+ #
61
59
  # @api private
62
60
  # @return [Hash]
63
61
  def defaults