vedeu 0.4.59 → 0.4.60
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +0 -2
- data/LICENSE.txt +4 -1
- data/README.md +12 -6
- data/Rakefile +0 -1
- data/docs/api.md +13 -13
- data/docs/dsl.md +10 -1
- data/docs/events.md +0 -1
- data/docs/getting_started.md +175 -17
- data/lib/vedeu/all.rb +5 -0
- data/lib/vedeu/api.rb +19 -0
- data/lib/vedeu/bindings/drb.rb +4 -0
- data/lib/vedeu/bindings/menus.rb +14 -10
- data/lib/vedeu/bootstrap.rb +44 -17
- data/lib/vedeu/colours/escape_sequences.rb +125 -0
- data/lib/vedeu/distributed/server.rb +43 -35
- data/lib/vedeu/dsl/view.rb +110 -7
- data/lib/vedeu/exceptions.rb +6 -0
- data/lib/vedeu/models/menus.rb +1 -0
- data/lib/vedeu/null/menu.rb +38 -0
- data/lib/vedeu/output/esc.rb +1 -96
- data/lib/vedeu/plugins.rb +82 -0
- data/lib/vedeu/plugins/plugin.rb +53 -0
- data/lib/vedeu/version.rb +1 -1
- data/test/lib/vedeu/api_test.rb +4 -0
- data/test/lib/vedeu/colours/escape_sequences_test.rb +100 -0
- data/test/lib/vedeu/null/menu_test.rb +47 -0
- data/test/lib/vedeu/output/esc_test.rb +0 -87
- data/test/lib/vedeu/plugins/plugin_test.rb +32 -0
- data/test/lib/vedeu/plugins_test.rb +47 -0
- metadata +14 -4
- data/docs/applications.md +0 -167
- data/docs/views.md +0 -158
data/lib/vedeu/exceptions.rb
CHANGED
data/lib/vedeu/models/menus.rb
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Vedeu
|
2
|
+
|
3
|
+
module Null
|
4
|
+
|
5
|
+
# Provides a non-existent model to swallow messages.
|
6
|
+
#
|
7
|
+
class Menu
|
8
|
+
|
9
|
+
# Returns an instance of the Vedeu::Null::Menu class.
|
10
|
+
#
|
11
|
+
# @param attributes [Hash<Symbol => void>]
|
12
|
+
# @option attributes name [String|NilClass]
|
13
|
+
# @return [Vedeu::Null::Menu]
|
14
|
+
def initialize(attributes = {})
|
15
|
+
@attributes = attributes
|
16
|
+
@name = @attributes[:name]
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [NilClass]
|
20
|
+
def item
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
alias_method :bottom_item, :item
|
24
|
+
alias_method :current_item, :item
|
25
|
+
alias_method :deselect_item, :item
|
26
|
+
alias_method :items, :item
|
27
|
+
alias_method :next_item, :item
|
28
|
+
alias_method :prev_item, :item
|
29
|
+
alias_method :select_item, :item
|
30
|
+
alias_method :selected_item, :item
|
31
|
+
alias_method :top_item, :item
|
32
|
+
alias_method :view, :item
|
33
|
+
|
34
|
+
end # Menu
|
35
|
+
|
36
|
+
end # Null
|
37
|
+
|
38
|
+
end # Vedeu
|
data/lib/vedeu/output/esc.rb
CHANGED
@@ -5,103 +5,9 @@ module Vedeu
|
|
5
5
|
#
|
6
6
|
module Esc
|
7
7
|
|
8
|
+
include Vedeu::EscapeSequences
|
8
9
|
extend self
|
9
10
|
|
10
|
-
# Produces the foreground named colour escape sequence hash. The background
|
11
|
-
# escape sequences are also generated from this by adding 10 to the values.
|
12
|
-
# This hash gives rise to methods you can call directly on `Esc` to produce
|
13
|
-
# the desired colours:
|
14
|
-
#
|
15
|
-
# @example
|
16
|
-
# Esc.red # => "\e[31m"
|
17
|
-
#
|
18
|
-
# Esc.red { 'some text' } # => "\e[31msome text\e[39m"
|
19
|
-
#
|
20
|
-
# Esc.on_blue # => "\e[44m"
|
21
|
-
#
|
22
|
-
# Esc.on_blue { 'some text' } # => "\e[44msome text\e[49m"
|
23
|
-
#
|
24
|
-
# # Valid names:
|
25
|
-
# :black, :red, :green, :yellow, :blue, :magenta, :cyan, :light_grey,
|
26
|
-
# :default, :dark_grey, :light_red, :light_green, :light_yellow,
|
27
|
-
# :light_blue, :light_magenta, :light_cyan, :white
|
28
|
-
#
|
29
|
-
# @return [Hash<Symbol => Fixnum>]
|
30
|
-
def codes
|
31
|
-
{
|
32
|
-
black: 30,
|
33
|
-
red: 31,
|
34
|
-
green: 32,
|
35
|
-
yellow: 33,
|
36
|
-
blue: 34,
|
37
|
-
magenta: 35,
|
38
|
-
cyan: 36,
|
39
|
-
light_grey: 37,
|
40
|
-
default: 39,
|
41
|
-
dark_grey: 90,
|
42
|
-
light_red: 91,
|
43
|
-
light_green: 92,
|
44
|
-
light_yellow: 93,
|
45
|
-
light_blue: 94,
|
46
|
-
light_magenta: 95,
|
47
|
-
light_cyan: 96,
|
48
|
-
white: 97,
|
49
|
-
}
|
50
|
-
end
|
51
|
-
alias_method :foreground_codes, :codes
|
52
|
-
|
53
|
-
# Produces the background named colour escape sequence hash from the
|
54
|
-
# foreground escape sequence hash.
|
55
|
-
#
|
56
|
-
# @return [Hash<Symbol => Fixnum>]
|
57
|
-
def background_codes
|
58
|
-
hash = {}
|
59
|
-
Vedeu::Esc.codes.inject(hash) do |h, (k, v)|
|
60
|
-
h.merge!(k => v + 10)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# Dynamically creates methods for each terminal named colour. When a block
|
65
|
-
# is given, then the colour is reset to 'default' once the block is called.
|
66
|
-
#
|
67
|
-
# @return [String]
|
68
|
-
foreground_codes.each do |key, code|
|
69
|
-
define_method(key) do |&blk|
|
70
|
-
"\e[#{code}m" + (blk ? blk.call + "\e[39m" : '')
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
background_codes.each do |key, code|
|
75
|
-
define_method('on_' + key.to_s) do |&blk|
|
76
|
-
"\e[#{code}m" + (blk ? blk.call + "\e[49m" : '')
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# @return [Hash<Symbol => String>]
|
81
|
-
def actions
|
82
|
-
{
|
83
|
-
hide_cursor: "\e[?25l",
|
84
|
-
show_cursor: "\e[?25h",
|
85
|
-
cursor_position: "\e[6n",
|
86
|
-
bg_reset: "\e[49m",
|
87
|
-
blink: "\e[5m",
|
88
|
-
blink_off: "\e[25m",
|
89
|
-
bold: "\e[1m",
|
90
|
-
bold_off: "\e[22m",
|
91
|
-
border_on: "\e(0",
|
92
|
-
border_off: "\e(B",
|
93
|
-
dim: "\e[2m",
|
94
|
-
fg_reset: "\e[39m",
|
95
|
-
negative: "\e[7m",
|
96
|
-
positive: "\e[27m",
|
97
|
-
reset: "\e[0m",
|
98
|
-
underline: "\e[4m",
|
99
|
-
underline_off: "\e[24m",
|
100
|
-
}
|
101
|
-
end
|
102
|
-
|
103
|
-
actions.each { |key, code| define_method(key) { code } }
|
104
|
-
|
105
11
|
# Return the stream with the escape sequences escaped so that they can be
|
106
12
|
# printed to the terminal instead of being interpreted by the terminal which
|
107
13
|
# will render them. This way we can see what escape sequences are being sent
|
@@ -124,7 +30,6 @@ module Vedeu
|
|
124
30
|
return '' if value.empty?
|
125
31
|
|
126
32
|
send(value.to_sym)
|
127
|
-
|
128
33
|
rescue NoMethodError
|
129
34
|
''
|
130
35
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Vedeu
|
2
|
+
|
3
|
+
# A class responsible for managing plugins installation.
|
4
|
+
#
|
5
|
+
class Plugins
|
6
|
+
|
7
|
+
# Returns a new instance of Vedeu::Plugins.
|
8
|
+
#
|
9
|
+
# @return [Vedeu::Plugins]
|
10
|
+
def initialize
|
11
|
+
@plugins = []
|
12
|
+
end
|
13
|
+
|
14
|
+
# Loads all plugins that are not enabled.
|
15
|
+
#
|
16
|
+
# @return [void]
|
17
|
+
def load
|
18
|
+
plugins.each do |plugin|
|
19
|
+
plugin.load! unless plugin.enabled?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Register plugin with name in an internal array.
|
24
|
+
#
|
25
|
+
# @param name [String]
|
26
|
+
# @param plugin [Vedeu::Plugin]
|
27
|
+
# @return [void]
|
28
|
+
def register(name, plugin = false)
|
29
|
+
if plugin && !loaded?(name)
|
30
|
+
plugins << plugin
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Find all installed plugins and store them.
|
35
|
+
#
|
36
|
+
# @return [void]
|
37
|
+
def find
|
38
|
+
Gem.refresh
|
39
|
+
|
40
|
+
Gem::Specification.each do |gem|
|
41
|
+
next unless gem.name =~ /^#{prefix}/
|
42
|
+
plugin_name = gem.name[/^#{prefix}-(.*)/, 1]
|
43
|
+
register(plugin_name, Plugin.new(plugin_name, gem))
|
44
|
+
end
|
45
|
+
|
46
|
+
plugins
|
47
|
+
end
|
48
|
+
|
49
|
+
# Return a list of all plugin names as strings.
|
50
|
+
#
|
51
|
+
# @return [void]
|
52
|
+
def names
|
53
|
+
plugins.reduce({}) do |hash, plugin|
|
54
|
+
hash[plugin.name] = plugin
|
55
|
+
hash
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
protected
|
60
|
+
|
61
|
+
# @!attribute [r] input
|
62
|
+
# @return [Array<String>]
|
63
|
+
attr_accessor :plugins
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# Returns a boolean indicating whether a plugin is already loaded.
|
68
|
+
#
|
69
|
+
# @param name [String]
|
70
|
+
# @return [Boolean]
|
71
|
+
def loaded?(name)
|
72
|
+
plugins.any? { |plugin| plugin.gem_name == name }
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [String]
|
76
|
+
def prefix
|
77
|
+
'vedeu'
|
78
|
+
end
|
79
|
+
|
80
|
+
end # Plugins
|
81
|
+
|
82
|
+
end # Vedeu
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Vedeu
|
2
|
+
|
3
|
+
# A class responsible for plugin loading.
|
4
|
+
#
|
5
|
+
class Plugin
|
6
|
+
|
7
|
+
# @!attribute [r] name
|
8
|
+
# @return [String]
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
# @!attribute [r] gem
|
12
|
+
# @return [String]
|
13
|
+
attr_reader :gem
|
14
|
+
|
15
|
+
# @!attribute [r] gem_name
|
16
|
+
# @return [String]
|
17
|
+
attr_reader :gem_name
|
18
|
+
|
19
|
+
# @!attribute [rw] enabled
|
20
|
+
# @return [Boolean]
|
21
|
+
attr_accessor :enabled
|
22
|
+
alias_method :enabled?, :enabled
|
23
|
+
|
24
|
+
# Returns a new instance of Vedeu::Plugin.
|
25
|
+
#
|
26
|
+
# @param name [String] The plugin name.
|
27
|
+
# @param gem [Gem::Specification] The RubyGems gem.
|
28
|
+
# @return [Vedeu::Plugin]
|
29
|
+
def initialize(name, gem)
|
30
|
+
@name = name
|
31
|
+
@gem = gem
|
32
|
+
@gem_name = "vedeu-#{name}"
|
33
|
+
@enabled = false
|
34
|
+
end
|
35
|
+
|
36
|
+
# Load the plugin (require the gem).
|
37
|
+
#
|
38
|
+
# @return [void]
|
39
|
+
def load!
|
40
|
+
begin
|
41
|
+
require gem_name unless enabled?
|
42
|
+
rescue LoadError => error
|
43
|
+
fail VedeuError, "Unable to load plugin #{gem_name} due to #{error}."
|
44
|
+
rescue => error
|
45
|
+
fail VedeuError, "require '#{gem_name}' failed with #{error}."
|
46
|
+
end
|
47
|
+
|
48
|
+
@enabled = true
|
49
|
+
end
|
50
|
+
|
51
|
+
end # Plugin
|
52
|
+
|
53
|
+
end # Vedeu
|
data/lib/vedeu/version.rb
CHANGED
data/test/lib/vedeu/api_test.rb
CHANGED
@@ -11,6 +11,10 @@ module Vedeu
|
|
11
11
|
it { Vedeu.must_respond_to(:configuration) }
|
12
12
|
it { Vedeu.must_respond_to(:cursor) }
|
13
13
|
it { Vedeu.must_respond_to(:cursors) }
|
14
|
+
it { Vedeu.must_respond_to(:drb_restart) }
|
15
|
+
it { Vedeu.must_respond_to(:drb_start) }
|
16
|
+
it { Vedeu.must_respond_to(:drb_status) }
|
17
|
+
it { Vedeu.must_respond_to(:drb_stop) }
|
14
18
|
it { Vedeu.must_respond_to(:border) }
|
15
19
|
it { Vedeu.must_respond_to(:geometry) }
|
16
20
|
it { Vedeu.must_respond_to(:group) }
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Vedeu
|
4
|
+
|
5
|
+
describe EscapeSequences do
|
6
|
+
|
7
|
+
let(:described) { Vedeu::EscapeSequences }
|
8
|
+
|
9
|
+
before { Vedeu::Terminal.stubs(:size).returns([80, 25]) }
|
10
|
+
|
11
|
+
describe 'foreground colour methods' do
|
12
|
+
it { described.black.must_equal("\e[30m") }
|
13
|
+
it { described.red.must_equal("\e[31m") }
|
14
|
+
it { described.green.must_equal("\e[32m") }
|
15
|
+
it { described.yellow.must_equal("\e[33m") }
|
16
|
+
it { described.blue.must_equal("\e[34m") }
|
17
|
+
it { described.magenta.must_equal("\e[35m") }
|
18
|
+
it { described.cyan.must_equal("\e[36m") }
|
19
|
+
it { described.light_grey.must_equal("\e[37m") }
|
20
|
+
it { described.default.must_equal("\e[39m") }
|
21
|
+
it { described.dark_grey.must_equal("\e[90m") }
|
22
|
+
it { described.light_red.must_equal("\e[91m") }
|
23
|
+
it { described.light_green.must_equal("\e[92m") }
|
24
|
+
it { described.light_yellow.must_equal("\e[93m") }
|
25
|
+
it { described.light_blue.must_equal("\e[94m") }
|
26
|
+
it { described.light_magenta.must_equal("\e[95m") }
|
27
|
+
it { described.light_cyan.must_equal("\e[96m") }
|
28
|
+
it { described.white.must_equal("\e[97m") }
|
29
|
+
|
30
|
+
it 'returns an escape sequence for the foreground colour and resets ' \
|
31
|
+
'after calling the block' do
|
32
|
+
described.cyan do
|
33
|
+
'ununpentium'
|
34
|
+
end.must_equal("\e[36mununpentium\e[39m")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '.codes' do
|
39
|
+
it { described.codes.must_be_instance_of(Hash) }
|
40
|
+
it { described.must_respond_to(:foreground_codes) }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '.background_codes' do
|
44
|
+
it { described.background_codes.must_be_instance_of(Hash) }
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'background colour methods' do
|
48
|
+
it { described.on_black.must_equal("\e[40m") }
|
49
|
+
it { described.on_red.must_equal("\e[41m") }
|
50
|
+
it { described.on_green.must_equal("\e[42m") }
|
51
|
+
it { described.on_yellow.must_equal("\e[43m") }
|
52
|
+
it { described.on_blue.must_equal("\e[44m") }
|
53
|
+
it { described.on_magenta.must_equal("\e[45m") }
|
54
|
+
it { described.on_cyan.must_equal("\e[46m") }
|
55
|
+
it { described.on_light_grey.must_equal("\e[47m") }
|
56
|
+
it { described.on_default.must_equal("\e[49m") }
|
57
|
+
it { described.on_dark_grey.must_equal("\e[100m") }
|
58
|
+
it { described.on_light_red.must_equal("\e[101m") }
|
59
|
+
it { described.on_light_green.must_equal("\e[102m") }
|
60
|
+
it { described.on_light_yellow.must_equal("\e[103m") }
|
61
|
+
it { described.on_light_blue.must_equal("\e[104m") }
|
62
|
+
it { described.on_light_magenta.must_equal("\e[105m") }
|
63
|
+
it { described.on_light_cyan.must_equal("\e[106m") }
|
64
|
+
it { described.on_white.must_equal("\e[107m") }
|
65
|
+
|
66
|
+
it 'returns an escape sequence for the background colour and resets ' \
|
67
|
+
'after calling the block' do
|
68
|
+
described.on_red do
|
69
|
+
'livermorium'
|
70
|
+
end.must_equal("\e[41mlivermorium\e[49m")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'action methods' do
|
75
|
+
it { described.hide_cursor.must_equal("\e[?25l") }
|
76
|
+
it { described.show_cursor.must_equal("\e[?25h") }
|
77
|
+
it { described.cursor_position.must_equal("\e[6n") }
|
78
|
+
it { described.bg_reset.must_equal("\e[49m") }
|
79
|
+
it { described.blink.must_equal("\e[5m") }
|
80
|
+
it { described.blink_off.must_equal("\e[25m") }
|
81
|
+
it { described.bold.must_equal("\e[1m") }
|
82
|
+
it { described.bold_off.must_equal("\e[22m") }
|
83
|
+
it { described.border_on.must_equal("\e(0") }
|
84
|
+
it { described.border_off.must_equal("\e(B") }
|
85
|
+
it { described.dim.must_equal("\e[2m") }
|
86
|
+
it { described.fg_reset.must_equal("\e[39m") }
|
87
|
+
it { described.negative.must_equal("\e[7m") }
|
88
|
+
it { described.positive.must_equal("\e[27m") }
|
89
|
+
it { described.reset.must_equal("\e[0m") }
|
90
|
+
it { described.underline.must_equal("\e[4m") }
|
91
|
+
it { described.underline_off.must_equal("\e[24m") }
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '.actions' do
|
95
|
+
it { described.actions.must_be_instance_of(Hash) }
|
96
|
+
end
|
97
|
+
|
98
|
+
end # EscapeSequences
|
99
|
+
|
100
|
+
end # Vedeu
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Vedeu
|
4
|
+
|
5
|
+
module Null
|
6
|
+
|
7
|
+
describe Menu do
|
8
|
+
|
9
|
+
let(:described) { Vedeu::Null::Menu }
|
10
|
+
let(:instance) { described.new(attributes) }
|
11
|
+
let(:attributes) {
|
12
|
+
{
|
13
|
+
name: _name
|
14
|
+
}
|
15
|
+
}
|
16
|
+
let(:_name) { 'null_geometry' }
|
17
|
+
|
18
|
+
describe '#initialize' do
|
19
|
+
it { instance.must_be_instance_of(described) }
|
20
|
+
it {
|
21
|
+
instance.instance_variable_get('@attributes').must_equal(attributes)
|
22
|
+
}
|
23
|
+
it { instance.instance_variable_get('@name').must_equal(_name) }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'alias methods' do
|
27
|
+
it { instance.must_respond_to(:bottom_item) }
|
28
|
+
it { instance.must_respond_to(:current_item) }
|
29
|
+
it { instance.must_respond_to(:deselect_item) }
|
30
|
+
it { instance.must_respond_to(:items) }
|
31
|
+
it { instance.must_respond_to(:next_item) }
|
32
|
+
it { instance.must_respond_to(:prev_item) }
|
33
|
+
it { instance.must_respond_to(:select_item) }
|
34
|
+
it { instance.must_respond_to(:selected_item) }
|
35
|
+
it { instance.must_respond_to(:top_item) }
|
36
|
+
it { instance.must_respond_to(:view) }
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#item' do
|
40
|
+
it { instance.item.must_equal(nil) }
|
41
|
+
end
|
42
|
+
|
43
|
+
end # Menu
|
44
|
+
|
45
|
+
end # Null
|
46
|
+
|
47
|
+
end # Vedeu
|