vedeu 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/LICENSE.txt +5 -0
  4. data/bin/vedeu +3 -1
  5. data/docs/api.md +2 -0
  6. data/examples/cursor_app/cursor_app.rb +22 -7
  7. data/examples/hello_world.rb +42 -0
  8. data/lib/vedeu.rb +5 -5
  9. data/lib/vedeu/api/api.rb +16 -33
  10. data/lib/vedeu/api/helpers.rb +86 -0
  11. data/lib/vedeu/api/interface.rb +60 -17
  12. data/lib/vedeu/api/keymap.rb +5 -0
  13. data/lib/vedeu/api/line.rb +52 -34
  14. data/lib/vedeu/api/menu.rb +1 -1
  15. data/lib/vedeu/api/stream.rb +0 -34
  16. data/lib/vedeu/configuration/api.rb +10 -10
  17. data/lib/vedeu/configuration/cli.rb +1 -1
  18. data/lib/vedeu/launcher.rb +21 -6
  19. data/lib/vedeu/models/background.rb +1 -1
  20. data/lib/vedeu/models/composition.rb +1 -1
  21. data/lib/vedeu/models/cursor.rb +25 -35
  22. data/lib/vedeu/models/foreground.rb +1 -1
  23. data/lib/vedeu/models/geometry.rb +216 -6
  24. data/lib/vedeu/models/interface.rb +14 -16
  25. data/lib/vedeu/models/keymap.rb +38 -6
  26. data/lib/vedeu/models/line.rb +1 -1
  27. data/lib/vedeu/models/stream.rb +1 -1
  28. data/lib/vedeu/output/compositor.rb +1 -1
  29. data/lib/vedeu/output/render.rb +1 -5
  30. data/lib/vedeu/output/viewport.rb +37 -2
  31. data/lib/vedeu/repositories/buffers.rb +21 -27
  32. data/lib/vedeu/repositories/cursors.rb +3 -15
  33. data/lib/vedeu/repositories/focus.rb +2 -6
  34. data/lib/vedeu/repositories/groups.rb +1 -1
  35. data/lib/vedeu/repositories/interfaces.rb +1 -1
  36. data/lib/vedeu/repositories/keymaps.rb +26 -22
  37. data/lib/vedeu/repositories/menus.rb +1 -1
  38. data/lib/vedeu/repositories/offsets.rb +30 -12
  39. data/lib/vedeu/repositories/positional.rb +23 -0
  40. data/lib/vedeu/support/colour_translator.rb +1 -16
  41. data/lib/vedeu/support/esc.rb +23 -28
  42. data/lib/vedeu/support/event.rb +6 -14
  43. data/lib/vedeu/{output → support}/refresh.rb +0 -0
  44. data/lib/vedeu/support/registrar.rb +6 -14
  45. data/lib/vedeu/support/repository.rb +3 -2
  46. data/lib/vedeu/support/terminal.rb +9 -13
  47. data/lib/vedeu/support/trace.rb +2 -3
  48. data/test/integration/cursors_test.rb +9 -0
  49. data/test/integration/views/basic_view_test.rb +19 -0
  50. data/test/lib/vedeu/api/api_test.rb +28 -5
  51. data/test/lib/vedeu/api/composition_test.rb +7 -3
  52. data/test/lib/vedeu/api/defined_test.rb +9 -3
  53. data/test/lib/vedeu/api/helpers_test.rb +39 -5
  54. data/test/lib/vedeu/api/interface_test.rb +88 -8
  55. data/test/lib/vedeu/api/keymap_test.rb +5 -3
  56. data/test/lib/vedeu/api/line_test.rb +9 -3
  57. data/test/lib/vedeu/api/menu_test.rb +11 -7
  58. data/test/lib/vedeu/api/stream_test.rb +9 -31
  59. data/test/lib/vedeu/application_test.rb +25 -2
  60. data/test/lib/vedeu/configuration/api_test.rb +5 -3
  61. data/test/lib/vedeu/configuration/cli_test.rb +5 -3
  62. data/test/lib/vedeu/configuration/configuration_test.rb +5 -2
  63. data/test/lib/vedeu/input/input_test.rb +5 -2
  64. data/test/lib/vedeu/launcher_test.rb +37 -2
  65. data/test/lib/vedeu/models/background_test.rb +6 -2
  66. data/test/lib/vedeu/models/char_test.rb +9 -6
  67. data/test/lib/vedeu/models/colour_test.rb +6 -2
  68. data/test/lib/vedeu/models/composition_test.rb +4 -2
  69. data/test/lib/vedeu/models/cursor_test.rb +27 -16
  70. data/test/lib/vedeu/models/foreground_test.rb +6 -2
  71. data/test/lib/vedeu/models/geometry_test.rb +6 -2
  72. data/test/lib/vedeu/models/interface_test.rb +5 -2
  73. data/test/lib/vedeu/models/keymap_test.rb +6 -4
  74. data/test/lib/vedeu/models/line_test.rb +5 -2
  75. data/test/lib/vedeu/models/offset_test.rb +7 -3
  76. data/test/lib/vedeu/models/stream_test.rb +4 -2
  77. data/test/lib/vedeu/models/style_test.rb +5 -2
  78. data/test/lib/vedeu/output/clear_test.rb +6 -2
  79. data/test/lib/vedeu/output/compositor_test.rb +8 -4
  80. data/test/lib/vedeu/output/render_test.rb +9 -6
  81. data/test/lib/vedeu/output/view_test.rb +7 -3
  82. data/test/lib/vedeu/output/viewport_test.rb +42 -9
  83. data/test/lib/vedeu/repositories/buffers_test.rb +52 -12
  84. data/test/lib/vedeu/repositories/cursors_test.rb +4 -26
  85. data/test/lib/vedeu/repositories/events_test.rb +6 -2
  86. data/test/lib/vedeu/repositories/focus_test.rb +5 -2
  87. data/test/lib/vedeu/repositories/groups_test.rb +5 -2
  88. data/test/lib/vedeu/repositories/interfaces_test.rb +4 -2
  89. data/test/lib/vedeu/repositories/keymaps_test.rb +8 -2
  90. data/test/lib/vedeu/repositories/menus_test.rb +3 -2
  91. data/test/lib/vedeu/repositories/offsets_test.rb +26 -19
  92. data/test/lib/vedeu/repositories/positional_test.rb +50 -0
  93. data/test/lib/vedeu/support/coercions_test.rb +7 -3
  94. data/test/lib/vedeu/support/colour_translator_test.rb +6 -2
  95. data/test/lib/vedeu/support/common_test.rb +5 -3
  96. data/test/lib/vedeu/support/esc_test.rb +6 -2
  97. data/test/lib/vedeu/support/event_test.rb +6 -2
  98. data/test/lib/vedeu/support/grid_test.rb +9 -3
  99. data/test/lib/vedeu/support/keymap_validator_test.rb +5 -2
  100. data/test/lib/vedeu/support/log_test.rb +4 -2
  101. data/test/lib/vedeu/support/menu_test.rb +10 -2
  102. data/test/lib/vedeu/support/position_test.rb +10 -2
  103. data/test/lib/vedeu/support/presentation_test.rb +6 -3
  104. data/test/lib/vedeu/{output → support}/refresh_test.rb +6 -2
  105. data/test/lib/vedeu/support/registrar_test.rb +2 -2
  106. data/test/lib/vedeu/support/repository_test.rb +4 -3
  107. data/test/lib/vedeu/support/terminal_test.rb +6 -2
  108. data/test/lib/vedeu/support/trace_test.rb +17 -2
  109. data/test/lib/vedeu_test.rb +1 -1
  110. data/vedeu.gemspec +2 -2
  111. metadata +13 -13
  112. data/lib/vedeu/output/area.rb +0 -284
  113. data/lib/vedeu/support/move.rb +0 -50
  114. data/test/lib/vedeu/output/area_test.rb +0 -242
  115. data/test/lib/vedeu/support/move_test.rb +0 -35
@@ -34,7 +34,7 @@ module Vedeu
34
34
  #
35
35
  # @return [Hash]
36
36
  def foreground_codes
37
- codes
37
+ Esc.codes
38
38
  end
39
39
 
40
40
  end # Foreground
@@ -95,8 +95,6 @@ module Vedeu
95
95
  # Returns an escape sequence to position the cursor at the top-left
96
96
  # coordinate, relative to the interface's position.
97
97
  #
98
- # @todo I think this method belongs with Area.
99
- #
100
98
  # @param index [Fixnum]
101
99
  # @param block [Proc]
102
100
  # @return [String]
@@ -117,6 +115,7 @@ module Vedeu
117
115
 
118
116
  end
119
117
  end
118
+ alias_method :y_min, :top
120
119
 
121
120
  # Returns the row above the top by default.
122
121
  #
@@ -146,6 +145,7 @@ module Vedeu
146
145
 
147
146
  end
148
147
  end
148
+ alias_method :x_min, :left
149
149
 
150
150
  # Returns the column before left by default.
151
151
  #
@@ -210,8 +210,6 @@ module Vedeu
210
210
 
211
211
  # Provides a virtual y position within the interface's dimensions.
212
212
  #
213
- # @todo I think this method belongs with Area.
214
- #
215
213
  # @example
216
214
  # # top = 3
217
215
  # # bottom = 6
@@ -224,8 +222,6 @@ module Vedeu
224
222
 
225
223
  # Provides a virtual x position within the interface's dimensions.
226
224
  #
227
- # @todo I think this method belongs with Area.
228
- #
229
225
  # @example
230
226
  # # left = 9
231
227
  # # right = 13
@@ -236,6 +232,56 @@ module Vedeu
236
232
  (left...right).to_a
237
233
  end
238
234
 
235
+ # Returns the actual position of y for a given index. Crudely corrects out
236
+ # of range values.
237
+ #
238
+ # @example
239
+ # # y_range = [7, 8, 9, 10, 11]
240
+ # y_position # => 7
241
+ # y_position(-2) # => 7
242
+ # y_position(2) # => 9
243
+ # y_position(7) # => 11
244
+ #
245
+ # @param index [Fixnum]
246
+ # @return [Fixnum]
247
+ def y_position(index = 0)
248
+ if index <= 0
249
+ y_min
250
+
251
+ elsif index >= y_max_index
252
+ y_max
253
+
254
+ else
255
+ y_range[index]
256
+
257
+ end
258
+ end
259
+
260
+ # Returns the actual position of x for a given index. Crudely corrects out
261
+ # of range values.
262
+ #
263
+ # @example
264
+ # # x_range = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
265
+ # x_position # => 4
266
+ # x_position(-2) # => 4
267
+ # x_position(2) # => 6
268
+ # x_position(15) # => 13
269
+ #
270
+ # @param index [Fixnum]
271
+ # @return [Fixnum]
272
+ def x_position(index = 0)
273
+ if index <= 0
274
+ x_min
275
+
276
+ elsif index >= x_max_index
277
+ x_max
278
+
279
+ else
280
+ x_range[index]
281
+
282
+ end
283
+ end
284
+
239
285
  # Provides all the geometry in a convenient hash.
240
286
  #
241
287
  # @return [Hash]
@@ -261,6 +307,170 @@ module Vedeu
261
307
 
262
308
  private
263
309
 
310
+ # Returns the y coordinate as an offset index in the area's y range. When a
311
+ # value is provided, the y coordinate is overridden. Crudely corrects out of
312
+ # range values.
313
+ #
314
+ # @example
315
+ # # y_range = [7, 8, 9, 10]
316
+ # # y = 8
317
+ # y_index # => 1
318
+ # y_index(10) # => 3
319
+ # y_index(5) # => 0
320
+ # y_index(15) # => 3
321
+ #
322
+ # @param value [Fixnum]
323
+ # @return [Fixnum]
324
+ def y_index(value = y)
325
+ if height <= 0 || value <= y_min
326
+ 0
327
+
328
+ elsif value >= y_max
329
+ y_max_index
330
+
331
+ else
332
+ y_range.index(value)
333
+
334
+ end
335
+ end
336
+
337
+ # Returns the x coordinate as an offset index in the area's x range. When a
338
+ # value is provided, the x coordinate is overridden. Crudely corrects out of
339
+ # range values.
340
+ #
341
+ # @example
342
+ # # x_range = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
343
+ # # x = 8
344
+ # x_index # => 4
345
+ # x_index(11) # => 7
346
+ # x_index(2) # => 0
347
+ # x_index(15) # => 9
348
+ #
349
+ # @param value [Fixnum]
350
+ # @return [Fixnum]
351
+ def x_index(value = x)
352
+ if width <= 0 || value <= x_min
353
+ 0
354
+
355
+ elsif value >= x_max
356
+ x_max_index
357
+
358
+ else
359
+ x_range.index(value)
360
+
361
+ end
362
+ end
363
+
364
+ # Returns the maximum y index for an area.
365
+ #
366
+ # @example
367
+ # # height = 3
368
+ # y_max_index # => 2
369
+ #
370
+ # @return [Fixnum]
371
+ def y_max_index
372
+ return 0 if y_indices.empty?
373
+
374
+ y_indices.last
375
+ end
376
+
377
+ # Returns the maximum x index for an area.
378
+ #
379
+ # @example
380
+ # # width = 6
381
+ # x_max_index # => 5
382
+ #
383
+ # @return [Fixnum]
384
+ def x_max_index
385
+ return 0 if x_indices.empty?
386
+
387
+ x_indices.last
388
+ end
389
+
390
+ # Returns the same as #y_range, except as indices of an array.
391
+ #
392
+ # @example
393
+ # # height = 4
394
+ # y_indices # => [0, 1, 2, 3]
395
+ #
396
+ # @return [Array]
397
+ def y_indices
398
+ (0...height).to_a
399
+ end
400
+
401
+ # Returns the same as #x_range, except as indices of an array.
402
+ #
403
+ # @example
404
+ # # width = 10
405
+ # x_indices # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
406
+ #
407
+ # @return [Array]
408
+ def x_indices
409
+ (0...width).to_a
410
+ end
411
+
412
+ # Returns an array with all coordinates from x to x_max.
413
+ #
414
+ # @example
415
+ # # width = 10
416
+ # # x_min = 4
417
+ # # x_max = 14
418
+ # x_range # => [4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
419
+ #
420
+ # @return [Array]
421
+ def x_range
422
+ (x_min...x_max).to_a
423
+ end
424
+
425
+ # Returns an array with all coordinates from y to y_max.
426
+ #
427
+ # @example
428
+ # # height = 4
429
+ # # y_min = 7
430
+ # # y_max = 11
431
+ # y_range # => [7, 8, 9, 10]
432
+ #
433
+ # @return [Array]
434
+ def y_range
435
+ (y_min...y_max).to_a
436
+ end
437
+
438
+ # Returns the maximum y coordinate for an area.
439
+ #
440
+ # @example
441
+ # # y_min = 2
442
+ # # height = 4
443
+ # y_max # => 6
444
+ #
445
+ # @return [Fixnum]
446
+ def y_max
447
+ if height <= 0
448
+ 0
449
+
450
+ else
451
+ y_min + height
452
+
453
+ end
454
+ end
455
+
456
+ # Returns the maximum x coordinate for an area.
457
+ #
458
+ # @example
459
+ # # x_min = 5
460
+ # # width = 20
461
+ # x_max # => 25
462
+ #
463
+ # @return [Fixnum]
464
+ def x_max
465
+ if width <= 0
466
+ 0
467
+
468
+ else
469
+ x_min + width
470
+
471
+ end
472
+ end
473
+
264
474
  # The default geometry of an interface- full screen.
265
475
  #
266
476
  # @return [Hash]
@@ -43,9 +43,10 @@ module Vedeu
43
43
  def initialize(attributes = {}, &block)
44
44
  @attributes = defaults.merge!(attributes)
45
45
 
46
- @name = @attributes[:name]
47
- @group = @attributes[:group]
46
+ @cursor = @attributes[:cursor]
48
47
  @delay = @attributes[:delay]
48
+ @group = @attributes[:group]
49
+ @name = @attributes[:name]
49
50
  @parent = @attributes[:parent]
50
51
 
51
52
  if block_given?
@@ -71,9 +72,10 @@ module Vedeu
71
72
  # @return [Cursor]
72
73
  def cursor
73
74
  @_cursor ||= Cursor.new({
74
- name: name,
75
- x: area.x_position(offset.x),
76
- y: area.y_position(offset.y),
75
+ name: name,
76
+ state: attributes[:cursor],
77
+ x: geometry.x_position(offset.x),
78
+ y: geometry.y_position(offset.y),
77
79
  })
78
80
  end
79
81
 
@@ -115,24 +117,20 @@ module Vedeu
115
117
 
116
118
  private
117
119
 
118
- # @return [Area]
119
- def area
120
- @_area ||= Area.from_interface(self)
121
- end
122
-
123
120
  # The default values for a new instance of Interface.
124
121
  #
125
122
  # @return [Hash]
126
123
  def defaults
127
124
  {
128
- name: '',
129
- group: '',
130
- lines: [],
131
125
  colour: {},
132
- style: '',
133
- geometry: {},
126
+ cursor: :hide,
134
127
  delay: 0.0,
128
+ geometry: {},
129
+ group: '',
130
+ lines: [],
131
+ name: '',
135
132
  parent: nil,
133
+ style: '',
136
134
  }
137
135
  end
138
136
 
@@ -141,7 +139,7 @@ module Vedeu
141
139
  # @param block [Proc] The optional block provided to the method.
142
140
  # @return []
143
141
  def method_missing(method, *args, &block)
144
- Vedeu.log("Interface#method_missing '#{method.to_s}' (args: #{args.inspect})")
142
+ Vedeu.log("Interface#method_missing '#{method}' (args: #{args.inspect})")
145
143
 
146
144
  @self_before_instance_eval.send(method, *args, &block) if @self_before_instance_eval
147
145
  end
@@ -10,12 +10,44 @@ module Vedeu
10
10
 
11
11
  attr_reader :attributes
12
12
 
13
+ # Define actions for keypresses for when specific interfaces are in focus.
14
+ # Unless an interface is specified, the key will be assumed to be global,
15
+ # meaning its action will happen regardless of the interface in focus.
16
+ #
17
+ # @param name_or_names [String] The name or names of the interface(s) which
18
+ # will handle these keys.
19
+ # @param block [Proc]
20
+ #
21
+ # @example
22
+ # keys do # => will be global
23
+ # key('s') { :something }
24
+ # ...
25
+ #
26
+ # keys 'my_interface' do # => will only function when 'my_interface'
27
+ # ... # is in focus
28
+ #
29
+ # keys('main', 'other') do # => will function for both 'main' and
30
+ # ... # 'other' interfaces
31
+ #
32
+ # keys do
33
+ # interface 'my_interface' # => will only function when 'my_interface'
34
+ # ... # is in focus
35
+ #
36
+ # @raise [InvalidSyntax] When the required block is not given.
37
+ # @return [Keymap]
38
+ def self.keys(*name_or_names, &block)
39
+ fail InvalidSyntax, '`keys` requires a block.' unless block_given?
40
+
41
+ define({ interfaces: name_or_names }, &block)
42
+ end
43
+
13
44
  # Define a keymap for an interface or interfaces to perform an action when
14
45
  # a key is pressed whilst an aforementioned interface is in focus.
15
46
  #
16
47
  # @param attributes [Hash] The attributes to register the keymap with.
17
- # @option attributes :interfaces []
18
- # @option attributes :keys []
48
+ # @option attributes :interfaces [] the interface(s) which will respond to
49
+ # the keypress(es)
50
+ # @option attributes :keys [] the keypress/action pairs for this keymap
19
51
  # @param block [Proc]
20
52
  # @return [Keymap]
21
53
  def self.define(attributes = {}, &block)
@@ -33,7 +65,7 @@ module Vedeu
33
65
  # Adds the attributes to the Keymaps repository.
34
66
  #
35
67
  # @param block [Proc]
36
- # @return [Interface]
68
+ # @return [Keymap]
37
69
  def define(&block)
38
70
  if block_given?
39
71
  @self_before_instance_eval = eval('self', block.binding)
@@ -53,8 +85,8 @@ module Vedeu
53
85
  # @return [Hash]
54
86
  def defaults
55
87
  {
56
- interfaces: [], # the interface(s) which will respond to the keypress(es)
57
- keys: [], # the keypress/action pairs for this keymap
88
+ interfaces: [],
89
+ keys: [],
58
90
  }
59
91
  end
60
92
 
@@ -63,7 +95,7 @@ module Vedeu
63
95
  # @param block [Proc] The optional block provided to the method.
64
96
  # @return []
65
97
  def method_missing(method, *args, &block)
66
- Vedeu.log("Keymap#method_missing '#{method.to_s}' (args: #{args.inspect})")
98
+ Vedeu.log("Keymap#method_missing '#{method}' (args: #{args.inspect})")
67
99
 
68
100
  @self_before_instance_eval.send(method, *args, &block) if @self_before_instance_eval
69
101
  end
@@ -90,7 +90,7 @@ module Vedeu
90
90
  # @param block [Proc] The optional block provided to the method.
91
91
  # @return []
92
92
  def method_missing(method, *args, &block)
93
- Vedeu.log("Line#method_missing '#{method.to_s}' (args: #{args.inspect})")
93
+ Vedeu.log("Line#method_missing '#{method}' (args: #{args.inspect})")
94
94
 
95
95
  @self_before_instance_eval.send(method, *args, &block) if @self_before_instance_eval
96
96
  end
@@ -120,7 +120,7 @@ module Vedeu
120
120
  # @param block [Proc] The optional block provided to the method.
121
121
  # @return []
122
122
  def method_missing(method, *args, &block)
123
- Vedeu.log("Stream#method_missing '#{method.to_s}' (args: #{args.inspect})")
123
+ Vedeu.log("Stream#method_missing '#{method}' (args: #{args.inspect})")
124
124
 
125
125
  @self_before_instance_eval.send(method, *args, &block) if @self_before_instance_eval
126
126
  end
@@ -68,7 +68,7 @@ module Vedeu
68
68
 
69
69
  # Returns the attributes of the latest buffer (view).
70
70
  #
71
- # @return [Hash]
71
+ # @return [Hash|NilClass]
72
72
  def buffer
73
73
  @_buffer ||= Vedeu::Buffers.latest(name)
74
74
  end