vedeu 0.2.10 → 0.2.11

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 (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.