vedeu 0.1.15 → 0.1.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +2 -0
- data/README.md +116 -98
- data/lib/vedeu.rb +24 -11
- data/lib/vedeu/api/api.rb +174 -33
- data/lib/vedeu/api/composition.rb +2 -13
- data/lib/vedeu/api/helpers.rb +41 -0
- data/lib/vedeu/api/interface.rb +147 -34
- data/lib/vedeu/api/line.rb +47 -0
- data/lib/vedeu/api/stream.rb +41 -0
- data/lib/vedeu/application.rb +9 -2
- data/lib/vedeu/configuration.rb +66 -8
- data/lib/vedeu/launcher.rb +11 -0
- data/lib/vedeu/models/attributes/background.rb +29 -0
- data/lib/vedeu/models/attributes/coercions.rb +30 -0
- data/lib/vedeu/models/attributes/colour_translator.rb +106 -16
- data/lib/vedeu/models/attributes/foreground.rb +29 -0
- data/lib/vedeu/models/attributes/presentation.rb +15 -0
- data/lib/vedeu/models/colour.rb +12 -7
- data/lib/vedeu/models/composition.rb +23 -5
- data/lib/vedeu/models/geometry.rb +101 -16
- data/lib/vedeu/models/interface.rb +36 -28
- data/lib/vedeu/models/line.rb +16 -14
- data/lib/vedeu/models/stream.rb +17 -25
- data/lib/vedeu/models/style.rb +29 -0
- data/lib/vedeu/support/buffer.rb +36 -21
- data/lib/vedeu/support/buffers.rb +88 -0
- data/lib/vedeu/{output → support}/clear.rb +9 -2
- data/lib/vedeu/support/esc.rb +16 -2
- data/lib/vedeu/support/event.rb +104 -0
- data/lib/vedeu/support/events.rb +61 -0
- data/lib/vedeu/support/focus.rb +69 -0
- data/lib/vedeu/{api → support}/grid.rb +29 -25
- data/lib/vedeu/support/groups.rb +51 -0
- data/lib/vedeu/support/input.rb +5 -0
- data/lib/vedeu/support/log.rb +105 -0
- data/lib/vedeu/support/menu.rb +19 -0
- data/lib/vedeu/support/position.rb +7 -0
- data/lib/vedeu/{output → support}/render.rb +12 -6
- data/lib/vedeu/support/terminal.rb +21 -0
- data/lib/vedeu/support/trace.rb +54 -0
- data/lib/vedeu/{output → support}/view.rb +15 -10
- data/test/lib/vedeu/api/api_test.rb +55 -29
- data/test/lib/vedeu/api/interface_test.rb +3 -49
- data/test/lib/vedeu/api/line_test.rb +71 -0
- data/test/lib/vedeu/api/stream_test.rb +25 -0
- data/test/lib/vedeu/models/attributes/background_test.rb +83 -0
- data/test/lib/vedeu/models/attributes/coercer_test.rb +52 -0
- data/test/lib/vedeu/models/attributes/foreground_test.rb +83 -0
- data/test/lib/vedeu/models/attributes/presentation_test.rb +30 -0
- data/test/lib/vedeu/models/composition_test.rb +6 -6
- data/test/lib/vedeu/models/geometry_test.rb +34 -0
- data/test/lib/vedeu/models/interface_test.rb +0 -12
- data/test/lib/vedeu/models/line_test.rb +1 -13
- data/test/lib/vedeu/models/stream_test.rb +4 -50
- data/test/lib/vedeu/models/style_test.rb +39 -0
- data/test/lib/vedeu/support/buffer_test.rb +7 -3
- data/test/lib/vedeu/support/buffers_test.rb +15 -0
- data/test/lib/vedeu/{output → support}/clear_test.rb +8 -1
- data/test/lib/vedeu/support/esc_test.rb +2 -2
- data/test/lib/vedeu/support/event_test.rb +41 -0
- data/test/lib/vedeu/support/events_test.rb +70 -0
- data/test/lib/vedeu/support/focus_test.rb +114 -0
- data/test/lib/vedeu/support/grid_test.rb +31 -0
- data/test/lib/vedeu/support/groups_test.rb +65 -0
- data/test/lib/vedeu/{output → support}/render_test.rb +8 -1
- data/test/lib/vedeu/{output → support}/view_test.rb +1 -1
- data/test/test_helper.rb +3 -1
- data/vedeu.gemspec +3 -2
- metadata +67 -31
- data/lib/vedeu/api/events.rb +0 -46
- data/lib/vedeu/api/log.rb +0 -84
- data/lib/vedeu/models/attributes/attributes.rb +0 -25
- data/lib/vedeu/models/store.rb +0 -29
- data/lib/vedeu/output/buffers.rb +0 -65
- data/test/lib/vedeu/api/events_test.rb +0 -36
- data/test/lib/vedeu/api/grid_test.rb +0 -33
- data/test/lib/vedeu/models/attributes/attributes_test.rb +0 -39
- data/test/lib/vedeu/models/attributes/colour_translator_test.rb +0 -78
- data/test/lib/vedeu/models/store_test.rb +0 -57
- data/test/lib/vedeu/output/buffers_test.rb +0 -35
@@ -1,4 +1,5 @@
|
|
1
1
|
class Fixnum
|
2
|
+
|
2
3
|
# Augment Fixnum to calculate column width in a grid-based layout.
|
3
4
|
#
|
4
5
|
# The grid system splits the terminal width into 12 equal parts, by dividing
|
@@ -11,44 +12,47 @@ class Fixnum
|
|
11
12
|
# # Terminal is 92 characters wide, maximum value is
|
12
13
|
# # therefore 84, meaning a column is 7 characters wide.
|
13
14
|
def columns
|
14
|
-
Vedeu::
|
15
|
+
Vedeu::Grid.columns(self)
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
18
19
|
module Vedeu
|
19
|
-
|
20
|
-
OutOfRange = Class.new(StandardError)
|
20
|
+
class Grid
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
# @param value [Fixnum]
|
23
|
+
# @return []
|
24
|
+
def self.columns(value)
|
25
|
+
new(value).columns
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
# @param value [Fixnum]
|
29
|
+
# @return [Grid]
|
30
|
+
def initialize(value)
|
31
|
+
@value = value
|
32
|
+
end
|
30
33
|
|
31
|
-
|
32
|
-
|
34
|
+
# @return []
|
35
|
+
def columns
|
36
|
+
fail OutOfRange, 'Valid range is 1..12.' if out_of_range?
|
33
37
|
|
34
|
-
|
35
|
-
|
38
|
+
column * value
|
39
|
+
end
|
36
40
|
|
37
|
-
|
41
|
+
private
|
38
42
|
|
39
|
-
|
43
|
+
attr_reader :value
|
40
44
|
|
41
|
-
|
42
|
-
|
43
|
-
|
45
|
+
def column
|
46
|
+
actual / 12
|
47
|
+
end
|
44
48
|
|
45
|
-
|
46
|
-
|
47
|
-
|
49
|
+
def actual
|
50
|
+
Terminal.width
|
51
|
+
end
|
48
52
|
|
49
|
-
|
50
|
-
|
51
|
-
end
|
53
|
+
def out_of_range?
|
54
|
+
value < 1 || value > 12
|
52
55
|
end
|
56
|
+
|
53
57
|
end
|
54
58
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Vedeu
|
2
|
+
class Groups
|
3
|
+
|
4
|
+
# @return [Groups]
|
5
|
+
def initialize; end
|
6
|
+
|
7
|
+
# @return [Set]
|
8
|
+
def all
|
9
|
+
@_storage
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param name [String]
|
13
|
+
# @return [Set]
|
14
|
+
def find(name)
|
15
|
+
storage.fetch(name) do
|
16
|
+
fail GroupNotFound, 'Cannot find interface group with this name.'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param group [String]
|
21
|
+
# @param name [String]
|
22
|
+
# @param delay [Float]
|
23
|
+
# @return [Groups|FalseClass]
|
24
|
+
def add(group, name, delay = 0.0)
|
25
|
+
return false if group.empty?
|
26
|
+
|
27
|
+
storage[group] << name
|
28
|
+
|
29
|
+
Vedeu.event("_refresh_group_#{group}_".to_sym, { delay: delay }) do
|
30
|
+
Buffers.refresh_group(group)
|
31
|
+
end
|
32
|
+
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Hash]
|
37
|
+
def reset
|
38
|
+
@_storage = in_memory
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def storage
|
44
|
+
@_storage ||= in_memory
|
45
|
+
end
|
46
|
+
|
47
|
+
def in_memory
|
48
|
+
Hash.new { |hash, key| hash[key] = Set.new }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/vedeu/support/input.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
module Vedeu
|
2
2
|
class Input
|
3
|
+
|
4
|
+
# @return []
|
3
5
|
def self.capture
|
4
6
|
new.capture
|
5
7
|
end
|
6
8
|
|
9
|
+
# @return []
|
7
10
|
def initialize; end
|
8
11
|
|
12
|
+
# @return []
|
9
13
|
def capture
|
10
14
|
Vedeu.trigger(:_keypress_, keypress)
|
11
15
|
end
|
@@ -53,5 +57,6 @@ module Vedeu
|
|
53
57
|
|
54
58
|
translated
|
55
59
|
end
|
60
|
+
|
56
61
|
end
|
57
62
|
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module Vedeu
|
5
|
+
class MonoLogger < Logger
|
6
|
+
# Create a trappable Logger instance.
|
7
|
+
#
|
8
|
+
# @param logdev [String|IO] The filename (String) or IO object (typically
|
9
|
+
# STDOUT, STDERR or an open file).
|
10
|
+
# @param shift_age [] Number of old log files to keep, or frequency of
|
11
|
+
# rotation (daily, weekly, monthly).
|
12
|
+
# @param shift_size [] Maximum log file size (only applies when shift_age
|
13
|
+
# is a number).
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# Logger.new(name, shift_age = 7, shift_size = 1048576)
|
17
|
+
# Logger.new(name, shift_age = 'weekly')
|
18
|
+
#
|
19
|
+
def initialize(logdev, shift_age=nil, shift_size=nil)
|
20
|
+
@progname = nil
|
21
|
+
@level = DEBUG
|
22
|
+
@default_formatter = Formatter.new
|
23
|
+
@formatter = nil
|
24
|
+
@logdev = nil
|
25
|
+
if logdev
|
26
|
+
@logdev = LocklessLogDevice.new(logdev)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class LocklessLogDevice < LogDevice
|
31
|
+
def initialize(log = nil)
|
32
|
+
@dev = @filename = @shift_age = @shift_size = nil
|
33
|
+
if log.respond_to?(:write) and log.respond_to?(:close)
|
34
|
+
@dev = log
|
35
|
+
else
|
36
|
+
@dev = open_logfile(log)
|
37
|
+
@dev.sync = true
|
38
|
+
@filename = log
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def write(message)
|
43
|
+
@dev.write(message)
|
44
|
+
rescue Exception => ignored
|
45
|
+
warn("log writing failed. #{ignored}")
|
46
|
+
end
|
47
|
+
|
48
|
+
def close
|
49
|
+
@dev.close rescue nil
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def open_logfile(filename)
|
55
|
+
if (FileTest.exist?(filename))
|
56
|
+
open(filename, (File::WRONLY | File::APPEND))
|
57
|
+
else
|
58
|
+
create_logfile(filename)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_logfile(filename)
|
63
|
+
logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT))
|
64
|
+
logdev.sync = true
|
65
|
+
add_log_header(logdev)
|
66
|
+
logdev
|
67
|
+
end
|
68
|
+
|
69
|
+
def add_log_header(file)
|
70
|
+
file.write(
|
71
|
+
"# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName]
|
72
|
+
)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class Log
|
78
|
+
|
79
|
+
# @return []
|
80
|
+
def self.logger
|
81
|
+
@logger ||= MonoLogger.new(filename).tap do |log|
|
82
|
+
log.formatter = proc do |_, time, _, message|
|
83
|
+
time.utc.iso8601 + ": " + message + "\n"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def self.filename
|
91
|
+
@_filename ||= directory + '/vedeu.log'
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.directory
|
95
|
+
FileUtils.mkdir_p(path) unless File.directory?(path)
|
96
|
+
|
97
|
+
path
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.path
|
101
|
+
Dir.home + '/.vedeu'
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
data/lib/vedeu/support/menu.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
module Vedeu
|
2
2
|
class Menu
|
3
|
+
|
4
|
+
# @param collection []
|
5
|
+
# @return [Menu]
|
3
6
|
def initialize(collection)
|
4
7
|
@collection = collection
|
5
8
|
@current = 0
|
@@ -7,6 +10,7 @@ module Vedeu
|
|
7
10
|
@events = events
|
8
11
|
end
|
9
12
|
|
13
|
+
# @return []
|
10
14
|
def events
|
11
15
|
@_events ||= Vedeu.events.add(self) do
|
12
16
|
event(:menu_next) { next_item }
|
@@ -22,24 +26,29 @@ module Vedeu
|
|
22
26
|
end
|
23
27
|
end
|
24
28
|
|
29
|
+
# @return []
|
25
30
|
def current
|
26
31
|
@current
|
27
32
|
end
|
28
33
|
|
34
|
+
# @return []
|
29
35
|
def selected
|
30
36
|
@selected
|
31
37
|
end
|
32
38
|
|
39
|
+
# @return []
|
33
40
|
def current_item
|
34
41
|
@collection[@current]
|
35
42
|
end
|
36
43
|
|
44
|
+
# @return []
|
37
45
|
def selected_item
|
38
46
|
return nil unless @selected
|
39
47
|
|
40
48
|
@collection[@selected]
|
41
49
|
end
|
42
50
|
|
51
|
+
# @return [Array]
|
43
52
|
def items
|
44
53
|
items = []
|
45
54
|
@collection.each_with_index do |item, index|
|
@@ -60,52 +69,62 @@ module Vedeu
|
|
60
69
|
items
|
61
70
|
end
|
62
71
|
|
72
|
+
# @return []
|
63
73
|
def view
|
64
74
|
items[@current, @collection.size]
|
65
75
|
end
|
66
76
|
|
77
|
+
# @return []
|
67
78
|
def top_item
|
68
79
|
@current = 0
|
69
80
|
|
70
81
|
items
|
71
82
|
end
|
72
83
|
|
84
|
+
# @return []
|
73
85
|
def bottom_item
|
74
86
|
@current = last
|
75
87
|
|
76
88
|
items
|
77
89
|
end
|
78
90
|
|
91
|
+
# @return []
|
79
92
|
def next_item
|
80
93
|
@current += 1 if @current < last
|
81
94
|
|
82
95
|
items
|
83
96
|
end
|
84
97
|
|
98
|
+
# @return []
|
85
99
|
def prev_item
|
86
100
|
@current -= 1 if @current > 0
|
87
101
|
|
88
102
|
items
|
89
103
|
end
|
90
104
|
|
105
|
+
# @return []
|
91
106
|
def select_item
|
92
107
|
@selected = @current
|
93
108
|
|
94
109
|
items
|
95
110
|
end
|
96
111
|
|
112
|
+
# @return []
|
97
113
|
def deselect_item
|
98
114
|
@selected = nil
|
99
115
|
|
100
116
|
items
|
101
117
|
end
|
102
118
|
|
119
|
+
# @return []
|
103
120
|
def last
|
104
121
|
@collection.size - 1
|
105
122
|
end
|
106
123
|
|
124
|
+
# @return []
|
107
125
|
def size
|
108
126
|
@collection.size
|
109
127
|
end
|
128
|
+
|
110
129
|
end
|
111
130
|
end
|
@@ -1,9 +1,15 @@
|
|
1
1
|
module Vedeu
|
2
2
|
class Position
|
3
|
+
|
4
|
+
# @param y [Fixnum]
|
5
|
+
# @param x [Fixnum]
|
6
|
+
# @return [Position]
|
3
7
|
def initialize(y = 1, x = 1)
|
4
8
|
@y, @x = y, x
|
5
9
|
end
|
6
10
|
|
11
|
+
# @param block [Proc]
|
12
|
+
# @return [String]
|
7
13
|
def to_s(&block)
|
8
14
|
if block_given?
|
9
15
|
[ sequence, yield, sequence ].join
|
@@ -27,5 +33,6 @@ module Vedeu
|
|
27
33
|
def x
|
28
34
|
(@x == 0 || @x == nil) ? 1 : @x
|
29
35
|
end
|
36
|
+
|
30
37
|
end
|
31
38
|
end
|
@@ -1,13 +1,19 @@
|
|
1
1
|
module Vedeu
|
2
2
|
class Render
|
3
|
+
|
4
|
+
# @param interface [Interface]
|
5
|
+
# @return [String]
|
3
6
|
def self.call(interface)
|
4
7
|
new(interface).render
|
5
8
|
end
|
6
9
|
|
10
|
+
# @param interface [Interface]
|
11
|
+
# @return [Render]
|
7
12
|
def initialize(interface)
|
8
13
|
@interface = interface
|
9
14
|
end
|
10
15
|
|
16
|
+
# @return [String]
|
11
17
|
def render
|
12
18
|
out = [ Clear.call(interface) ]
|
13
19
|
processed_lines.each_with_index do |line, index|
|
@@ -42,7 +48,7 @@ module Vedeu
|
|
42
48
|
|
43
49
|
processed << Stream.new({
|
44
50
|
colour: stream.colour.attributes,
|
45
|
-
style: stream.style,
|
51
|
+
style: stream.style.values,
|
46
52
|
text: truncate(stream.text, remainder),
|
47
53
|
})
|
48
54
|
|
@@ -55,7 +61,7 @@ module Vedeu
|
|
55
61
|
Line.new({
|
56
62
|
colour: line.colour.attributes,
|
57
63
|
streams: processed,
|
58
|
-
style: line.style,
|
64
|
+
style: line.style.values,
|
59
65
|
})
|
60
66
|
|
61
67
|
else
|
@@ -66,8 +72,7 @@ module Vedeu
|
|
66
72
|
end
|
67
73
|
|
68
74
|
def exceeds_width?(line)
|
69
|
-
|
70
|
-
content.size > width
|
75
|
+
line.streams.map(&:text).join.size > width
|
71
76
|
end
|
72
77
|
|
73
78
|
def truncate(text, value)
|
@@ -79,11 +84,12 @@ module Vedeu
|
|
79
84
|
end
|
80
85
|
|
81
86
|
def height
|
82
|
-
interface.
|
87
|
+
interface.viewport_height
|
83
88
|
end
|
84
89
|
|
85
90
|
def width
|
86
|
-
interface.
|
91
|
+
interface.viewport_width
|
87
92
|
end
|
93
|
+
|
88
94
|
end
|
89
95
|
end
|