vedeu 0.2.1 → 0.2.2

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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/README.md +1 -2
  4. data/Rakefile +5 -5
  5. data/bin/vedeu +8 -4
  6. data/docs/api.md +3 -1
  7. data/docs/events.md +43 -29
  8. data/docs/getting_started.md +2 -0
  9. data/examples/cursor_app/cursor_app.rb +85 -0
  10. data/examples/lines_app/lines_app.rb +60 -0
  11. data/lib/vedeu.rb +9 -3
  12. data/lib/vedeu/api/api.rb +28 -7
  13. data/lib/vedeu/api/composition.rb +2 -0
  14. data/lib/vedeu/api/helpers.rb +2 -0
  15. data/lib/vedeu/api/interface.rb +2 -20
  16. data/lib/vedeu/api/keymap.rb +2 -0
  17. data/lib/vedeu/api/line.rb +2 -0
  18. data/lib/vedeu/api/menu.rb +3 -1
  19. data/lib/vedeu/api/stream.rb +25 -2
  20. data/lib/vedeu/application.rb +4 -4
  21. data/lib/vedeu/configuration/api.rb +327 -0
  22. data/lib/vedeu/configuration/cli.rb +110 -0
  23. data/lib/vedeu/{configuration.rb → configuration/configuration.rb} +49 -99
  24. data/lib/vedeu/launcher.rb +0 -1
  25. data/lib/vedeu/models/attributes/colour_translator.rb +2 -2
  26. data/lib/vedeu/models/colour.rb +0 -1
  27. data/lib/vedeu/models/composition.rb +2 -8
  28. data/lib/vedeu/models/cursor.rb +261 -0
  29. data/lib/vedeu/models/geometry.rb +11 -19
  30. data/lib/vedeu/models/interface.rb +2 -12
  31. data/lib/vedeu/models/keymap.rb +2 -0
  32. data/lib/vedeu/models/line.rb +2 -0
  33. data/lib/vedeu/models/stream.rb +2 -0
  34. data/lib/vedeu/models/style.rb +2 -0
  35. data/lib/vedeu/output/clear.rb +0 -1
  36. data/lib/vedeu/output/compositor.rb +0 -1
  37. data/lib/vedeu/output/refresh.rb +3 -0
  38. data/lib/vedeu/output/render.rb +12 -6
  39. data/lib/vedeu/output/view.rb +1 -0
  40. data/lib/vedeu/repositories/cursors.rb +98 -0
  41. data/lib/vedeu/repositories/events.rb +0 -1
  42. data/lib/vedeu/repositories/focus.rb +18 -0
  43. data/lib/vedeu/repositories/menus.rb +4 -4
  44. data/lib/vedeu/support/common.rb +2 -1
  45. data/lib/vedeu/support/event.rb +1 -10
  46. data/lib/vedeu/support/grid.rb +1 -2
  47. data/lib/vedeu/{repositories → support}/keymap_validator.rb +5 -4
  48. data/lib/vedeu/support/log.rb +3 -0
  49. data/lib/vedeu/support/menu.rb +4 -1
  50. data/lib/vedeu/support/registrar.rb +2 -1
  51. data/test/integration/defining_interfaces_test.rb +0 -1
  52. data/test/integration/views/basic_view_test.rb +741 -739
  53. data/test/lib/vedeu/api/api_test.rb +14 -3
  54. data/test/lib/vedeu/api/helpers_test.rb +3 -3
  55. data/test/lib/vedeu/api/interface_test.rb +17 -70
  56. data/test/lib/vedeu/api/keymap_test.rb +2 -0
  57. data/test/lib/vedeu/api/line_test.rb +4 -4
  58. data/test/lib/vedeu/api/menu_test.rb +6 -5
  59. data/test/lib/vedeu/api/stream_test.rb +18 -0
  60. data/test/lib/vedeu/configuration/api_test.rb +248 -0
  61. data/test/lib/vedeu/configuration/cli_test.rb +88 -0
  62. data/test/lib/vedeu/configuration/configuration_test.rb +67 -0
  63. data/test/lib/vedeu/input/input_test.rb +2 -2
  64. data/test/lib/vedeu/models/attributes/background_test.rb +3 -3
  65. data/test/lib/vedeu/models/attributes/foreground_test.rb +3 -3
  66. data/test/lib/vedeu/models/composition_test.rb +0 -222
  67. data/test/lib/vedeu/models/cursor_test.rb +164 -0
  68. data/test/lib/vedeu/models/interface_test.rb +0 -11
  69. data/test/lib/vedeu/output/compositor_test.rb +2 -4
  70. data/test/lib/vedeu/output/render_test.rb +4 -41
  71. data/test/lib/vedeu/repositories/cursors_test.rb +13 -0
  72. data/test/lib/vedeu/repositories/focus_test.rb +14 -4
  73. data/test/lib/vedeu/repositories/menus_test.rb +36 -29
  74. data/test/lib/vedeu/{repositories → support}/keymap_validator_test.rb +0 -0
  75. data/test/lib/vedeu/support/menu_test.rb +3 -3
  76. data/test/lib/vedeu/support/registrar_test.rb +6 -0
  77. data/test/lib/vedeu/support/terminal_test.rb +2 -2
  78. data/test/test_helper.rb +1 -1
  79. data/vedeu.gemspec +1 -1
  80. metadata +23 -14
  81. data/elements.txt +0 -118
  82. data/lib/vedeu/support/cursor.rb +0 -96
  83. data/test/lib/vedeu/configuration_test.rb +0 -154
  84. data/test/lib/vedeu/support/cursor_test.rb +0 -79
  85. data/test/support/model_test_data.json +0 -437
@@ -3,22 +3,13 @@ module Vedeu
3
3
  # Calculates and provides interface geometry determined by both the client's
4
4
  # requirements and the terminal's current viewing area.
5
5
  #
6
- # With terminal geometry, the origin is top-left, y = 1, x = 1.
6
+ # Geometry for Vedeu, as the same for ANSI terminals, has the origin at
7
+ # top-left, y = 1, x = 1. The 'y' coordinate is deliberately first.
7
8
  #
8
9
  # @api private
9
10
  class Geometry
10
11
 
11
- # @return [Hash]
12
- attr_reader :attributes
13
-
14
- # @return [Boolean]
15
- attr_reader :centred
16
-
17
- # @return [Fixnum]
18
- attr_reader :height
19
-
20
- # @return [Fixnum]
21
- attr_reader :width
12
+ attr_reader :attributes, :centred, :height, :width
22
13
 
23
14
  # Returns a new instance of Geometry.
24
15
  #
@@ -110,8 +101,8 @@ module Vedeu
110
101
  Esc.set_position(virtual_y[index], left, &block)
111
102
  end
112
103
 
113
- # Returns a fixed or dynamic value depending on whether the interface is
114
- # centred or not.
104
+ # Returns the top coordinate of the interface, a fixed or dynamic value
105
+ # depending on whether the interface is centred or not.
115
106
  #
116
107
  # @return [Fixnum]
117
108
  def top
@@ -139,8 +130,8 @@ module Vedeu
139
130
  top - value
140
131
  end
141
132
 
142
- # Returns a fixed or dynamic value depending on whether the interface is
143
- # centred or not.
133
+ # Returns the left coordinate of the interface, a fixed or dynamic value
134
+ # depending on whether the interface is centred or not.
144
135
  #
145
136
  # @return [Fixnum]
146
137
  def left
@@ -168,7 +159,8 @@ module Vedeu
168
159
  left - value
169
160
  end
170
161
 
171
- # Returns a fixed or dynamic value depending on the value of {#top}.
162
+ # Returns the bottom coordinate of the interface, a fixed or dynamic value
163
+ # depending on the value of {#top}.
172
164
  #
173
165
  # @return [Fixnum]
174
166
  def bottom
@@ -190,8 +182,8 @@ module Vedeu
190
182
  bottom + value
191
183
  end
192
184
 
193
- # Returns a fixed or dynamic value depending on whether the interface is
194
- # centred or not.
185
+ # Returns the right coordinate of the interface, a fixed or dynamic value
186
+ # depending on the value of {#left}.
195
187
  #
196
188
  # @return [Fixnum]
197
189
  def right
@@ -3,6 +3,8 @@ module Vedeu
3
3
  # An Interface represents a portion of the terminal defined by
4
4
  # {Vedeu::Geometry}. It is a container for {Vedeu::Line} and {Vedeu::Stream}
5
5
  # objects.
6
+ #
7
+ # @api private
6
8
  class Interface
7
9
 
8
10
  include Coercions
@@ -79,17 +81,6 @@ module Vedeu
79
81
  @geometry ||= Geometry.new(attributes[:geometry])
80
82
  end
81
83
 
82
- # @return [String]
83
- def cursor
84
- @cursor ||= if attributes[:cursor] == true
85
- Esc.string('show_cursor')
86
-
87
- else
88
- Esc.string('hide_cursor')
89
-
90
- end
91
- end
92
-
93
84
  private
94
85
 
95
86
  # The default values for a new instance of Interface.
@@ -104,7 +95,6 @@ module Vedeu
104
95
  colour: {},
105
96
  style: '',
106
97
  geometry: {},
107
- cursor: true,
108
98
  delay: 0.0,
109
99
  parent: nil,
110
100
  }
@@ -2,6 +2,8 @@ module Vedeu
2
2
 
3
3
  # A Keymap is the binding of a keypress to one or more interfaces; or globally
4
4
  # to perform a client application defined action.
5
+ #
6
+ # @api private
5
7
  class Keymap
6
8
 
7
9
  include Common
@@ -3,6 +3,8 @@ module Vedeu
3
3
  # A Line represents a single row of the terminal. It is a container for
4
4
  # {Vedeu::Stream} objects. A line's width is determined by the
5
5
  # {Vedeu::Interface} it belongs to.
6
+ #
7
+ # @api private
6
8
  class Line
7
9
 
8
10
  include Coercions
@@ -3,6 +3,8 @@ module Vedeu
3
3
  # A Stream can represent a character or collection of characters as part of a
4
4
  # {Vedeu::Line} which you wish to colour and style independently of the other
5
5
  # characters in that line.
6
+ #
7
+ # @api private
6
8
  class Stream
7
9
 
8
10
  include Coercions
@@ -2,6 +2,8 @@ module Vedeu
2
2
 
3
3
  # Converts the style value or value collection into a terminal escape
4
4
  # sequence. Unrecognised values are discarded- an empty string is returned.
5
+ #
6
+ # @api private
5
7
  class Style
6
8
 
7
9
  include Vedeu::Common
@@ -36,7 +36,6 @@ module Vedeu
36
36
 
37
37
  private
38
38
 
39
- # @return [Interface]
40
39
  attr_reader :interface
41
40
 
42
41
  # @api private
@@ -31,7 +31,6 @@ module Vedeu
31
31
 
32
32
  private
33
33
 
34
- # @return [String]
35
34
  attr_reader :name
36
35
 
37
36
  # Renders the buffer unless empty, otherwise clears the area which the
@@ -8,6 +8,9 @@ module Vedeu
8
8
  include Vedeu::Common
9
9
  extend self
10
10
 
11
+ # System event to refresh all registered interfaces.
12
+ Vedeu.event(:_refresh_) { Vedeu::Refresh.all }
13
+
11
14
  # Refresh all registered interfaces.
12
15
  #
13
16
  # @return [Array]
@@ -39,13 +39,11 @@ module Vedeu
39
39
  out << interface.origin(index)
40
40
  out << line.to_s
41
41
  end
42
- out << interface.cursor
43
42
  out.join
44
43
  end
45
44
 
46
45
  private
47
46
 
48
- # @return [Interface]
49
47
  attr_reader :interface
50
48
 
51
49
  # The client application may have created a line that us too long for the
@@ -58,9 +56,9 @@ module Vedeu
58
56
  # @api private
59
57
  # @return [Array]
60
58
  def processed_lines
61
- return [] unless lines.any? { |line| line.streams.any? }
59
+ return [] unless visible_lines.any? { |line| line.streams.any? }
62
60
 
63
- lines.map do |line|
61
+ visible_lines.map do |line|
64
62
  if exceeds_width?(line)
65
63
  line_length = 0
66
64
  new_streams = []
@@ -142,14 +140,22 @@ module Vedeu
142
140
  text.chomp.slice(0...value)
143
141
  end
144
142
 
145
- # Provides a collection of lines associated with the interface.
143
+ # Provides the collection of visible lines associated with the interface.
146
144
  # If the option `:top` was set, we will start at that line. Any lines
147
145
  # outside of the height will not be rendered.
148
146
  #
149
147
  # @api private
150
148
  # @return [Array]
149
+ def visible_lines
150
+ lines[top..height]
151
+ end
152
+
153
+ # Provides the collection of lines associated with the interface.
154
+ #
155
+ # @api private
156
+ # @return [Array]
151
157
  def lines
152
- interface.lines[top..height]
158
+ interface.lines
153
159
  end
154
160
 
155
161
  # Provides the currently available height of the interface.
@@ -7,6 +7,7 @@ module Vedeu
7
7
  #
8
8
  # @deprecated May disappear in 0.3.0. Prefer {Vedeu::API#render} instead.
9
9
  # @see Vedeu::API#render
10
+ # @api private
10
11
  class View
11
12
 
12
13
  include Vedeu::API
@@ -0,0 +1,98 @@
1
+ module Vedeu
2
+
3
+ # Repository for storing, retrieving and manipulating the cursor position and
4
+ # visibility for an interface.
5
+ #
6
+ # @api private
7
+ module Cursors
8
+
9
+ include Common
10
+ extend self
11
+
12
+ # System events which when called will update the cursor position or
13
+ # visibility accordingly for the interface in focus.
14
+ Vedeu.event(:_cursor_up_) { Cursors.use(:move_up) }
15
+ Vedeu.event(:_cursor_right_) { Cursors.use(:move_right) }
16
+ Vedeu.event(:_cursor_down_) { Cursors.use(:move_down) }
17
+ Vedeu.event(:_cursor_left_) { Cursors.use(:move_left) }
18
+ Vedeu.event(:_cursor_hide_) { Cursors.use(:hide) }
19
+ Vedeu.event(:_cursor_show_) { Cursors.use(:show) }
20
+ Vedeu.event(:_cursor_refresh_) { Cursors.use(:refresh) }
21
+
22
+ # Adds an interface to the cursors repository.
23
+ #
24
+ # @param attributes [Hash]
25
+ # @return [Hash]
26
+ def add(attributes)
27
+ return false unless defined_value?(attributes[:name])
28
+
29
+ storage.store(attributes[:name], {
30
+ name: attributes[:name],
31
+ x: 1,
32
+ y: 1,
33
+ state: :show
34
+ })
35
+ end
36
+
37
+ # Find the cursor attributes by name.
38
+ #
39
+ # @param name [String]
40
+ # @return [Hash]
41
+ def find(name)
42
+ storage.fetch(name) do
43
+ fail CursorNotFound,
44
+ "Cursor was not found with this name: #{name.to_s}."
45
+ end
46
+ end
47
+
48
+ # Returns a boolean indicating whether the named interface is registered.
49
+ #
50
+ # @api private
51
+ # @return [Boolean]
52
+ def registered?(name)
53
+ return false if storage.empty?
54
+
55
+ storage.keys.include?(name)
56
+ end
57
+
58
+ # Perform an action (moving, showing or hiding) and save the new cursor
59
+ # state.
60
+ #
61
+ # @param action [Symbol] A symbol representing the method name to be called
62
+ # on the Cursor instance.
63
+ # @return [String] The escape sequence sent to the Terminal on completion
64
+ # of the action.
65
+ def use(action)
66
+ name = Focus.current
67
+ cursor = Cursor.new(find(name))
68
+
69
+ storage.store(name, cursor.send(action))
70
+
71
+ Terminal.output(cursor.to_s)
72
+ end
73
+
74
+ private
75
+
76
+ # Access to the storage for this repository.
77
+ #
78
+ # @api private
79
+ # @example
80
+ # { 'holmium' => { name: 'holmium', y: 12, x: 6, state: :show } }
81
+ #
82
+ # @return [Hash]
83
+ def storage
84
+ @_storage ||= in_memory
85
+ end
86
+
87
+ # Returns an empty collection ready for the storing of cursors by name with
88
+ # current attributes.
89
+ #
90
+ # @api private
91
+ # @return [Hash]
92
+ def in_memory
93
+ {}
94
+ end
95
+
96
+ end
97
+
98
+ end
@@ -69,7 +69,6 @@ module Vedeu
69
69
 
70
70
  private
71
71
 
72
- # @return [Hash]
73
72
  attr_reader :handlers
74
73
 
75
74
  # @api private
@@ -9,6 +9,24 @@ module Vedeu
9
9
 
10
10
  extend self
11
11
 
12
+ # System events which when called will change which interface is currently
13
+ # focussed. When the interface is brought into focus, its cursor position
14
+ # and visibility is restored.
15
+ Vedeu.event(:_focus_by_name_) do |name|
16
+ Vedeu::Focus.by_name(name)
17
+ Vedeu.trigger(:_cursor_refresh_)
18
+ end
19
+
20
+ Vedeu.event(:_focus_next_) do
21
+ Vedeu::Focus.next_item
22
+ Vedeu.trigger(:_cursor_refresh_)
23
+ end
24
+
25
+ Vedeu.event(:_focus_prev_) do
26
+ Vedeu::Focus.prev_item
27
+ Vedeu.trigger(:_cursor_refresh_)
28
+ end
29
+
12
30
  # Add an interface name to the focus list unless it is already registered.
13
31
  #
14
32
  # @param attributes [String]
@@ -30,6 +30,8 @@ module Vedeu
30
30
 
31
31
  Vedeu.log("Registering menu '#{attributes[:name]}'")
32
32
 
33
+ attributes.merge!({ items: Vedeu::Menu.new(attributes[:items]) })
34
+
33
35
  storage.store(attributes[:name], attributes)
34
36
  end
35
37
 
@@ -90,11 +92,9 @@ module Vedeu
90
92
  # Access a menu by name.
91
93
  #
92
94
  # @param name [String]
93
- # @return [Vedeu::Menu|MenuNotFound]
95
+ # @return [Vedeu::Menu]
94
96
  def use(name)
95
- find(name).fetch(:items) do
96
- fail MenuNotFound, "This menu '#{name}' has no items."
97
- end
97
+ find(name).fetch(:items)
98
98
  end
99
99
 
100
100
  private
@@ -7,9 +7,10 @@ module Vedeu
7
7
 
8
8
  # Returns a boolean indicating whether a variable has a useful value.
9
9
  #
10
- # @param variable [String|Symbol|Array] The variable to check.
10
+ # @param variable [String|Symbol|Array|Fixnum] The variable to check.
11
11
  # @return [Boolean]
12
12
  def defined_value?(variable)
13
+ return true if variable.is_a?(Fixnum)
13
14
  return true unless variable.nil? || variable.empty?
14
15
 
15
16
  false
@@ -32,17 +32,8 @@ module Vedeu
32
32
 
33
33
  private
34
34
 
35
- # @return [Proc]
36
35
  attr_reader :closure
37
-
38
- # @return []
39
- attr_accessor :deadline
40
-
41
- # @return []
42
- attr_accessor :executed_at
43
-
44
- # @return []
45
- attr_accessor :now
36
+ attr_accessor :deadline, :executed_at, :now
46
37
 
47
38
  # Execute the code stored in the event closure.
48
39
  #
@@ -1,5 +1,5 @@
1
1
  # Monkey-patch Ruby's Fixnum to provide a columns method.
2
- # TODO: Don't monkey-patch because it is naughty.
2
+ # @todo Don't monkey-patch because it is naughty.
3
3
  class Fixnum
4
4
 
5
5
  # Augment Fixnum to calculate column width in a grid-based layout.
@@ -47,7 +47,6 @@ module Vedeu
47
47
 
48
48
  private
49
49
 
50
- # @return [Fixnum]
51
50
  attr_reader :value
52
51
 
53
52
  # @api private
@@ -3,6 +3,7 @@ module Vedeu
3
3
  # Validates that a given key is can be used and is not already in-use, either
4
4
  # by the same interface, globally or as a system key.
5
5
  #
6
+ # @api private
6
7
  class KeymapValidator
7
8
 
8
9
  include Common
@@ -31,17 +32,17 @@ module Vedeu
31
32
  # @see KeymapValidator.check
32
33
  def check
33
34
  if system_key?(key)
34
- [false, "#{fail_message(key)} by the system."]
35
+ [false, fail_message(key) + ' by the system.']
35
36
 
36
37
  elsif global_key?(key)
37
- [false, "#{fail_message(key)} as a global key."]
38
+ [false, fail_message(key) + ' as a global key.']
38
39
 
39
40
  elsif interface_key?(key, interface)
40
41
  if defined_value?(interface)
41
- [false, "#{fail_message(key)} by this interface."]
42
+ [false, fail_message(key) + ' by this interface.']
42
43
 
43
44
  else
44
- [false, "#{fail_message(key)} by another interface and therefore " \
45
+ [false, fail_message(key) + ' by another interface and therefore ' \
45
46
  'cannot be global.']
46
47
 
47
48
  end