vedeu 0.1.18 → 0.1.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +5 -0
- data/Dockerfile +40 -0
- data/README.md +7 -30
- data/docs/api.md +79 -0
- data/docs/events.md +121 -0
- data/lib/vedeu.rb +61 -18
- data/lib/vedeu/api/api.rb +73 -53
- data/lib/vedeu/api/composition.rb +4 -1
- data/lib/vedeu/api/defined.rb +35 -0
- data/lib/vedeu/api/helpers.rb +20 -15
- data/lib/vedeu/api/interface.rb +17 -12
- data/lib/vedeu/api/line.rb +20 -12
- data/lib/vedeu/api/stream.rb +3 -0
- data/lib/vedeu/application.rb +34 -1
- data/lib/vedeu/configuration.rb +15 -3
- data/lib/vedeu/input/input.rb +77 -0
- data/lib/vedeu/launcher.rb +7 -0
- data/lib/vedeu/models/attributes/background.rb +15 -2
- data/lib/vedeu/models/attributes/coercions.rb +18 -3
- data/lib/vedeu/models/attributes/colour_translator.rb +23 -17
- data/lib/vedeu/models/attributes/foreground.rb +10 -2
- data/lib/vedeu/models/attributes/presentation.rb +62 -0
- data/lib/vedeu/models/colour.rb +7 -3
- data/lib/vedeu/models/composition.rb +17 -19
- data/lib/vedeu/models/geometry.rb +13 -5
- data/lib/vedeu/models/interface.rb +35 -19
- data/lib/vedeu/models/line.rb +24 -8
- data/lib/vedeu/models/stream.rb +13 -7
- data/lib/vedeu/models/style.rb +17 -7
- data/lib/vedeu/{support → output}/clear.rb +14 -0
- data/lib/vedeu/output/compositor.rb +77 -0
- data/lib/vedeu/output/refresh.rb +129 -0
- data/lib/vedeu/{support → output}/render.rb +49 -13
- data/lib/vedeu/{support → output}/view.rb +15 -8
- data/lib/vedeu/repositories/buffers.rb +181 -0
- data/lib/vedeu/{support → repositories}/events.rb +16 -6
- data/lib/vedeu/repositories/focus.rb +109 -0
- data/lib/vedeu/repositories/groups.rb +76 -0
- data/lib/vedeu/repositories/interfaces.rb +74 -0
- data/lib/vedeu/support/common.rb +20 -0
- data/lib/vedeu/support/cursor.rb +77 -0
- data/lib/vedeu/support/esc.rb +181 -46
- data/lib/vedeu/support/event.rb +22 -4
- data/lib/vedeu/support/grid.rb +10 -3
- data/lib/vedeu/support/log.rb +14 -1
- data/lib/vedeu/support/menu.rb +51 -12
- data/lib/vedeu/support/position.rb +9 -0
- data/lib/vedeu/support/terminal.rb +49 -15
- data/lib/vedeu/support/trace.rb +11 -4
- data/test/integration/defining_interfaces_test.rb +27 -0
- data/test/integration/views/basic_view_test.rb +767 -0
- data/test/lib/vedeu/api/api_test.rb +32 -37
- data/test/lib/vedeu/api/composition_test.rb +23 -61
- data/test/lib/vedeu/api/defined_test.rb +49 -0
- data/test/lib/vedeu/api/helpers_test.rb +91 -0
- data/test/lib/vedeu/api/interface_test.rb +136 -688
- data/test/lib/vedeu/api/line_test.rb +28 -32
- data/test/lib/vedeu/application_test.rb +6 -0
- data/test/lib/vedeu/configuration_test.rb +8 -4
- data/test/lib/vedeu/{support → input}/input_test.rb +9 -0
- data/test/lib/vedeu/launcher_test.rb +6 -0
- data/test/lib/vedeu/models/attributes/{coercer_test.rb → coercions_test.rb} +11 -10
- data/test/lib/vedeu/models/attributes/colour_translator_test.rb +13 -0
- data/test/lib/vedeu/models/attributes/presentation_test.rb +30 -0
- data/test/lib/vedeu/models/colour_test.rb +8 -0
- data/test/lib/vedeu/models/composition_test.rb +208 -200
- data/test/lib/vedeu/models/geometry_test.rb +39 -0
- data/test/lib/vedeu/models/interface_test.rb +11 -1
- data/test/lib/vedeu/models/line_test.rb +8 -1
- data/test/lib/vedeu/models/stream_test.rb +35 -0
- data/test/lib/vedeu/models/style_test.rb +8 -0
- data/test/lib/vedeu/{support → output}/clear_test.rb +1 -1
- data/test/lib/vedeu/output/compositor_test.rb +64 -0
- data/test/lib/vedeu/output/refresh_test.rb +48 -0
- data/test/lib/vedeu/{support → output}/render_test.rb +36 -0
- data/test/lib/vedeu/{support → output}/view_test.rb +0 -0
- data/test/lib/vedeu/repositories/buffers_test.rb +48 -0
- data/test/lib/vedeu/{support → repositories}/events_test.rb +0 -0
- data/test/lib/vedeu/repositories/focus_test.rb +74 -0
- data/test/lib/vedeu/repositories/groups_test.rb +66 -0
- data/test/lib/vedeu/repositories/interfaces_test.rb +6 -0
- data/test/lib/vedeu/support/common_test.rb +6 -0
- data/test/lib/vedeu/support/cursor_test.rb +79 -0
- data/test/lib/vedeu/support/log_test.rb +6 -0
- data/test/lib/vedeu/support/terminal_test.rb +6 -28
- data/test/lib/vedeu/support/trace_test.rb +6 -0
- data/test/test_helper.rb +37 -0
- data/vedeu.gemspec +1 -1
- metadata +65 -33
- data/bin/log +0 -13
- data/lib/vedeu/support/buffer.rb +0 -69
- data/lib/vedeu/support/buffers.rb +0 -106
- data/lib/vedeu/support/focus.rb +0 -83
- data/lib/vedeu/support/groups.rb +0 -61
- data/lib/vedeu/support/input.rb +0 -67
- data/test/lib/vedeu/support/buffer_test.rb +0 -83
- data/test/lib/vedeu/support/buffers_test.rb +0 -15
- data/test/lib/vedeu/support/focus_test.rb +0 -114
- data/test/lib/vedeu/support/groups_test.rb +0 -65
@@ -0,0 +1,77 @@
|
|
1
|
+
module Vedeu
|
2
|
+
|
3
|
+
# Captures input from the user via {Vedeu::Terminal#input} and translates
|
4
|
+
# special characters into symbols.
|
5
|
+
#
|
6
|
+
# @api private
|
7
|
+
class Input
|
8
|
+
|
9
|
+
# @return [String|Symbol]
|
10
|
+
def self.capture
|
11
|
+
new.capture
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns a new instance of Input.
|
15
|
+
#
|
16
|
+
# @return [Input]
|
17
|
+
def initialize; end
|
18
|
+
|
19
|
+
# @return []
|
20
|
+
def capture
|
21
|
+
Vedeu.trigger(:_keypress_, keypress)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# @api private
|
27
|
+
# @return [String]
|
28
|
+
def input
|
29
|
+
@_input ||= Terminal.input
|
30
|
+
end
|
31
|
+
|
32
|
+
# @api private
|
33
|
+
# @return [String|Symbol]
|
34
|
+
def keypress
|
35
|
+
key = input
|
36
|
+
|
37
|
+
specials.fetch(key, key)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @api private
|
41
|
+
# @return [Hash]
|
42
|
+
def specials
|
43
|
+
{
|
44
|
+
"\r" => :enter,
|
45
|
+
"\t" => :tab,
|
46
|
+
"\e" => :escape,
|
47
|
+
"\e[A" => :up,
|
48
|
+
"\e[B" => :down,
|
49
|
+
"\e[C" => :right,
|
50
|
+
"\e[D" => :left,
|
51
|
+
"\e[5~" => :page_up,
|
52
|
+
"\e[6~" => :page_down,
|
53
|
+
"\e[H" => :home,
|
54
|
+
"\e[3~" => :delete,
|
55
|
+
"\e[F" => :end,
|
56
|
+
"\e[Z" => :shift_tab,
|
57
|
+
"\eOP" => :f1,
|
58
|
+
"\eOQ" => :f2,
|
59
|
+
"\eOR" => :f3,
|
60
|
+
"\eOS" => :f4,
|
61
|
+
"\e[15~" => :f5,
|
62
|
+
"\e[17~" => :f6,
|
63
|
+
"\e[18~" => :f7,
|
64
|
+
"\e[19~" => :f8,
|
65
|
+
"\e[20~" => :f9,
|
66
|
+
"\e[21~" => :f10,
|
67
|
+
"\e[23~" => :f11,
|
68
|
+
"\e[24~" => :f12,
|
69
|
+
"\e[1;2P" => :print_screen,
|
70
|
+
"\e[1;2Q" => :scroll_lock,
|
71
|
+
"\e[1;2R" => :pause_break,
|
72
|
+
"\u007F" => :backspace,
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
data/lib/vedeu/launcher.rb
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
module Vedeu
|
2
|
+
|
3
|
+
# This class ensures that STDIN, STDOUT and STDERR point to the correct
|
4
|
+
# places. It also handles the initial configuration of the application,
|
5
|
+
# the starting of the application, the handling of uncaught exceptions and
|
6
|
+
# finally the exiting of the application with the correct exit code.
|
7
|
+
#
|
8
|
+
# @api public
|
2
9
|
class Launcher
|
3
10
|
|
4
11
|
# :nocov:
|
@@ -1,18 +1,28 @@
|
|
1
1
|
module Vedeu
|
2
|
+
|
3
|
+
# The class represents one half (the other, can be found at
|
4
|
+
# {Vedeu::Foreground}) of a terminal colour escape sequence.
|
5
|
+
#
|
6
|
+
# @api private
|
2
7
|
class Background < ColourTranslator
|
3
8
|
|
4
9
|
private
|
5
10
|
|
11
|
+
# Returns an escape sequence for a named background colour.
|
12
|
+
#
|
13
|
+
# Valid names are: `:black`, `:red`, `:green`, `:yellow`, `:blue`,
|
14
|
+
# `:magenta`, `:cyan`, `:white` and `:default`.
|
15
|
+
#
|
6
16
|
# @api private
|
7
17
|
# @return [String]
|
8
18
|
def named
|
9
|
-
["\e[", background_codes[colour],
|
19
|
+
["\e[", background_codes[colour], 'm'].join
|
10
20
|
end
|
11
21
|
|
12
22
|
# @api private
|
13
23
|
# @return [String]
|
14
24
|
def numbered
|
15
|
-
["\e[48;5;", css_to_numbered,
|
25
|
+
["\e[48;5;", css_to_numbered, 'm'].join
|
16
26
|
end
|
17
27
|
|
18
28
|
# @api private
|
@@ -27,6 +37,9 @@ module Vedeu
|
|
27
37
|
end
|
28
38
|
end
|
29
39
|
|
40
|
+
# Produces the background named colour escape sequence hash from the
|
41
|
+
# foreground escape sequence hash.
|
42
|
+
#
|
30
43
|
# @api private
|
31
44
|
# @return [Hash]
|
32
45
|
def background_codes
|
@@ -1,27 +1,42 @@
|
|
1
1
|
module Vedeu
|
2
|
+
|
3
|
+
# Provides means to convert attributes into the correct model.
|
4
|
+
#
|
5
|
+
# @api private
|
2
6
|
module Coercions
|
7
|
+
|
8
|
+
# Contains class methods which are accessible as such to classes and modules
|
9
|
+
# which include {Vedeu::Coercions}.
|
3
10
|
module ClassMethods
|
4
11
|
|
12
|
+
include Vedeu::Common
|
13
|
+
|
5
14
|
# Produces new objects of the correct class from attributes hashes,
|
6
15
|
# ignores objects that have already been coerced.
|
16
|
+
# When provided with a parent argument, will allow the new object
|
17
|
+
# to know the colour and style of its parent.
|
7
18
|
#
|
8
19
|
# @param values [Array|Hash]
|
20
|
+
# @param parent [Hash|Nil]
|
9
21
|
# @return [Array]
|
10
|
-
def coercer(values)
|
11
|
-
return []
|
22
|
+
def coercer(values, parent = nil)
|
23
|
+
return [] unless defined_value?(values)
|
12
24
|
|
13
25
|
[values].flatten.map do |value|
|
14
26
|
if value.is_a?(self)
|
15
27
|
value
|
16
28
|
|
17
29
|
else
|
18
|
-
self.new(value)
|
30
|
+
self.new(value.merge!({ parent: parent }))
|
19
31
|
|
20
32
|
end
|
21
33
|
end
|
22
34
|
end
|
23
35
|
end
|
24
36
|
|
37
|
+
# Whenever this module {Vedeu::Coercions} is included in another class or
|
38
|
+
# module, make its methods into class methods, so they may be called
|
39
|
+
# directly.
|
25
40
|
def self.included(receiver)
|
26
41
|
receiver.extend(ClassMethods)
|
27
42
|
end
|
@@ -1,30 +1,36 @@
|
|
1
1
|
module Vedeu
|
2
|
+
|
3
|
+
# Convert a CSS/HTML colour string into a terminal escape sequence.
|
4
|
+
#
|
5
|
+
# If provided with an empty value or a string it cannot convert, it will
|
6
|
+
# return an empty string.
|
7
|
+
#
|
8
|
+
# When provided with a named colour, uses the terminal's value for that
|
9
|
+
# colour. If a theme is being used with the terminal, which overrides the
|
10
|
+
# defaults, then the theme's colour will be used. The recognised names are:
|
11
|
+
# :black, :red, :green, :yellow, :blue, :magenta, :cyan, :white, :default.
|
12
|
+
#
|
13
|
+
# When a number between 0 and 255 is provided, Vedeu will use the terminal
|
14
|
+
# colour corresponding with that colour. TODO: Create chart.
|
15
|
+
#
|
16
|
+
# Finally, when provided a CSS/HTML colour string e.g. '#ff0000', Vedeu will
|
17
|
+
# translate that to the 8-bit escape sequence or if you have a capable
|
18
|
+
# terminal and the `VEDEU_TERM=xterm-truecolor` environment variable set,
|
19
|
+
# a 24-bit representation.
|
20
|
+
#
|
21
|
+
# @api private
|
2
22
|
class ColourTranslator
|
3
23
|
|
4
24
|
# Convert a CSS/HTML colour string into a terminal escape sequence.
|
5
25
|
#
|
6
|
-
# If provided with an empty value or a string it cannot convert, it will
|
7
|
-
# return an empty string.
|
8
|
-
#
|
9
|
-
# When provided with a named colour, uses the terminal's value for that
|
10
|
-
# colour. If a theme is being used with the terminal, which overrides the
|
11
|
-
# defaults, then the theme's colour will be used. The recognised names are:
|
12
|
-
# :black, :red, :green, :yellow, :blue, :magenta, :cyan, :white, :default.
|
13
|
-
#
|
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.
|
21
|
-
#
|
22
26
|
# @param colour [String]
|
23
27
|
# @return [String]
|
24
28
|
def self.escape_sequence(colour = '')
|
25
29
|
new(colour).escape_sequence
|
26
30
|
end
|
27
31
|
|
32
|
+
# Return a new instance of ColourTranslator.
|
33
|
+
#
|
28
34
|
# @param colour [String]
|
29
35
|
# @return [ColourTranslator]
|
30
36
|
def initialize(colour = '')
|
@@ -32,7 +38,7 @@ module Vedeu
|
|
32
38
|
end
|
33
39
|
|
34
40
|
# @return [String]
|
35
|
-
# @see Vedeu::ColourTranslator
|
41
|
+
# @see Vedeu::ColourTranslator
|
36
42
|
def escape_sequence
|
37
43
|
if no_colour?
|
38
44
|
''
|
@@ -1,4 +1,9 @@
|
|
1
1
|
module Vedeu
|
2
|
+
|
3
|
+
# The class represents one half (the other, can be found at
|
4
|
+
# {Vedeu::Background}) of a terminal colour escape sequence.
|
5
|
+
#
|
6
|
+
# @api private
|
2
7
|
class Foreground < ColourTranslator
|
3
8
|
|
4
9
|
private
|
@@ -6,13 +11,13 @@ module Vedeu
|
|
6
11
|
# @api private
|
7
12
|
# @return [String]
|
8
13
|
def named
|
9
|
-
["\e[", foreground_codes[colour],
|
14
|
+
["\e[", foreground_codes[colour], 'm'].join
|
10
15
|
end
|
11
16
|
|
12
17
|
# @api private
|
13
18
|
# @return [String]
|
14
19
|
def numbered
|
15
|
-
["\e[38;5;", css_to_numbered,
|
20
|
+
["\e[38;5;", css_to_numbered, 'm'].join
|
16
21
|
end
|
17
22
|
|
18
23
|
# @api private
|
@@ -27,6 +32,9 @@ module Vedeu
|
|
27
32
|
end
|
28
33
|
end
|
29
34
|
|
35
|
+
# Produces the foreground named colour escape sequence hash from
|
36
|
+
# {Vedeu::ColourTranslator#codes}
|
37
|
+
#
|
30
38
|
# @api private
|
31
39
|
# @return [Hash]
|
32
40
|
def foreground_codes
|
@@ -1,15 +1,77 @@
|
|
1
1
|
module Vedeu
|
2
|
+
|
3
|
+
# This module allows the sharing of presentation concerns between the models:
|
4
|
+
# Interface, Line and Stream.
|
5
|
+
#
|
6
|
+
# @api private
|
2
7
|
module Presentation
|
3
8
|
|
9
|
+
# Returns the colour attributes of the receiving class.
|
10
|
+
#
|
11
|
+
# @return [Hash]
|
12
|
+
def view_attributes
|
13
|
+
{
|
14
|
+
colour: attributes[:colour],
|
15
|
+
style: attributes[:style],
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns a new Colour instance.
|
20
|
+
#
|
4
21
|
# @return [Colour]
|
5
22
|
def colour
|
6
23
|
@colour ||= Colour.new(attributes[:colour])
|
7
24
|
end
|
8
25
|
|
26
|
+
# Returns a new Style instance.
|
27
|
+
#
|
9
28
|
# @return [Style]
|
10
29
|
def style
|
11
30
|
@style ||= Style.new(attributes[:style])
|
12
31
|
end
|
13
32
|
|
33
|
+
# Converts the colours and styles to escape sequences, and if the parent
|
34
|
+
# model has previously set the colour and style, reverts back to that for
|
35
|
+
# consistent formatting.
|
36
|
+
#
|
37
|
+
# @return [String]
|
38
|
+
def to_s
|
39
|
+
render_colour do
|
40
|
+
render_style do
|
41
|
+
data
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# @api private
|
49
|
+
# @return [String]
|
50
|
+
def render_colour(&block)
|
51
|
+
[ colour.to_s, yield, parent_colour ].join
|
52
|
+
end
|
53
|
+
|
54
|
+
# @api private
|
55
|
+
# @return [String]
|
56
|
+
def render_style(&block)
|
57
|
+
[ style.to_s, yield, parent_style ].join
|
58
|
+
end
|
59
|
+
|
60
|
+
# @api private
|
61
|
+
# @return [String]
|
62
|
+
def parent_colour
|
63
|
+
return '' if parent.nil?
|
64
|
+
|
65
|
+
Colour.new(parent[:colour]).to_s
|
66
|
+
end
|
67
|
+
|
68
|
+
# @api private
|
69
|
+
# @return [String]
|
70
|
+
def parent_style
|
71
|
+
return '' if parent.nil?
|
72
|
+
|
73
|
+
Style.new(parent[:style]).to_s
|
74
|
+
end
|
75
|
+
|
14
76
|
end
|
15
77
|
end
|
data/lib/vedeu/models/colour.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
module Vedeu
|
2
|
+
|
3
|
+
# Provides a container for terminal escape sequences controlling the
|
4
|
+
# foreground and background colours of a character or collection of
|
5
|
+
# characters.
|
6
|
+
#
|
7
|
+
# @api private
|
2
8
|
class Colour
|
3
9
|
|
4
10
|
attr_reader :attributes
|
5
11
|
|
6
|
-
#
|
7
|
-
# sequences controlling the foreground and background colour of a
|
8
|
-
# character or collection of characters.
|
12
|
+
# Returns a new instance of Colour.
|
9
13
|
#
|
10
14
|
# @param attributes [Hash]
|
11
15
|
# @return [Colour]
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module Vedeu
|
2
|
+
|
3
|
+
# A composition is a collection of interfaces.
|
2
4
|
class Composition
|
3
5
|
|
4
6
|
attr_reader :attributes
|
5
7
|
|
6
|
-
# Builds a new composition,
|
7
|
-
# rendered to the screen.
|
8
|
+
# Builds a new composition, ready to be rendered to the screen.
|
8
9
|
#
|
9
10
|
# @param attributes [Hash]
|
10
11
|
# @param block [Proc]
|
@@ -13,6 +14,8 @@ module Vedeu
|
|
13
14
|
new(attributes, &block).attributes
|
14
15
|
end
|
15
16
|
|
17
|
+
# Returns a new instance of Composition.
|
18
|
+
#
|
16
19
|
# @param attributes [Hash]
|
17
20
|
# @param block [Proc]
|
18
21
|
# @return [Composition]
|
@@ -26,30 +29,23 @@ module Vedeu
|
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
29
|
-
# Returns a collection of
|
30
|
-
# composition.
|
32
|
+
# Returns a collection of interfaces associated with this composition.
|
31
33
|
#
|
32
34
|
# @return [Array]
|
33
35
|
def interfaces
|
34
|
-
@interfaces ||=
|
35
|
-
|
36
|
-
|
37
|
-
else
|
38
|
-
[ attributes[:interfaces] ].flatten.map do |attrs|
|
39
|
-
stored = Buffers.retrieve_attributes(attrs[:name])
|
40
|
-
|
41
|
-
combined = stored.merge(attrs) do |key, s, a|
|
42
|
-
key == :lines && s.empty? ? a : s
|
43
|
-
end
|
44
|
-
|
45
|
-
Interface.new(combined)
|
46
|
-
end
|
36
|
+
@interfaces ||= Interface.coercer(attributes[:interfaces])
|
37
|
+
end
|
47
38
|
|
48
|
-
|
39
|
+
# Returns the view attributes for a Composition, which will always be none,
|
40
|
+
# as a composition is a merely a collection of interfaces.
|
41
|
+
#
|
42
|
+
# @return [Hash]
|
43
|
+
def view_attributes
|
44
|
+
{}
|
49
45
|
end
|
50
46
|
|
51
47
|
# Returns the complete escape sequence which this composition renders to.
|
52
|
-
# This is used by {Terminal.output} to draw the view.
|
48
|
+
# This is used by {Vedeu::Terminal.output} to draw the view.
|
53
49
|
#
|
54
50
|
# @return [String]
|
55
51
|
def to_s
|
@@ -58,6 +54,8 @@ module Vedeu
|
|
58
54
|
|
59
55
|
private
|
60
56
|
|
57
|
+
# The default values for a new instance of Composition.
|
58
|
+
#
|
61
59
|
# @api private
|
62
60
|
# @return [Hash]
|
63
61
|
def defaults
|