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.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/README.md +1 -2
- data/Rakefile +5 -5
- data/bin/vedeu +8 -4
- data/docs/api.md +3 -1
- data/docs/events.md +43 -29
- data/docs/getting_started.md +2 -0
- data/examples/cursor_app/cursor_app.rb +85 -0
- data/examples/lines_app/lines_app.rb +60 -0
- data/lib/vedeu.rb +9 -3
- data/lib/vedeu/api/api.rb +28 -7
- data/lib/vedeu/api/composition.rb +2 -0
- data/lib/vedeu/api/helpers.rb +2 -0
- data/lib/vedeu/api/interface.rb +2 -20
- data/lib/vedeu/api/keymap.rb +2 -0
- data/lib/vedeu/api/line.rb +2 -0
- data/lib/vedeu/api/menu.rb +3 -1
- data/lib/vedeu/api/stream.rb +25 -2
- data/lib/vedeu/application.rb +4 -4
- data/lib/vedeu/configuration/api.rb +327 -0
- data/lib/vedeu/configuration/cli.rb +110 -0
- data/lib/vedeu/{configuration.rb → configuration/configuration.rb} +49 -99
- data/lib/vedeu/launcher.rb +0 -1
- data/lib/vedeu/models/attributes/colour_translator.rb +2 -2
- data/lib/vedeu/models/colour.rb +0 -1
- data/lib/vedeu/models/composition.rb +2 -8
- data/lib/vedeu/models/cursor.rb +261 -0
- data/lib/vedeu/models/geometry.rb +11 -19
- data/lib/vedeu/models/interface.rb +2 -12
- data/lib/vedeu/models/keymap.rb +2 -0
- data/lib/vedeu/models/line.rb +2 -0
- data/lib/vedeu/models/stream.rb +2 -0
- data/lib/vedeu/models/style.rb +2 -0
- data/lib/vedeu/output/clear.rb +0 -1
- data/lib/vedeu/output/compositor.rb +0 -1
- data/lib/vedeu/output/refresh.rb +3 -0
- data/lib/vedeu/output/render.rb +12 -6
- data/lib/vedeu/output/view.rb +1 -0
- data/lib/vedeu/repositories/cursors.rb +98 -0
- data/lib/vedeu/repositories/events.rb +0 -1
- data/lib/vedeu/repositories/focus.rb +18 -0
- data/lib/vedeu/repositories/menus.rb +4 -4
- data/lib/vedeu/support/common.rb +2 -1
- data/lib/vedeu/support/event.rb +1 -10
- data/lib/vedeu/support/grid.rb +1 -2
- data/lib/vedeu/{repositories → support}/keymap_validator.rb +5 -4
- data/lib/vedeu/support/log.rb +3 -0
- data/lib/vedeu/support/menu.rb +4 -1
- data/lib/vedeu/support/registrar.rb +2 -1
- data/test/integration/defining_interfaces_test.rb +0 -1
- data/test/integration/views/basic_view_test.rb +741 -739
- data/test/lib/vedeu/api/api_test.rb +14 -3
- data/test/lib/vedeu/api/helpers_test.rb +3 -3
- data/test/lib/vedeu/api/interface_test.rb +17 -70
- data/test/lib/vedeu/api/keymap_test.rb +2 -0
- data/test/lib/vedeu/api/line_test.rb +4 -4
- data/test/lib/vedeu/api/menu_test.rb +6 -5
- data/test/lib/vedeu/api/stream_test.rb +18 -0
- data/test/lib/vedeu/configuration/api_test.rb +248 -0
- data/test/lib/vedeu/configuration/cli_test.rb +88 -0
- data/test/lib/vedeu/configuration/configuration_test.rb +67 -0
- data/test/lib/vedeu/input/input_test.rb +2 -2
- data/test/lib/vedeu/models/attributes/background_test.rb +3 -3
- data/test/lib/vedeu/models/attributes/foreground_test.rb +3 -3
- data/test/lib/vedeu/models/composition_test.rb +0 -222
- data/test/lib/vedeu/models/cursor_test.rb +164 -0
- data/test/lib/vedeu/models/interface_test.rb +0 -11
- data/test/lib/vedeu/output/compositor_test.rb +2 -4
- data/test/lib/vedeu/output/render_test.rb +4 -41
- data/test/lib/vedeu/repositories/cursors_test.rb +13 -0
- data/test/lib/vedeu/repositories/focus_test.rb +14 -4
- data/test/lib/vedeu/repositories/menus_test.rb +36 -29
- data/test/lib/vedeu/{repositories → support}/keymap_validator_test.rb +0 -0
- data/test/lib/vedeu/support/menu_test.rb +3 -3
- data/test/lib/vedeu/support/registrar_test.rb +6 -0
- data/test/lib/vedeu/support/terminal_test.rb +2 -2
- data/test/test_helper.rb +1 -1
- data/vedeu.gemspec +1 -1
- metadata +23 -14
- data/elements.txt +0 -118
- data/lib/vedeu/support/cursor.rb +0 -96
- data/test/lib/vedeu/configuration_test.rb +0 -154
- data/test/lib/vedeu/support/cursor_test.rb +0 -79
- 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
|
-
#
|
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
|
-
|
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
|
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
|
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
|
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
|
194
|
-
#
|
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
|
}
|
data/lib/vedeu/models/keymap.rb
CHANGED
data/lib/vedeu/models/line.rb
CHANGED
data/lib/vedeu/models/stream.rb
CHANGED
data/lib/vedeu/models/style.rb
CHANGED
data/lib/vedeu/output/clear.rb
CHANGED
data/lib/vedeu/output/refresh.rb
CHANGED
data/lib/vedeu/output/render.rb
CHANGED
@@ -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
|
59
|
+
return [] unless visible_lines.any? { |line| line.streams.any? }
|
62
60
|
|
63
|
-
|
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
|
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
|
158
|
+
interface.lines
|
153
159
|
end
|
154
160
|
|
155
161
|
# Provides the currently available height of the interface.
|
data/lib/vedeu/output/view.rb
CHANGED
@@ -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
|
@@ -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
|
95
|
+
# @return [Vedeu::Menu]
|
94
96
|
def use(name)
|
95
|
-
find(name).fetch(:items)
|
96
|
-
fail MenuNotFound, "This menu '#{name}' has no items."
|
97
|
-
end
|
97
|
+
find(name).fetch(:items)
|
98
98
|
end
|
99
99
|
|
100
100
|
private
|
data/lib/vedeu/support/common.rb
CHANGED
@@ -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
|
data/lib/vedeu/support/event.rb
CHANGED
@@ -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
|
#
|
data/lib/vedeu/support/grid.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Monkey-patch Ruby's Fixnum to provide a columns method.
|
2
|
-
#
|
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,
|
35
|
+
[false, fail_message(key) + ' by the system.']
|
35
36
|
|
36
37
|
elsif global_key?(key)
|
37
|
-
[false,
|
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,
|
42
|
+
[false, fail_message(key) + ' by this interface.']
|
42
43
|
|
43
44
|
else
|
44
|
-
[false,
|
45
|
+
[false, fail_message(key) + ' by another interface and therefore ' \
|
45
46
|
'cannot be global.']
|
46
47
|
|
47
48
|
end
|