vedeu 0.1.17 → 0.1.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/README.md +17 -3
- data/lib/vedeu.rb +12 -7
- data/lib/vedeu/api/api.rb +37 -13
- data/lib/vedeu/api/composition.rb +1 -6
- data/lib/vedeu/api/helpers.rb +2 -0
- data/lib/vedeu/api/interface.rb +47 -55
- data/lib/vedeu/api/line.rb +6 -0
- data/lib/vedeu/api/stream.rb +9 -1
- data/lib/vedeu/application.rb +38 -50
- data/lib/vedeu/configuration.rb +163 -44
- data/lib/vedeu/launcher.rb +3 -6
- data/lib/vedeu/models/attributes/background.rb +9 -1
- data/lib/vedeu/models/attributes/colour_translator.rb +40 -2
- data/lib/vedeu/models/attributes/foreground.rb +9 -1
- data/lib/vedeu/models/colour.rb +6 -0
- data/lib/vedeu/models/composition.rb +8 -1
- data/lib/vedeu/models/geometry.rb +27 -14
- data/lib/vedeu/models/interface.rb +59 -0
- data/lib/vedeu/models/line.rb +4 -0
- data/lib/vedeu/models/stream.rb +10 -0
- data/lib/vedeu/models/style.rb +2 -0
- data/lib/vedeu/support/buffer.rb +12 -1
- data/lib/vedeu/support/buffers.rb +10 -0
- data/lib/vedeu/support/clear.rb +4 -0
- data/lib/vedeu/support/esc.rb +26 -8
- data/lib/vedeu/support/event.rb +28 -0
- data/lib/vedeu/support/events.rb +2 -0
- data/lib/vedeu/support/focus.rb +14 -6
- data/lib/vedeu/support/grid.rb +6 -0
- data/lib/vedeu/support/groups.rb +13 -3
- data/lib/vedeu/support/input.rb +7 -2
- data/lib/vedeu/support/log.rb +7 -1
- data/lib/vedeu/support/position.rb +6 -0
- data/lib/vedeu/support/render.rb +38 -0
- data/lib/vedeu/support/terminal.rb +69 -15
- data/lib/vedeu/support/trace.rb +8 -0
- data/lib/vedeu/support/view.rb +6 -0
- data/test/integration/run_once_test.rb +26 -0
- data/test/lib/vedeu/api/api_test.rb +19 -6
- data/test/lib/vedeu/api/interface_test.rb +67 -1
- data/test/lib/vedeu/api/line_test.rb +10 -0
- data/test/lib/vedeu/api/stream_test.rb +8 -0
- data/test/lib/vedeu/configuration_test.rb +119 -12
- data/test/lib/vedeu/models/attributes/background_test.rb +1 -1
- data/test/lib/vedeu/models/attributes/foreground_test.rb +1 -1
- data/test/lib/vedeu/models/interface_test.rb +22 -0
- data/test/lib/vedeu/support/buffer_test.rb +44 -0
- data/test/lib/vedeu/support/events_test.rb +3 -9
- data/test/lib/vedeu/support/input_test.rb +1 -0
- data/test/lib/vedeu/support/terminal_test.rb +128 -5
- data/test/test_helper.rb +2 -2
- data/vedeu.gemspec +1 -1
- metadata +5 -2
data/lib/vedeu/launcher.rb
CHANGED
@@ -24,7 +24,9 @@ module Vedeu
|
|
24
24
|
def execute!
|
25
25
|
$stdin, $stdout, $stderr = @stdin, @stdout, @stderr
|
26
26
|
|
27
|
-
|
27
|
+
Configuration.configure(argv)
|
28
|
+
|
29
|
+
Application.start
|
28
30
|
|
29
31
|
@exit_code = 0
|
30
32
|
rescue StandardError => uncaught_exception
|
@@ -41,10 +43,5 @@ module Vedeu
|
|
41
43
|
|
42
44
|
attr_reader :argv
|
43
45
|
|
44
|
-
def configuration
|
45
|
-
Configuration.configure(argv)
|
46
|
-
end
|
47
|
-
# :nocov:
|
48
|
-
|
49
46
|
end
|
50
47
|
end
|
@@ -3,16 +3,22 @@ module Vedeu
|
|
3
3
|
|
4
4
|
private
|
5
5
|
|
6
|
+
# @api private
|
7
|
+
# @return [String]
|
6
8
|
def named
|
7
9
|
["\e[", background_codes[colour], "m"].join
|
8
10
|
end
|
9
11
|
|
12
|
+
# @api private
|
13
|
+
# @return [String]
|
10
14
|
def numbered
|
11
15
|
["\e[48;5;", css_to_numbered, "m"].join
|
12
16
|
end
|
13
17
|
|
18
|
+
# @api private
|
19
|
+
# @return [String]
|
14
20
|
def rgb
|
15
|
-
if
|
21
|
+
if Configuration.colour_mode == 16777216
|
16
22
|
sprintf("\e[48;2;%s;%s;%sm", *css_to_rgb)
|
17
23
|
|
18
24
|
else
|
@@ -21,6 +27,8 @@ module Vedeu
|
|
21
27
|
end
|
22
28
|
end
|
23
29
|
|
30
|
+
# @api private
|
31
|
+
# @return [Hash]
|
24
32
|
def background_codes
|
25
33
|
codes.inject({}){ |h, (k, v)| h.merge(k => v + 10) }
|
26
34
|
end
|
@@ -11,7 +11,13 @@ module Vedeu
|
|
11
11
|
# defaults, then the theme's colour will be used. The recognised names are:
|
12
12
|
# :black, :red, :green, :yellow, :blue, :magenta, :cyan, :white, :default.
|
13
13
|
#
|
14
|
-
#
|
14
|
+
# When a number between 0 and 255 is provided, Vedeu will use the terminal
|
15
|
+
# colour corresponding with that colour. TODO: Create chart.
|
16
|
+
#
|
17
|
+
# Finally, when provided a CSS/HTML colour string e.g. '#ff0000', Vedeu will
|
18
|
+
# translate that to the 8-bit escape sequence or if you have a capable
|
19
|
+
# terminal and the `VEDEU_TERM=xterm-truecolor` environment variable set,
|
20
|
+
# a 24-bit representation.
|
15
21
|
#
|
16
22
|
# @param colour [String]
|
17
23
|
# @return [String]
|
@@ -50,46 +56,68 @@ module Vedeu
|
|
50
56
|
|
51
57
|
attr_reader :colour
|
52
58
|
|
59
|
+
# @api private
|
60
|
+
# @return [TrueClass|FalseClass]
|
53
61
|
def no_colour?
|
54
62
|
colour.nil? || colour.to_s.empty?
|
55
63
|
end
|
56
64
|
|
65
|
+
# @api private
|
66
|
+
# @return [TrueClass|FalseClass]
|
57
67
|
def named?
|
58
68
|
colour.is_a?(Symbol) && valid_name?
|
59
69
|
end
|
60
70
|
|
71
|
+
# @api private
|
72
|
+
# @return [Exception]
|
61
73
|
def named
|
62
74
|
fail NotImplemented, 'Subclasses implement this.'
|
63
75
|
end
|
64
76
|
|
77
|
+
# @api private
|
78
|
+
# @return [TrueClass|FalseClass]
|
65
79
|
def valid_name?
|
66
80
|
codes.keys.include?(colour)
|
67
81
|
end
|
68
82
|
|
83
|
+
# @api private
|
84
|
+
# @return [TrueClass|FalseClass]
|
69
85
|
def numbered?
|
70
86
|
colour.is_a?(Fixnum) && valid_range?
|
71
87
|
end
|
72
88
|
|
89
|
+
# @api private
|
90
|
+
# @return [Exception]
|
73
91
|
def numbered
|
74
92
|
fail NotImplemented, 'Subclasses implement this.'
|
75
93
|
end
|
76
94
|
|
95
|
+
# @api private
|
96
|
+
# @return [TrueClass|FalseClass]
|
77
97
|
def valid_range?
|
78
98
|
colour >= 0 && colour <= 255
|
79
99
|
end
|
80
100
|
|
101
|
+
# @api private
|
102
|
+
# @return [TrueClass|FalseClass]
|
81
103
|
def rgb?
|
82
104
|
colour.is_a?(String) && valid_rgb?
|
83
105
|
end
|
84
106
|
|
107
|
+
# @api private
|
108
|
+
# @return [Exception]
|
85
109
|
def rgb
|
86
110
|
fail NotImplemented, 'Subclasses implement this.'
|
87
111
|
end
|
88
112
|
|
113
|
+
# @api private
|
114
|
+
# @return [TrueClass|FalseClass]
|
89
115
|
def valid_rgb?
|
90
|
-
colour =~ /^#([A-Fa-f0-9]{6})$/
|
116
|
+
!!(colour =~ /^#([A-Fa-f0-9]{6})$/)
|
91
117
|
end
|
92
118
|
|
119
|
+
# @api private
|
120
|
+
# @return [Array]
|
93
121
|
def css_to_rgb
|
94
122
|
[
|
95
123
|
colour[1..2].to_i(16),
|
@@ -98,6 +126,8 @@ module Vedeu
|
|
98
126
|
]
|
99
127
|
end
|
100
128
|
|
129
|
+
# @api private
|
130
|
+
# @return [Fixnum]
|
101
131
|
def css_to_numbered
|
102
132
|
if rgb?
|
103
133
|
[16, red, green, blue].inject(:+)
|
@@ -108,18 +138,26 @@ module Vedeu
|
|
108
138
|
end
|
109
139
|
end
|
110
140
|
|
141
|
+
# @api private
|
142
|
+
# @return [Fixnum]
|
111
143
|
def red
|
112
144
|
(css_to_rgb[0] / 51) * 36
|
113
145
|
end
|
114
146
|
|
147
|
+
# @api private
|
148
|
+
# @return [Fixnum]
|
115
149
|
def green
|
116
150
|
(css_to_rgb[1] / 51) * 6
|
117
151
|
end
|
118
152
|
|
153
|
+
# @api private
|
154
|
+
# @return [Fixnum]
|
119
155
|
def blue
|
120
156
|
(css_to_rgb[2] / 51) * 1
|
121
157
|
end
|
122
158
|
|
159
|
+
# @api private
|
160
|
+
# @return [Hash]
|
123
161
|
def codes
|
124
162
|
{
|
125
163
|
black: 30,
|
@@ -3,16 +3,22 @@ module Vedeu
|
|
3
3
|
|
4
4
|
private
|
5
5
|
|
6
|
+
# @api private
|
7
|
+
# @return [String]
|
6
8
|
def named
|
7
9
|
["\e[", foreground_codes[colour], "m"].join
|
8
10
|
end
|
9
11
|
|
12
|
+
# @api private
|
13
|
+
# @return [String]
|
10
14
|
def numbered
|
11
15
|
["\e[38;5;", css_to_numbered, "m"].join
|
12
16
|
end
|
13
17
|
|
18
|
+
# @api private
|
19
|
+
# @return [String]
|
14
20
|
def rgb
|
15
|
-
if
|
21
|
+
if Configuration.colour_mode == 16777216
|
16
22
|
sprintf("\e[38;2;%s;%s;%sm", *css_to_rgb)
|
17
23
|
|
18
24
|
else
|
@@ -21,6 +27,8 @@ module Vedeu
|
|
21
27
|
end
|
22
28
|
end
|
23
29
|
|
30
|
+
# @api private
|
31
|
+
# @return [Hash]
|
24
32
|
def foreground_codes
|
25
33
|
codes
|
26
34
|
end
|
data/lib/vedeu/models/colour.rb
CHANGED
@@ -3,6 +3,10 @@ module Vedeu
|
|
3
3
|
|
4
4
|
attr_reader :attributes
|
5
5
|
|
6
|
+
# Initialises a new Colour object which is a container terminal escape
|
7
|
+
# sequences controlling the foreground and background colour of a
|
8
|
+
# character or collection of characters.
|
9
|
+
#
|
6
10
|
# @param attributes [Hash]
|
7
11
|
# @return [Colour]
|
8
12
|
def initialize(attributes = {})
|
@@ -33,6 +37,8 @@ module Vedeu
|
|
33
37
|
|
34
38
|
private
|
35
39
|
|
40
|
+
# @api private
|
41
|
+
# @return [Hash]
|
36
42
|
def defaults
|
37
43
|
{
|
38
44
|
foreground: '',
|
@@ -49,7 +49,7 @@ module Vedeu
|
|
49
49
|
end
|
50
50
|
|
51
51
|
# Returns the complete escape sequence which this composition renders to.
|
52
|
-
# This is used by
|
52
|
+
# This is used by {Terminal.output} to draw the view.
|
53
53
|
#
|
54
54
|
# @return [String]
|
55
55
|
def to_s
|
@@ -58,11 +58,18 @@ module Vedeu
|
|
58
58
|
|
59
59
|
private
|
60
60
|
|
61
|
+
# @api private
|
62
|
+
# @return [Hash]
|
61
63
|
def defaults
|
62
64
|
{
|
63
65
|
interfaces: []
|
64
66
|
}
|
65
67
|
end
|
66
68
|
|
69
|
+
# @api private
|
70
|
+
def method_missing(method, *args, &block)
|
71
|
+
@self_before_instance_eval.send(method, *args, &block)
|
72
|
+
end
|
73
|
+
|
67
74
|
end
|
68
75
|
end
|
@@ -3,6 +3,9 @@ module Vedeu
|
|
3
3
|
|
4
4
|
attr_reader :attributes, :centred, :height, :width
|
5
5
|
|
6
|
+
# Calculate and provide interface geometry determined by both the client's
|
7
|
+
# requirements and the terminal's current viewing area.
|
8
|
+
#
|
6
9
|
# @param attributes [Hash]
|
7
10
|
# @return [Geometry]
|
8
11
|
def initialize(attributes = {})
|
@@ -80,6 +83,8 @@ module Vedeu
|
|
80
83
|
end
|
81
84
|
end
|
82
85
|
|
86
|
+
# Returns the top-left coordinate, relative to the interface's position.
|
87
|
+
#
|
83
88
|
# @param index [Fixnum]
|
84
89
|
# @param block [Proc]
|
85
90
|
# @return [String]
|
@@ -87,10 +92,13 @@ module Vedeu
|
|
87
92
|
Esc.set_position(virtual_y[index], left, &block)
|
88
93
|
end
|
89
94
|
|
95
|
+
# Returns a fixed or dynamic value depending on whether the interface is
|
96
|
+
# centred or not.
|
97
|
+
#
|
90
98
|
# @return [Fixnum]
|
91
99
|
def top
|
92
100
|
if centred
|
93
|
-
centre_y - (viewport_height / 2)
|
101
|
+
Terminal.centre_y - (viewport_height / 2)
|
94
102
|
|
95
103
|
else
|
96
104
|
y
|
@@ -113,10 +121,13 @@ module Vedeu
|
|
113
121
|
top - value
|
114
122
|
end
|
115
123
|
|
124
|
+
# Returns a fixed or dynamic value depending on whether the interface is
|
125
|
+
# centred or not.
|
126
|
+
#
|
116
127
|
# @return [Fixnum]
|
117
128
|
def left
|
118
129
|
if centred
|
119
|
-
centre_x - (viewport_width / 2)
|
130
|
+
Terminal.centre_x - (viewport_width / 2)
|
120
131
|
|
121
132
|
else
|
122
133
|
x
|
@@ -159,6 +170,9 @@ module Vedeu
|
|
159
170
|
bottom + value
|
160
171
|
end
|
161
172
|
|
173
|
+
# Returns a fixed or dynamic value depending on whether the interface is
|
174
|
+
# centred or not.
|
175
|
+
#
|
162
176
|
# @return [Fixnum]
|
163
177
|
def right
|
164
178
|
left + width
|
@@ -181,22 +195,21 @@ module Vedeu
|
|
181
195
|
|
182
196
|
private
|
183
197
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
centre.first
|
190
|
-
end
|
191
|
-
|
192
|
-
def centre_x
|
193
|
-
centre.last
|
198
|
+
# Provides a virtual y position within the interface's dimensions.
|
199
|
+
#
|
200
|
+
# @return [Array]
|
201
|
+
def virtual_y
|
202
|
+
(top..bottom).to_a
|
194
203
|
end
|
195
204
|
|
196
|
-
|
197
|
-
|
205
|
+
# Provides a virtual x position within the interface's dimensions.
|
206
|
+
#
|
207
|
+
# @return [Array]
|
208
|
+
def virtual_x
|
209
|
+
(left..right).to_a
|
198
210
|
end
|
199
211
|
|
212
|
+
# @return [Hash]
|
200
213
|
def defaults
|
201
214
|
{
|
202
215
|
y: 1,
|
@@ -19,6 +19,14 @@ module Vedeu
|
|
19
19
|
new(attributes, &block).attributes
|
20
20
|
end
|
21
21
|
|
22
|
+
# @see Vedeu::API#interface
|
23
|
+
# @param attributes [Hash]
|
24
|
+
# @param block [Proc]
|
25
|
+
# @return []
|
26
|
+
def self.define(attributes = {}, &block)
|
27
|
+
new(attributes).define(&block)
|
28
|
+
end
|
29
|
+
|
22
30
|
# @param attributes [Hash]
|
23
31
|
# @param block [Proc]
|
24
32
|
# @return [Interface]
|
@@ -36,6 +44,30 @@ module Vedeu
|
|
36
44
|
end
|
37
45
|
end
|
38
46
|
|
47
|
+
# @see Vedeu::API#interface
|
48
|
+
# @param block [Proc]
|
49
|
+
#
|
50
|
+
# @example
|
51
|
+
# TODO
|
52
|
+
#
|
53
|
+
# @return []
|
54
|
+
def define(&block)
|
55
|
+
instance_eval(&block) if block_given?
|
56
|
+
|
57
|
+
if attributes[:name].nil? || attributes[:name].empty?
|
58
|
+
fail InvalidSyntax, 'Interfaces and views must have a `name`.'
|
59
|
+
end
|
60
|
+
|
61
|
+
Vedeu::Buffers.create(attributes)
|
62
|
+
|
63
|
+
Vedeu.event("_refresh_#{attributes[:name]}_".to_sym,
|
64
|
+
{ delay: attributes[:delay] }) do
|
65
|
+
Vedeu::Buffers.refresh(attributes[:name])
|
66
|
+
end
|
67
|
+
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
39
71
|
# @return [Array]
|
40
72
|
def lines
|
41
73
|
@lines ||= Line.coercer(attributes[:lines])
|
@@ -69,6 +101,8 @@ module Vedeu
|
|
69
101
|
|
70
102
|
private
|
71
103
|
|
104
|
+
# @api private
|
105
|
+
# @return [Hash]
|
72
106
|
def defaults
|
73
107
|
{
|
74
108
|
name: '',
|
@@ -82,5 +116,30 @@ module Vedeu
|
|
82
116
|
}
|
83
117
|
end
|
84
118
|
|
119
|
+
# @api private
|
120
|
+
# @return [String]
|
121
|
+
def out_of_bounds(name)
|
122
|
+
"Note: For this terminal, the value of '#{name}' may lead to content " \
|
123
|
+
"that is outside the viewable area."
|
124
|
+
end
|
125
|
+
|
126
|
+
# @api private
|
127
|
+
# @return [TrueClass|FalseClass]
|
128
|
+
def y_out_of_bounds?(value)
|
129
|
+
value < 1 || value > Terminal.height
|
130
|
+
end
|
131
|
+
|
132
|
+
# @api private
|
133
|
+
# @return [TrueClass|FalseClass]
|
134
|
+
def x_out_of_bounds?(value)
|
135
|
+
value < 1 || value > Terminal.width
|
136
|
+
end
|
137
|
+
|
138
|
+
# @api private
|
139
|
+
# @return []
|
140
|
+
def method_missing(method, *args, &block)
|
141
|
+
@self_before_instance_eval.send(method, *args, &block)
|
142
|
+
end
|
143
|
+
|
85
144
|
end
|
86
145
|
end
|
data/lib/vedeu/models/line.rb
CHANGED
@@ -37,6 +37,8 @@ module Vedeu
|
|
37
37
|
|
38
38
|
private
|
39
39
|
|
40
|
+
# @api private
|
41
|
+
# @return [Hash]
|
40
42
|
def defaults
|
41
43
|
{
|
42
44
|
colour: {},
|
@@ -45,6 +47,8 @@ module Vedeu
|
|
45
47
|
}
|
46
48
|
end
|
47
49
|
|
50
|
+
# @api private
|
51
|
+
# @return []
|
48
52
|
def method_missing(method, *args, &block)
|
49
53
|
@self_before_instance_eval.send(method, *args, &block)
|
50
54
|
end
|