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
@@ -1,6 +1,12 @@
1
1
  module Vedeu
2
+
3
+ # Contains all the logic of an event. Handles debouncing and throttling.
4
+ #
5
+ # @api private
2
6
  class Event
3
7
 
8
+ # Returns a new instance of Event.
9
+ #
4
10
  # @param closure [Proc]
5
11
  # @param options [Hash]
6
12
  # @return [Event]
@@ -12,6 +18,8 @@ module Vedeu
12
18
  @now = 0
13
19
  end
14
20
 
21
+ # Triggers the event based on debouncing and throttling conditions.
22
+ #
15
23
  # @param args [Array]
16
24
  # @return []
17
25
  def trigger(*args)
@@ -27,6 +35,8 @@ module Vedeu
27
35
  attr_reader :closure
28
36
  attr_accessor :deadline, :executed_at, :now
29
37
 
38
+ # Execute the code stored in the event closure.
39
+ #
30
40
  # @api private
31
41
  # @return []
32
42
  def execute(*args)
@@ -39,6 +49,10 @@ module Vedeu
39
49
  closure.call(*args)
40
50
  end
41
51
 
52
+ # Returns a boolean indicating whether throttling is required for this
53
+ # event. Setting the delay option to any value greater than 0 will enable
54
+ # throttling.
55
+ #
42
56
  # @api private
43
57
  # @return [TrueClass|FalseClass]
44
58
  def throttling?
@@ -47,6 +61,10 @@ module Vedeu
47
61
  options[:delay] > 0
48
62
  end
49
63
 
64
+ # Returns a boolean indicating whether debouncing is required for this
65
+ # event. Setting the debounce option to any value greater than 0 will
66
+ # enable debouncing.
67
+ #
50
68
  # @api private
51
69
  # @return [TrueClass|FalseClass]
52
70
  def debouncing?
@@ -104,13 +122,13 @@ module Vedeu
104
122
  # @api private
105
123
  # @return [Fixnum|Float]
106
124
  def debounce
107
- options[:debounce]
125
+ options[:debounce] || defaults[:debounce]
108
126
  end
109
127
 
110
128
  # @api private
111
129
  # @return [Fixnum|Float]
112
130
  def delay
113
- options[:delay]
131
+ options[:delay] || defaults[:delay]
114
132
  end
115
133
 
116
134
  # @api private
@@ -123,8 +141,8 @@ module Vedeu
123
141
  # @return [Hash]
124
142
  def defaults
125
143
  {
126
- delay: 0,
127
- debounce: 0
144
+ delay: 0.0,
145
+ debounce: 0.0
128
146
  }
129
147
  end
130
148
 
@@ -1,3 +1,5 @@
1
+ # Monkey-patch Ruby's Fixnum to provide a columns method.
2
+ # TODO: Don't monkey-patch because it is naughty.
1
3
  class Fixnum
2
4
 
3
5
  # Augment Fixnum to calculate column width in a grid-based layout.
@@ -12,15 +14,20 @@ class Fixnum
12
14
  # # Terminal is 92 characters wide, maximum value is
13
15
  # # therefore 84, meaning a column is 7 characters wide.
14
16
  def columns
15
- Vedeu::Grid.columns(self)
17
+ Vedeu::Grid.columns(self)
16
18
  end
17
19
  end
18
20
 
19
21
  module Vedeu
22
+
23
+ # Divides horizontal terminal space into 12 equal columns, discarding
24
+ # the remainder.
25
+ #
26
+ # @api private
20
27
  class Grid
21
28
 
22
29
  # @param value [Fixnum]
23
- # @return []
30
+ # @return [Fixnum]
24
31
  def self.columns(value)
25
32
  new(value).columns
26
33
  end
@@ -31,7 +38,7 @@ module Vedeu
31
38
  @value = value
32
39
  end
33
40
 
34
- # @return []
41
+ # @return [Fixnum|OutOfRange]
35
42
  def columns
36
43
  fail OutOfRange, 'Valid range is 1..12.' if out_of_range?
37
44
 
@@ -2,6 +2,7 @@ require 'fileutils'
2
2
  require 'time'
3
3
 
4
4
  module Vedeu
5
+ # :nocov:
5
6
  class MonoLogger < Logger
6
7
  # Create a trappable Logger instance.
7
8
  #
@@ -27,7 +28,11 @@ module Vedeu
27
28
  end
28
29
  end
29
30
 
31
+ # Ensures we can always write to the log file by creating a lock-less
32
+ # log device.
30
33
  class LocklessLogDevice < LogDevice
34
+
35
+ # @return []
31
36
  def initialize(log = nil)
32
37
  @dev = @filename = @shift_age = @shift_size = nil
33
38
  if log.respond_to?(:write) and log.respond_to?(:close)
@@ -39,18 +44,21 @@ module Vedeu
39
44
  end
40
45
  end
41
46
 
47
+ # @return []
42
48
  def write(message)
43
49
  @dev.write(message)
44
50
  rescue Exception => ignored
45
51
  warn("log writing failed. #{ignored}")
46
52
  end
47
53
 
54
+ # @return []
48
55
  def close
49
56
  @dev.close rescue nil
50
57
  end
51
58
 
52
- private
59
+ private
53
60
 
61
+ # @return []
54
62
  def open_logfile(filename)
55
63
  if (FileTest.exist?(filename))
56
64
  open(filename, (File::WRONLY | File::APPEND))
@@ -59,6 +67,7 @@ module Vedeu
59
67
  end
60
68
  end
61
69
 
70
+ # @return []
62
71
  def create_logfile(filename)
63
72
  logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT))
64
73
  logdev.sync = true
@@ -66,6 +75,7 @@ module Vedeu
66
75
  logdev
67
76
  end
68
77
 
78
+ # @return []
69
79
  def add_log_header(file)
70
80
  file.write(
71
81
  "# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName]
@@ -74,6 +84,8 @@ module Vedeu
74
84
  end
75
85
  end
76
86
 
87
+ # Provides the ability to Log anything to the Vedeu log file which is
88
+ # hard-coded to reside in `$HOME/.vedeu/vedeu.log`.
77
89
  class Log
78
90
 
79
91
  # @return [TrueClass]
@@ -108,4 +120,5 @@ module Vedeu
108
120
  end
109
121
 
110
122
  end
123
+ # :nocov:
111
124
  end
@@ -1,6 +1,12 @@
1
1
  module Vedeu
2
+
3
+ # Converts the collection passed into a list of menu items which can be
4
+ # navigated using the instance methods or events provided.
5
+ #
2
6
  class Menu
3
7
 
8
+ # Returns a new instance of Menu.
9
+ #
4
10
  # @param collection []
5
11
  # @return [Menu]
6
12
  def initialize(collection)
@@ -10,6 +16,8 @@ module Vedeu
10
16
  @events = events
11
17
  end
12
18
 
19
+ # Creates events to manipulate this menu.
20
+ #
13
21
  # @return []
14
22
  def events
15
23
  @_events ||= Vedeu.events.add(self) do
@@ -26,28 +34,41 @@ module Vedeu
26
34
  end
27
35
  end
28
36
 
29
- # @return []
37
+ # Returns the index of the value in the collection which is current.
38
+ #
39
+ # @return [Fixnum]
30
40
  def current
31
41
  @current
32
42
  end
33
43
 
34
- # @return []
44
+ # Returns the index of the value in the collection which is selected.
45
+ #
46
+ # @return [Fixnum]
35
47
  def selected
36
48
  @selected
37
49
  end
38
50
 
51
+ # Returns the item from the collection which shares the same index as the
52
+ # value of {Vedeu::Menu#current}.
53
+ #
39
54
  # @return []
40
55
  def current_item
41
56
  @collection[@current]
42
57
  end
43
58
 
44
- # @return []
59
+ # Returns the item from the collection which shares the same index as the
60
+ # value of {Vedeu::Menu#selected}.
61
+ #
62
+ # @return [|NilClass]
45
63
  def selected_item
46
64
  return nil unless @selected
47
65
 
48
66
  @collection[@selected]
49
67
  end
50
68
 
69
+ # Returns a new collection of items, which includes the `current` and
70
+ # `selected` states.
71
+ #
51
72
  # @return [Array]
52
73
  def items
53
74
  items = []
@@ -69,59 +90,77 @@ module Vedeu
69
90
  items
70
91
  end
71
92
 
72
- # @return []
93
+ # @return [Array]
73
94
  def view
74
95
  items[@current, @collection.size]
75
96
  end
76
97
 
77
- # @return []
98
+ # Sets the value of current to be the first item of the collection.
99
+ #
100
+ # @return [Array]
78
101
  def top_item
79
102
  @current = 0
80
103
 
81
104
  items
82
105
  end
83
106
 
84
- # @return []
107
+ # Sets the value of current to be the last item of the collection.
108
+ #
109
+ # @return [Array]
85
110
  def bottom_item
86
111
  @current = last
87
112
 
88
113
  items
89
114
  end
90
115
 
91
- # @return []
116
+ # Sets the value of current to be the next item in the collection until we
117
+ # reach the last.
118
+ #
119
+ # @return [Array]
92
120
  def next_item
93
121
  @current += 1 if @current < last
94
122
 
95
123
  items
96
124
  end
97
125
 
98
- # @return []
126
+ # Sets the value of current to be the previous item in the collection until
127
+ # we reach the first.
128
+ #
129
+ # @return [Array]
99
130
  def prev_item
100
131
  @current -= 1 if @current > 0
101
132
 
102
133
  items
103
134
  end
104
135
 
105
- # @return []
136
+ # Sets the selected item to be the same value as the current item.
137
+ #
138
+ # @return [Array]
106
139
  def select_item
107
140
  @selected = @current
108
141
 
109
142
  items
110
143
  end
111
144
 
112
- # @return []
145
+ # Removes the value of `selected`, meaning no items are selected.
146
+ #
147
+ # @return [Array]
113
148
  def deselect_item
114
149
  @selected = nil
115
150
 
116
151
  items
117
152
  end
118
153
 
119
- # @return []
154
+ # Returns the last index of the collection.
155
+ #
156
+ # @return [Fixnum]
120
157
  def last
121
158
  @collection.size - 1
122
159
  end
123
160
 
124
- # @return []
161
+ # Returns the size of the collection.
162
+ #
163
+ # @return [Fixnum]
125
164
  def size
126
165
  @collection.size
127
166
  end
@@ -1,6 +1,12 @@
1
1
  module Vedeu
2
+
3
+ # Change coordinates into an escape sequence to set the cursor position.
4
+ #
5
+ # @api private
2
6
  class Position
3
7
 
8
+ # Initializes a new instance of Position.
9
+ #
4
10
  # @param y [Fixnum]
5
11
  # @param x [Fixnum]
6
12
  # @return [Position]
@@ -8,6 +14,9 @@ module Vedeu
8
14
  @y, @x = y, x
9
15
  end
10
16
 
17
+ # Returns an escape sequence to position the cursor. When passed a block,
18
+ # will position the cursor, yield and return the original position.
19
+ #
11
20
  # @param block [Proc]
12
21
  # @return [String]
13
22
  def to_s(&block)
@@ -1,10 +1,18 @@
1
1
  module Vedeu
2
+
3
+ # This module is the direct interface between Vedeu and your terminal/
4
+ # console, via Ruby's IO core library.
5
+ #
6
+ # @api private
2
7
  module Terminal
3
8
 
4
9
  extend self
5
10
 
11
+ # Opens a terminal screen in either `raw` or `cooked` mode. On exit,
12
+ # attempts to restore the screen. See {Vedeu::Terminal#restore_screen}.
13
+ #
6
14
  # @param block [Proc]
7
- # @return []
15
+ # @return [Array]
8
16
  def open(&block)
9
17
  fail InvalidSyntax, '`open` requires a block.' unless block_given?
10
18
 
@@ -20,7 +28,11 @@ module Vedeu
20
28
 
21
29
  end
22
30
 
31
+ # Takes input from the user via the keyboard. Accepts special keys like
32
+ # the F-Keys etc, by capturing the entire sequence.
33
+ #
23
34
  # @return [String]
35
+ # :nocov:
24
36
  def input
25
37
  if raw_mode?
26
38
  keys = console.getch
@@ -35,13 +47,16 @@ module Vedeu
35
47
 
36
48
  end
37
49
  end
50
+ # :nocov:
38
51
 
39
- # @param stream [String]
40
- # @return [String]
41
- def output(stream = '')
42
- console.print(stream)
52
+ # Prints the streams to the screen and returns the streams.
53
+ #
54
+ # @param streams [String|Array]
55
+ # @return [Array]
56
+ def output(*streams)
57
+ streams.each { |stream| console.print(stream) }
43
58
 
44
- stream
59
+ streams
45
60
  end
46
61
 
47
62
  # @param block [Proc]
@@ -52,42 +67,64 @@ module Vedeu
52
67
  yield
53
68
  end
54
69
 
70
+ # Clears the entire terminal space.
71
+ #
55
72
  # @return [String]
56
73
  def clear_screen
57
74
  output Esc.string 'clear'
58
75
  end
59
76
 
77
+ # Attempts to tidy up the screen just before the application terminates.
78
+ # The cursor is shown, colours are reset to terminal defaults, the
79
+ # terminal is told to reset, and finally we clear the last line ready for
80
+ # the prompt.
81
+ #
60
82
  # @return [String]
61
83
  def restore_screen
62
- output Esc.string 'screen_exit'
63
- output clear_last_line
84
+ output(Esc.string('screen_exit'), Esc.string('clear_last_line'))
64
85
  end
65
86
 
87
+ # Sets the cursor to be visible unless in raw mode, whereby it will be left
88
+ # hidden.
89
+ #
66
90
  # @return [String]
67
91
  def set_cursor_mode
68
92
  output Esc.string 'show_cursor' unless raw_mode?
69
93
  end
70
94
 
95
+ # Returns a boolean indicating whether the terminal is currently in `cooked`
96
+ # mode.
97
+ #
71
98
  # @return [Boolean]
72
99
  def cooked_mode?
73
100
  mode == :cooked
74
101
  end
75
102
 
103
+ # Sets the terminal in to `cooked` mode.
104
+ #
76
105
  # @return [Symbol]
77
106
  def cooked_mode!
78
107
  @_mode = :cooked
79
108
  end
80
109
 
110
+ # Returns a boolean indicating whether the terminal is currently in `raw`
111
+ # mode.
112
+ #
81
113
  # @return [Boolean]
82
114
  def raw_mode?
83
115
  mode == :raw
84
116
  end
85
117
 
118
+ # Sets the terminal in to `raw` mode.
119
+ #
86
120
  # @return [Symbol]
87
121
  def raw_mode!
88
122
  @_mode = :raw
89
123
  end
90
124
 
125
+ # Toggles the terminal's mode between `cooked` and `raw`, depending on its
126
+ # current mode.
127
+ #
91
128
  # @return [Symbol]
92
129
  def switch_mode!
93
130
  if raw_mode?
@@ -99,11 +136,6 @@ module Vedeu
99
136
  end
100
137
  end
101
138
 
102
- # @return [String]
103
- def clear_last_line
104
- Esc.set_position((height - 1), 1) + Esc.string('clear_line')
105
- end
106
-
107
139
  # Returns the mode of the terminal, either `:raw` or `:cooked`
108
140
  #
109
141
  # @return [Symbol]
@@ -120,7 +152,7 @@ module Vedeu
120
152
  end
121
153
 
122
154
  # Returns the `y` (row/line) component of the coordinate tuple provided by
123
- # {Terminal.centre}
155
+ # {Vedeu::Terminal.centre}
124
156
  #
125
157
  # @return [Fixnum]
126
158
  def centre_y
@@ -128,7 +160,7 @@ module Vedeu
128
160
  end
129
161
 
130
162
  # Returns the `x` (column/character) component of the coodinate tuple
131
- # provided by {Terminal.centre}
163
+ # provided by {Vedeu::Terminal.centre}
132
164
  #
133
165
  # @return [Fixnum]
134
166
  def centre_x
@@ -157,6 +189,8 @@ module Vedeu
157
189
  console.winsize
158
190
  end
159
191
 
192
+ # Provides our gateway into the wonderful rainbow-filled world of IO.
193
+ #
160
194
  # @return [File]
161
195
  def console
162
196
  IO.console