vedeu 0.2.10 → 0.2.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/docs/events.md +6 -0
  3. data/examples/{cursor_app/cursor_app.rb → cursor_app.rb} +1 -1
  4. data/examples/{lines_app/lines_app.rb → lines_app.rb} +1 -1
  5. data/lib/vedeu.rb +48 -28
  6. data/lib/vedeu/api/api.rb +8 -95
  7. data/lib/vedeu/application.rb +6 -2
  8. data/lib/vedeu/{models → colours}/background.rb +1 -1
  9. data/lib/vedeu/{models → colours}/colour.rb +0 -0
  10. data/lib/vedeu/{models → colours}/foreground.rb +2 -2
  11. data/lib/vedeu/{support/colour_translator.rb → colours/translator.rb} +7 -7
  12. data/lib/vedeu/input/input.rb +13 -5
  13. data/lib/vedeu/models/geometry.rb +30 -2
  14. data/lib/vedeu/models/key.rb +39 -0
  15. data/lib/vedeu/output/compositor.rb +30 -76
  16. data/lib/vedeu/output/output.rb +74 -0
  17. data/lib/vedeu/output/viewport.rb +36 -44
  18. data/lib/vedeu/repositories/buffers.rb +5 -18
  19. data/lib/vedeu/repositories/cursors.rb +16 -8
  20. data/lib/vedeu/repositories/events.rb +96 -9
  21. data/lib/vedeu/repositories/focus.rb +21 -20
  22. data/lib/vedeu/repositories/groups.rb +3 -11
  23. data/lib/vedeu/repositories/interfaces.rb +6 -9
  24. data/lib/vedeu/repositories/keymaps.rb +8 -3
  25. data/lib/vedeu/repositories/menus.rb +6 -21
  26. data/lib/vedeu/{models → repositories/models}/buffer.rb +62 -28
  27. data/lib/vedeu/{models → repositories/models}/cursor.rb +8 -2
  28. data/lib/vedeu/{models → repositories/models}/event.rb +7 -0
  29. data/lib/vedeu/repositories/models/group.rb +56 -0
  30. data/lib/vedeu/{models → repositories/models}/interface.rb +6 -0
  31. data/lib/vedeu/{models → repositories/models}/keymap.rb +7 -1
  32. data/lib/vedeu/{models → repositories/models}/menu.rb +9 -0
  33. data/lib/vedeu/{models → repositories/models}/offset.rb +8 -1
  34. data/lib/vedeu/repositories/offsets.rb +17 -12
  35. data/lib/vedeu/support/bounding_area.rb +127 -0
  36. data/lib/vedeu/support/common.rb +8 -0
  37. data/lib/vedeu/support/exceptions.rb +2 -12
  38. data/lib/vedeu/support/model.rb +14 -0
  39. data/lib/vedeu/support/refresh.rb +8 -7
  40. data/lib/vedeu/support/registrar.rb +7 -1
  41. data/lib/vedeu/support/repository.rb +31 -10
  42. data/lib/vedeu/support/sentence.rb +67 -0
  43. data/lib/vedeu/support/terminal.rb +19 -0
  44. data/lib/vedeu/support/trace.rb +2 -5
  45. data/test/integration/api/api_test.rb +97 -0
  46. data/test/integration/api_dsl/dsl_api_test.rb +4 -0
  47. data/test/integration/api_dsl/dsl_composition_test.rb +4 -0
  48. data/test/integration/api_dsl/dsl_defined_test.rb +4 -0
  49. data/test/integration/api_dsl/dsl_helpers_test.rb +4 -0
  50. data/test/integration/api_dsl/dsl_interface_test.rb +4 -0
  51. data/test/integration/api_dsl/dsl_keymap.rb +4 -0
  52. data/test/integration/api_dsl/dsl_line_test.rb +4 -0
  53. data/test/integration/api_dsl/dsl_menu_test.rb +4 -0
  54. data/test/integration/api_dsl/dsl_stream_test.rb +138 -0
  55. data/test/lib/vedeu/api/api_test.rb +1 -25
  56. data/test/lib/vedeu/api/helpers_test.rb +0 -10
  57. data/test/lib/vedeu/{models → colours}/background_test.rb +0 -0
  58. data/test/lib/vedeu/{models → colours}/colour_test.rb +0 -0
  59. data/test/lib/vedeu/{models → colours}/foreground_test.rb +0 -0
  60. data/test/lib/vedeu/{support/colour_translator_test.rb → colours/translator_test.rb} +3 -3
  61. data/test/lib/vedeu/input/input_test.rb +16 -47
  62. data/test/lib/vedeu/models/geometry_test.rb +46 -0
  63. data/test/lib/vedeu/models/group_test.rb +99 -0
  64. data/test/lib/vedeu/models/key_test.rb +41 -0
  65. data/test/lib/vedeu/output/compositor_test.rb +25 -101
  66. data/test/lib/vedeu/output/output_test.rb +108 -0
  67. data/test/lib/vedeu/repositories/buffers_test.rb +0 -8
  68. data/test/lib/vedeu/repositories/cursors_test.rb +34 -0
  69. data/test/lib/vedeu/repositories/focus_test.rb +37 -28
  70. data/test/lib/vedeu/repositories/interfaces_test.rb +1 -1
  71. data/test/lib/vedeu/repositories/keymaps_test.rb +6 -20
  72. data/test/lib/vedeu/repositories/menus_test.rb +0 -6
  73. data/test/lib/vedeu/{models → repositories/models}/buffer_test.rb +24 -27
  74. data/test/lib/vedeu/{models → repositories/models}/cursor_test.rb +0 -0
  75. data/test/lib/vedeu/{models → repositories/models}/event_test.rb +0 -0
  76. data/test/lib/vedeu/{models → repositories/models}/interface_test.rb +0 -0
  77. data/test/lib/vedeu/{models → repositories/models}/keymap_test.rb +0 -0
  78. data/test/lib/vedeu/{models → repositories/models}/menu_test.rb +0 -0
  79. data/test/lib/vedeu/{models → repositories/models}/offset_test.rb +0 -0
  80. data/test/lib/vedeu/support/bounding_area_test.rb +139 -0
  81. data/test/lib/vedeu/support/coercions_test.rb +6 -17
  82. data/test/lib/vedeu/support/grid_test.rb +1 -1
  83. data/test/lib/vedeu/support/model_test.rb +23 -0
  84. data/test/lib/vedeu/support/presentation_test.rb +0 -10
  85. data/test/lib/vedeu/support/refresh_test.rb +2 -2
  86. data/test/lib/vedeu/support/repository_test.rb +63 -64
  87. data/test/lib/vedeu/support/sentence_test.rb +48 -0
  88. data/test/lib/vedeu/support/terminal_test.rb +86 -6
  89. data/test/support/test_classes/all.rb +5 -0
  90. data/test/support/test_classes/coercions.rb +16 -0
  91. data/test/support/test_classes/helpers.rb +19 -0
  92. data/test/support/test_classes/model.rb +23 -0
  93. data/test/support/test_classes/presentation.rb +16 -0
  94. data/test/support/test_classes/repositories.rb +26 -0
  95. data/test/support/test_modules/all.rb +1 -0
  96. data/test/support/test_modules/repository.rb +16 -0
  97. data/test/test_helper.rb +4 -0
  98. data/vedeu.gemspec +3 -3
  99. metadata +95 -50
  100. data/lib/vedeu/output/clear.rb +0 -88
  101. data/lib/vedeu/output/render.rb +0 -50
  102. data/lib/vedeu/repositories/positional.rb +0 -23
  103. data/test/lib/vedeu/output/clear_test.rb +0 -56
  104. data/test/lib/vedeu/output/render_test.rb +0 -100
  105. data/test/lib/vedeu/repositories/positional_test.rb +0 -50
@@ -7,13 +7,21 @@ module Vedeu
7
7
  module Cursors
8
8
 
9
9
  include Repository
10
- include Positional
11
10
  extend self
12
11
 
13
- # System events which when called will update the cursor visibility
14
- # accordingly for the interface in focus.
15
- Vedeu.event(:_cursor_hide_) { Cursors.hide }
16
- Vedeu.event(:_cursor_show_) { Cursors.show }
12
+ # Add or update the cursor coordinates.
13
+ #
14
+ # @param attributes [Hash]
15
+ # @return [Offset]
16
+ def add(attributes)
17
+ validate_attributes!(attributes)
18
+
19
+ Vedeu.log("#{action(__callee__)} positional (#{model}): " \
20
+ "'#{attributes[:name]}'")
21
+
22
+ model.new(attributes).store
23
+ end
24
+ alias_method :update, :add
17
25
 
18
26
  # Make the cursor of this interface invisible.
19
27
  #
@@ -31,9 +39,9 @@ module Vedeu
31
39
 
32
40
  private
33
41
 
34
- # @return [Class]
35
- def entity
36
- Cursor
42
+ # @return [Class] The model class for this repository.
43
+ def model
44
+ Vedeu::Cursor
37
45
  end
38
46
 
39
47
  # Returns an empty collection ready for the storing of cursors by name with
@@ -14,11 +14,53 @@ module Vedeu
14
14
  # @see Vedeu::API#unevent
15
15
  alias_method :unevent, :remove
16
16
 
17
- # @see Vedeu::API#event
17
+ # Register an event by name with optional delay (throttling) which when
18
+ # triggered will execute the code contained within the passed block.
19
+ #
20
+ # @param name [Symbol] The name of the event which will be triggered later.
21
+ # @param [Hash] opts The options to register the event with.
22
+ # @option opts :delay [Fixnum|Float] Limits the execution of the
23
+ # triggered event to only execute when first triggered, with subsequent
24
+ # triggering being ignored until the delay has expired.
25
+ # @option opts :debounce [Fixnum|Float] Limits the execution of the
26
+ # triggered event to only execute once the debounce has expired.
27
+ # Subsequent triggers before debounce expiry are ignored.
28
+ # @param block [Proc] The event to be executed when triggered. This block
29
+ # could be a method call, or the triggering of another event, or sequence
30
+ # of either/both.
31
+ #
32
+ # @example
33
+ # Vedeu.event :my_event do |some, args|
34
+ # ... some code here ...
35
+ #
36
+ # Vedeu.trigger(:my_other_event)
37
+ # end
38
+ #
39
+ # T = Triggered, X = Executed, i = Ignored.
40
+ #
41
+ # 0.0.....0.2.....0.4.....0.6.....0.8.....1.0.....1.2.....1.4.....1.6...
42
+ # .T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T
43
+ # .X...i...i...i...i...X...i...i...i...i...X...i...i...i...i...i...i...i
44
+ #
45
+ # Vedeu.event(:my_delayed_event, { delay: 0.5 })
46
+ # ... some code here ...
47
+ # end
48
+ #
49
+ # T = Triggered, X = Executed, i = Ignored.
50
+ #
51
+ # 0.0.....0.2.....0.4.....0.6.....0.8.....1.0.....1.2.....1.4.....1.6...
52
+ # .T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T
53
+ # .i...i...i...i...i...i...i...X...i...i...i...i...i...i...X...i...i...i
54
+ #
55
+ # Vedeu.event(:my_debounced_event, { debounce: 0.7 })
56
+ # ... some code here ...
57
+ # end
58
+ #
59
+ # @return [Hash]
18
60
  def add(name, options = {}, &block)
19
61
  Vedeu.log("Registering event: '#{name}'")
20
62
 
21
- events(name) << Event.new(name, options, block)
63
+ events(name) << model.new(name, options, block)
22
64
  end
23
65
  alias_method :event, :add
24
66
 
@@ -34,6 +76,11 @@ module Vedeu
34
76
 
35
77
  private
36
78
 
79
+ # @return [Class] The model class for this repository.
80
+ def model
81
+ Vedeu::Event
82
+ end
83
+
37
84
  def events(name)
38
85
  storage[name][:events]
39
86
  end
@@ -47,13 +94,53 @@ module Vedeu
47
94
  end
48
95
 
49
96
  # System events needed by Vedeu to run.
50
- event(:_clear_) { Terminal.clear_screen }
51
- event(:_exit_) { Vedeu::Application.stop }
52
- event(:_initialize_) { Vedeu.trigger(:_refresh_) }
53
- event(:_keypress_) { |key| Vedeu.keypress(key) }
54
- event(:_log_) { |msg| Vedeu.log(msg) }
55
- event(:_mode_switch_) { fail ModeSwitch }
56
- event(:_resize_, { delay: 0.25 }) { Vedeu.resize }
97
+ event(:_clear_) { Vedeu::Terminal.clear_screen }
98
+ event(:_exit_) { Vedeu::Application.stop }
99
+ event(:_initialize_) { Vedeu.trigger(:_refresh_) }
100
+ event(:_keypress_) { |key| Vedeu.keypress(key) }
101
+ event(:_log_) { |msg| Vedeu.log(msg) }
102
+ event(:_mode_switch_) { fail ModeSwitch }
103
+ event(:_resize_, { delay: 0.25 }) { Vedeu.resize }
104
+
105
+ # System events which when called will update the cursor visibility
106
+ # accordingly for the interface in focus.
107
+ # From: Cursors (top)
108
+ event(:_cursor_hide_) { Vedeu::Cursors.hide }
109
+ event(:_cursor_show_) { Vedeu::Cursors.show }
110
+
111
+ # System events which when called will change which interface is currently
112
+ # focussed. When the interface is brought into focus, its cursor position
113
+ # and visibility is restored.
114
+ # From: Focus (top)
115
+ event(:_focus_by_name_) { |name| Vedeu::Focus.by_name(name) }
116
+ event(:_focus_next_) { Vedeu::Focus.next_item }
117
+ event(:_focus_prev_) { Vedeu::Focus.prev_item }
118
+
119
+ # System events which when called will move in the direction specified;
120
+ # these will update the cursor position or content offset (scrolling)
121
+ # according to the interface in focus.
122
+ # From: Offsets (bottom)
123
+ event(:_cursor_down_) { Vedeu::Offsets.down }
124
+ event(:_cursor_left_) { Vedeu::Offsets.left }
125
+ event(:_cursor_right_) { Vedeu::Offsets.right }
126
+ event(:_cursor_up_) { Vedeu::Offsets.up }
127
+
128
+ # System events which when called with the appropriate menu name will
129
+ # update the menu accordingly.
130
+ # From: Menus (top)
131
+ event(:_menu_bottom_) { |name| Vedeu::Menus.use(name).bottom_item }
132
+ event(:_menu_current_) { |name| Vedeu::Menus.use(name).current_item }
133
+ event(:_menu_deselect_) { |name| Vedeu::Menus.use(name).deselect_item }
134
+ event(:_menu_items_) { |name| Vedeu::Menus.use(name).items }
135
+ event(:_menu_next_) { |name| Vedeu::Menus.use(name).next_item }
136
+ event(:_menu_prev_) { |name| Vedeu::Menus.use(name).prev_item }
137
+ event(:_menu_selected_) { |name| Vedeu::Menus.use(name).selected_item }
138
+ event(:_menu_select_) { |name| Vedeu::Menus.use(name).select_item }
139
+ event(:_menu_top_) { |name| Vedeu::Menus.use(name).top_item }
140
+ event(:_menu_view_) { |name| Vedeu::Menus.use(name).view }
141
+
142
+ # System event to refresh all registered interfaces.
143
+ event(:_refresh_) { Vedeu::Refresh.all }
57
144
 
58
145
  end # Events
59
146
 
@@ -10,27 +10,20 @@ module Vedeu
10
10
  include Repository
11
11
  extend self
12
12
 
13
- # System events which when called will change which interface is currently
14
- # focussed. When the interface is brought into focus, its cursor position
15
- # and visibility is restored.
16
- Vedeu.event(:_focus_by_name_) { |name| Vedeu::Focus.by_name(name) }
17
- Vedeu.event(:_focus_next_) { Vedeu::Focus.next_item }
18
- Vedeu.event(:_focus_prev_) { Vedeu::Focus.prev_item }
19
-
20
13
  # Add an interface name to the focus list unless it is already registered.
21
14
  #
22
- # @param attributes [String]
23
- # @return [Array]
24
- def add(attributes)
25
- validate_attributes!(attributes)
26
-
27
- return storage if registered?(attributes[:name])
15
+ # @param name [String] The name of the interface.
16
+ # @param focus [Boolean] When true, prepends the interface name to the
17
+ # collection, making that interface the currently focussed interface.
18
+ # @return [Array] The collection of interface names.
19
+ def add(name, focus = false)
20
+ return storage if registered?(name)
28
21
 
29
- if attributes[:focus]
30
- storage.unshift(attributes[:name])
22
+ if focus
23
+ storage.unshift(name)
31
24
 
32
25
  else
33
- storage.push(attributes[:name])
26
+ storage.push(name)
34
27
 
35
28
  end
36
29
  end
@@ -38,10 +31,10 @@ module Vedeu
38
31
  # Focus an interface by name.
39
32
  #
40
33
  # @param name [String]
41
- # @raise [InterfaceNotFound] When the interface cannot be found.
34
+ # @raise [ModelNotFound] When the interface cannot be found.
42
35
  # @return [String]
43
36
  def by_name(name)
44
- fail InterfaceNotFound unless storage.include?(name)
37
+ fail ModelNotFound unless registered?(name)
45
38
 
46
39
  storage.rotate!(storage.index(name))
47
40
 
@@ -54,11 +47,19 @@ module Vedeu
54
47
  # make one focussed.
55
48
  # @return [String]
56
49
  def current
57
- fail NoInterfacesDefined if storage.empty?
50
+ fail NoInterfacesDefined if empty?
58
51
 
59
52
  storage.first
60
53
  end
61
54
 
55
+ # Return the cursor for the currently focussed interface. May be hidden.
56
+ #
57
+ # @return [String] The escape sequence to render the cursor as shown or
58
+ # hidden.
59
+ def cursor
60
+ Interface.new(Interfaces.find(current)).cursor.to_s
61
+ end
62
+
62
63
  # Returns a boolean indicating whether the named interface is focussed.
63
64
  #
64
65
  # @param name [String]
@@ -102,7 +103,7 @@ module Vedeu
102
103
  #
103
104
  # @return [String|FalseClass]
104
105
  def update
105
- return false if storage.empty?
106
+ return false if empty?
106
107
 
107
108
  Vedeu.log("Interface in focus: '#{current}'")
108
109
 
@@ -31,10 +31,10 @@ module Vedeu
31
31
  # @param attributes [Hash]
32
32
  # @return [Boolean]
33
33
  def register_event(attributes)
34
- name = attributes[:group]
35
- delay = attributes[:delay] || 0.0
34
+ group_name = attributes[:group]
35
+ delay = attributes[:delay] || 0.0
36
36
 
37
- Vedeu::Refresh.register_event(:by_group, name, delay)
37
+ Vedeu::Refresh.register_event(:by_group, group_name, delay)
38
38
  end
39
39
 
40
40
  # @return [Hash]
@@ -42,14 +42,6 @@ module Vedeu
42
42
  Hash.new { |hash, key| hash[key] = Set.new }
43
43
  end
44
44
 
45
- # @param name [String]
46
- # @raise [GroupNotFound] When the entity cannot be found with this name.
47
- # @return [GroupNotFound]
48
- def not_found(name)
49
- fail GroupNotFound,
50
- "Cannot find interface group with this name: #{name}."
51
- end
52
-
53
45
  end # Groups
54
46
 
55
47
  end # Vedeu
@@ -29,7 +29,7 @@ module Vedeu
29
29
  # @param name [String]
30
30
  # @return [Interface]
31
31
  def build(name)
32
- Interface.new(find(name))
32
+ model.new(find(name))
33
33
  end
34
34
 
35
35
  # Reset the interfaces repository; removing all registered interfaces.
@@ -53,6 +53,11 @@ module Vedeu
53
53
 
54
54
  private
55
55
 
56
+ # @return [Class] The model class for this repository.
57
+ def model
58
+ Vedeu::Interface
59
+ end
60
+
56
61
  # @see Vedeu::Refresh.register_event
57
62
  # @param attributes [Hash]
58
63
  # @return [Boolean]
@@ -68,14 +73,6 @@ module Vedeu
68
73
  {}
69
74
  end
70
75
 
71
- # @param name [String]
72
- # @raise [InterfaceNotFound] When the entity cannot be found with this name.
73
- # @return [InterfaceNotFound]
74
- def not_found(name)
75
- fail InterfaceNotFound,
76
- "Interface was not found with this name: #{name}."
77
- end
78
-
79
76
  end # Interfaces
80
77
 
81
78
  end # Vedeu
@@ -119,7 +119,7 @@ module Vedeu
119
119
  # @example
120
120
  # Vedeu.keypress('s')
121
121
  #
122
- # @return [|FalseClass]
122
+ # @return [Array|FalseClass]
123
123
  def use(key)
124
124
  Vedeu.log("Key pressed: '#{key}'")
125
125
 
@@ -145,10 +145,15 @@ module Vedeu
145
145
 
146
146
  private
147
147
 
148
+ # @return [Class] The model class for this repository.
149
+ def model
150
+ Vedeu::Keymap
151
+ end
152
+
148
153
  # Triggers the system event defined for this key.
149
154
  #
150
155
  # @param key [String|Symbol]
151
- # @return [] The result(s) of triggering the event.
156
+ # @return [Array] The result(s) of triggering the event.
152
157
  def system_key(key)
153
158
  action = Vedeu::Configuration.system_keys.key(key)
154
159
  event = ['_', action, '_'].join.to_sym
@@ -160,7 +165,7 @@ module Vedeu
160
165
  #
161
166
  # @param attributes [Hash]
162
167
  # @param interface [String]
163
- # @return []
168
+ # @return [Array]
164
169
  def register(attributes, interface = '_global_keymap_')
165
170
  attributes[:keys].map do |keymap|
166
171
  KeymapValidator.check(storage, keymap[:key], interface)
@@ -8,19 +8,6 @@ module Vedeu
8
8
  include Repository
9
9
  extend self
10
10
 
11
- # System events which when called with the appropriate menu name will
12
- # update the menu accordingly.
13
- Vedeu.event(:_menu_current_) { |name| Menus.use(name).current_item }
14
- Vedeu.event(:_menu_selected_) { |name| Menus.use(name).selected_item }
15
- Vedeu.event(:_menu_next_) { |name| Menus.use(name).next_item }
16
- Vedeu.event(:_menu_prev_) { |name| Menus.use(name).prev_item }
17
- Vedeu.event(:_menu_top_) { |name| Menus.use(name).top_item }
18
- Vedeu.event(:_menu_bottom_) { |name| Menus.use(name).bottom_item }
19
- Vedeu.event(:_menu_select_) { |name| Menus.use(name).select_item }
20
- Vedeu.event(:_menu_deselect_) { |name| Menus.use(name).deselect_item }
21
- Vedeu.event(:_menu_items_) { |name| Menus.use(name).items }
22
- Vedeu.event(:_menu_view_) { |name| Menus.use(name).view }
23
-
24
11
  # Stores the menu attributes defined by the API.
25
12
  #
26
13
  # @param attributes [Hash]
@@ -30,7 +17,7 @@ module Vedeu
30
17
 
31
18
  Vedeu.log("Registering menu: '#{attributes[:name]}'")
32
19
 
33
- attributes.merge!({ items: Vedeu::Menu.new(attributes[:items]) })
20
+ attributes.merge!({ items: model.new(attributes[:items]) })
34
21
 
35
22
  storage.store(attributes[:name], attributes)
36
23
  end
@@ -45,6 +32,11 @@ module Vedeu
45
32
 
46
33
  private
47
34
 
35
+ # @return [Class] The model class for this repository.
36
+ def model
37
+ Vedeu::Menu
38
+ end
39
+
48
40
  # Returns an empty collection ready for the storing of menus by name with
49
41
  # associated menu instance.
50
42
  #
@@ -53,13 +45,6 @@ module Vedeu
53
45
  {}
54
46
  end
55
47
 
56
- # @param name [String]
57
- # @raise [MenuNotFound] When the entity cannot be found with this name.
58
- # @return [MenuNotFound]
59
- def not_found(name)
60
- fail MenuNotFound, "Menu was not found with this name: #{name}."
61
- end
62
-
63
48
  end # Menus
64
49
 
65
50
  end # Vedeu
@@ -12,6 +12,8 @@ module Vedeu
12
12
  #
13
13
  class Buffer
14
14
 
15
+ include Model
16
+
15
17
  attr_reader :back, :front, :name, :previous
16
18
  alias_method :current, :front
17
19
 
@@ -28,28 +30,6 @@ module Vedeu
28
30
  @previous = @attributes[:previous]
29
31
  end
30
32
 
31
- # Return a boolean indicating content on the front buffer.
32
- #
33
- # @return [Boolean]
34
- def front?
35
- front.any? { |k, v| k == :lines && v.any? }
36
- end
37
- alias_method :current?, :front?
38
-
39
- # Return a boolean indicating content on the back buffer.
40
- #
41
- # @return [Boolean]
42
- def back?
43
- back.any? { |k, v| k == :lines && v.any? }
44
- end
45
-
46
- # Return a boolean indicating content on the previous buffer.
47
- #
48
- # @return [Boolean]
49
- def previous?
50
- previous.any? { |k, v| k == :lines && v.any? }
51
- end
52
-
53
33
  # Add the content to the back buffer, then update the repository. Returns
54
34
  # boolean indicating that the repository was updated.
55
35
  #
@@ -58,7 +38,9 @@ module Vedeu
58
38
  def add(content = {})
59
39
  self.back = content
60
40
 
61
- update!
41
+ store
42
+
43
+ true
62
44
  end
63
45
 
64
46
  # Return a boolean indicating content was swapped between buffers. It also
@@ -66,7 +48,7 @@ module Vedeu
66
48
  #
67
49
  # @return [Boolean]
68
50
  def swap
69
- return false unless back?
51
+ return false unless content_for?(:back)
70
52
 
71
53
  # Offsets.update({ name: name })
72
54
 
@@ -74,16 +56,68 @@ module Vedeu
74
56
  self.front = back
75
57
  self.back = {}
76
58
 
77
- update!
59
+ store
60
+
61
+ true
62
+ end
63
+
64
+ # Return the content for this buffer.
65
+ #
66
+ # - If we have new content (i.e. content on 'back') to be shown, we first
67
+ # clear the area occupied by the previous content, then clear the area for
68
+ # the new content, and then finally render the new content.
69
+ # - If there is no new content (i.e. 'back' is empty), check the 'front'
70
+ # buffer and display that.
71
+ # - If there is no new content, and the front buffer is empty, display the
72
+ # 'previous' buffer.
73
+ # - If the 'previous' buffer is empty, return an empty hash.
74
+ #
75
+ # @return [Array<Hash>]
76
+ def content
77
+ if content_for?(:back)
78
+ swap
79
+
80
+ [clear_if_previous, front]
81
+
82
+ elsif content_for?(:front)
83
+ [front]
84
+
85
+ elsif content_for?(:previous)
86
+ [previous]
87
+
88
+ else
89
+ [{}]
90
+
91
+ end
78
92
  end
79
93
 
80
94
  private
81
95
 
82
96
  attr_writer :back, :front, :previous
83
97
 
84
- # @see Buffers#update
85
- def update!
86
- Buffers.update(self)
98
+ def clear_if_previous
99
+ if content_for?(:previous)
100
+ previous
101
+
102
+ else
103
+ {}
104
+
105
+ end
106
+ end
107
+
108
+ # Return a boolean indicating content presence on the buffer type.
109
+ #
110
+ # @param buffer [Symbol] One of; :back, :current/:front or :previous.
111
+ # @return [Boolean] Whether the buffer targetted has content.
112
+ def content_for?(buffer)
113
+ public_send(buffer).any? do |k, v|
114
+ k == :lines && v && v.any?
115
+ end
116
+ end
117
+
118
+ # @return [Class] The repository class for this model.
119
+ def repository
120
+ Vedeu::Buffers
87
121
  end
88
122
 
89
123
  # Return the default attributes of a Buffer.