vedeu 0.0.3 → 0.0.4

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/Gemfile +0 -1
  4. data/Guardfile +0 -8
  5. data/README.md +33 -1
  6. data/Rakefile +0 -8
  7. data/bin/vedeu +9 -0
  8. data/lib/vedeu.rb +23 -6
  9. data/lib/vedeu/application.rb +47 -0
  10. data/lib/vedeu/interface/interface.rb +37 -0
  11. data/lib/vedeu/interface/interfaces.rb +49 -0
  12. data/lib/vedeu/output/background.rb +23 -0
  13. data/lib/vedeu/output/base.rb +49 -0
  14. data/lib/vedeu/output/colour.rb +30 -0
  15. data/lib/vedeu/output/compositor.rb +60 -0
  16. data/lib/vedeu/output/directive.rb +34 -0
  17. data/lib/vedeu/output/esc.rb +37 -0
  18. data/lib/vedeu/output/foreground.rb +23 -0
  19. data/lib/vedeu/output/position.rb +22 -0
  20. data/lib/vedeu/output/style.rb +32 -0
  21. data/lib/vedeu/output/translator.rb +62 -0
  22. data/lib/vedeu/process/command.rb +51 -0
  23. data/lib/vedeu/process/commands.rb +58 -0
  24. data/lib/vedeu/process/process.rb +31 -0
  25. data/lib/vedeu/support/terminal.rb +139 -0
  26. data/lib/vedeu/version.rb +1 -1
  27. data/test/lib/vedeu/application_test.rb +18 -0
  28. data/test/lib/vedeu/interface/interface_test.rb +76 -0
  29. data/test/lib/vedeu/interface/interfaces_test.rb +63 -0
  30. data/test/lib/vedeu/output/background_test.rb +10 -0
  31. data/test/lib/vedeu/output/base_test.rb +10 -0
  32. data/test/lib/vedeu/output/colour_test.rb +67 -0
  33. data/test/lib/vedeu/output/compositor_test.rb +106 -0
  34. data/test/lib/vedeu/output/directive_test.rb +55 -0
  35. data/test/lib/vedeu/output/esc_test.rb +71 -0
  36. data/test/lib/vedeu/output/foreground_test.rb +10 -0
  37. data/test/lib/vedeu/output/position_test.rb +33 -0
  38. data/test/lib/vedeu/output/style_test.rb +59 -0
  39. data/test/lib/vedeu/output/translator_test.rb +52 -0
  40. data/test/lib/vedeu/process/command_test.rb +54 -0
  41. data/test/lib/vedeu/process/commands_test.rb +62 -0
  42. data/test/lib/vedeu/process/process_test.rb +11 -0
  43. data/test/lib/vedeu/support/terminal_test.rb +140 -0
  44. data/test/lib/vedeu/version_test.rb +9 -0
  45. data/test/support/test_app/bin/testapp +32 -0
  46. data/test/test_helper.rb +4 -0
  47. data/vedeu.gemspec +0 -6
  48. metadata +60 -99
  49. data/.rubocop.yml +0 -2
  50. data/features/.gitkeep +0 -0
  51. data/lib/vedeu/buffer.rb +0 -106
  52. data/lib/vedeu/colour.rb +0 -98
  53. data/lib/vedeu/terminal.rb +0 -25
  54. data/test/lib/vedeu/buffer_test.rb +0 -114
  55. data/test/lib/vedeu/colour_test.rb +0 -57
  56. data/test/lib/vedeu/terminal_test.rb +0 -30
@@ -0,0 +1,34 @@
1
+ module Vedeu
2
+ class InvalidDirective < StandardError; end
3
+
4
+ class Directive
5
+ class << self
6
+ def enact(directive)
7
+ new(directive).enact
8
+ end
9
+ end
10
+
11
+ def initialize(directive)
12
+ @directive = directive
13
+ end
14
+
15
+ def enact
16
+ raise InvalidDirective unless valid_directive?
17
+
18
+ return Style.set(directive) if directive.is_a?(Symbol)
19
+
20
+ if directive.is_a?(Array)
21
+ return Position.set(*directive) if directive.first.is_a?(Numeric)
22
+ return Colour.set(directive) if directive.first.is_a?(Symbol)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :directive
29
+
30
+ def valid_directive?
31
+ directive.is_a?(Array) || directive.is_a?(Symbol)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,37 @@
1
+ module Vedeu
2
+ class Esc
3
+ class << self
4
+ def bold
5
+ [esc, '1m'].join
6
+ end
7
+
8
+ def clear
9
+ [esc, '2J'].join
10
+ end
11
+
12
+ def esc
13
+ [27.chr, '['].join
14
+ end
15
+
16
+ def hide_cursor
17
+ [esc, '?25l'].join
18
+ end
19
+
20
+ def inverse
21
+ [esc, '7m'].join
22
+ end
23
+
24
+ def reset
25
+ [esc, '0m'].join
26
+ end
27
+
28
+ def show_cursor
29
+ [esc, '?25h'].join
30
+ end
31
+
32
+ def underline
33
+ [esc, '4m'].join
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,23 @@
1
+ module Vedeu
2
+ class Foreground < Base
3
+ private
4
+
5
+ def prefix
6
+ '38;5;'
7
+ end
8
+
9
+ def codes
10
+ {
11
+ black: 30,
12
+ red: 31,
13
+ green: 32,
14
+ yellow: 33,
15
+ blue: 34,
16
+ magenta: 35,
17
+ cyan: 36,
18
+ white: 37,
19
+ default: 39,
20
+ }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ module Vedeu
2
+ class Position
3
+ class << self
4
+ def set(y = 0, x = 0)
5
+ new(y, x).set
6
+ end
7
+ alias_method :reset, :set
8
+ end
9
+
10
+ def initialize(y = 0, x = 0)
11
+ @y, @x = y, x
12
+ end
13
+
14
+ def set
15
+ [Esc.esc, (y + 1), ';', (x + 1), 'H'].join
16
+ end
17
+
18
+ private
19
+
20
+ attr_accessor :y, :x
21
+ end
22
+ end
@@ -0,0 +1,32 @@
1
+ module Vedeu
2
+ class Style
3
+ class << self
4
+ def set(style)
5
+ new(style).set
6
+ end
7
+ end
8
+
9
+ def initialize(style)
10
+ @style = style
11
+ end
12
+
13
+ def set
14
+ case style
15
+ when :bold then Esc.bold
16
+ when :clear then Esc.clear
17
+ when :hide_cursor then Esc.hide_cursor
18
+ when :inverse then Esc.inverse
19
+ when :reset then Esc.reset
20
+ when :normal then Esc.reset
21
+ when :show_cursor then Esc.show_cursor
22
+ when :underline then Esc.underline
23
+ else
24
+ ""
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :style
31
+ end
32
+ end
@@ -0,0 +1,62 @@
1
+ module Vedeu
2
+ class Translator
3
+ class << self
4
+ def translate(html_colour = nil)
5
+ new(html_colour).translate
6
+ end
7
+ end
8
+
9
+ def initialize(html_colour = nil)
10
+ @html_colour = html_colour
11
+ end
12
+
13
+ def translate
14
+ return unless valid?
15
+ [term_colour_base, red, green, blue].inject(:+)
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :html_colour
21
+
22
+ def red
23
+ (html_colour[1..2].to_i(16) / colour_divide) * 36
24
+ end
25
+
26
+ def green
27
+ (html_colour[3..4].to_i(16) / colour_divide) * 6
28
+ end
29
+
30
+ def blue
31
+ (html_colour[5..6].to_i(16) / colour_divide) * 1
32
+ end
33
+
34
+ def colour_divide
35
+ source_values / target_values
36
+ end
37
+
38
+ def source_values
39
+ 256
40
+ end
41
+
42
+ def target_values
43
+ 5
44
+ end
45
+
46
+ def term_colour_base
47
+ 16
48
+ end
49
+
50
+ def valid?
51
+ html_colour && valid_type? && valid_format?
52
+ end
53
+
54
+ def valid_type?
55
+ html_colour.is_a?(String)
56
+ end
57
+
58
+ def valid_format?
59
+ html_colour =~ /^#([A-Fa-f0-9]{6})$/
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,51 @@
1
+ module Vedeu
2
+ class InvalidCommand < StandardError; end
3
+
4
+ class Command
5
+ class << self
6
+ def define(name, klass, args = [], options = {})
7
+ new(name, klass, args, options).define
8
+ end
9
+ end
10
+
11
+ def initialize(name, klass, args = [], options = {})
12
+ @name, @klass, @args, @options = name, klass, args, options
13
+ end
14
+
15
+ def define
16
+ { name => executable } if valid?
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :name, :klass, :args, :options
22
+
23
+ def executable
24
+ Proc.new { klass.dispatch(*args) }
25
+ end
26
+
27
+ def valid?
28
+ empty_name? || empty_klass? || klass_defined? || dispatch_defined? || true
29
+ end
30
+
31
+ def empty_name?
32
+ raise InvalidCommand, "Command name is missing." if name.to_s.empty?
33
+ end
34
+
35
+ def empty_klass?
36
+ raise InvalidCommand, "Command class is missing." if klass.to_s.empty?
37
+ end
38
+
39
+ def klass_defined?
40
+ unless Object.const_defined?(klass.to_s)
41
+ raise InvalidCommand, "Command class is not defined."
42
+ end
43
+ end
44
+
45
+ def dispatch_defined?
46
+ unless klass.singleton_methods(false).include?(:dispatch)
47
+ raise InvalidCommand, "Command dispatch method is not defined."
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,58 @@
1
+ module Vedeu
2
+ class Commands
3
+ include Singleton
4
+
5
+ class << self
6
+ def instance(&block)
7
+ @instance ||= new(&block)
8
+ end
9
+ alias_method :define, :instance
10
+
11
+ # def define(name, klass, args = [], options = {}, &block)
12
+ # instance.define(name, klass, args = [], options = {})
13
+ # end
14
+
15
+ def execute(command = "")
16
+ instance.execute(command)
17
+ end
18
+
19
+ def list
20
+ instance.list
21
+ end
22
+ end
23
+
24
+ def initialize(&block)
25
+ @commands ||= { 'exit' => Proc.new { Exit.dispatch } }
26
+
27
+ yield self if block_given?
28
+ end
29
+
30
+ def define(name, klass, args = [], options = {})
31
+ commands.merge!(Command.define(name, klass, args, options))
32
+ end
33
+ alias_method :add, :define
34
+
35
+ def execute(command)
36
+ commands.fetch(command).call if exists?(command)
37
+ end
38
+
39
+ def list
40
+ commands.inspect
41
+ end
42
+
43
+ private
44
+
45
+ attr_accessor :commands
46
+ attr_accessor :instance
47
+
48
+ def exists?(command)
49
+ commands.fetch(command, false)
50
+ end
51
+ end
52
+
53
+ class Exit
54
+ def self.dispatch
55
+ :stop
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,31 @@
1
+ module Vedeu
2
+ class Process
3
+ class << self
4
+ def event_loop
5
+ new.event_loop
6
+ end
7
+ end
8
+
9
+ def initialize; end
10
+
11
+ def event_loop
12
+ while true do
13
+ command = evaluate
14
+
15
+ break if command == :stop
16
+
17
+ Compositor.write(command)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def evaluate
24
+ Commands.execute(read)
25
+ end
26
+
27
+ def read
28
+ Terminal.input
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,139 @@
1
+ module Vedeu
2
+ class Terminal
3
+ class << self
4
+ def input
5
+ console.gets.chomp
6
+ end
7
+
8
+ def output(stream = '')
9
+ console.puts(stream)
10
+ end
11
+
12
+ def width
13
+ size.last
14
+ end
15
+
16
+ def height
17
+ size.first
18
+ end
19
+
20
+ def size
21
+ console.winsize
22
+ end
23
+
24
+ def open(options = {}, &block)
25
+ new(options).open(&block)
26
+ end
27
+
28
+ def close
29
+ clear_screen
30
+ show_cursor
31
+ output(Position.reset)
32
+ end
33
+
34
+ def cooked(instance, &block)
35
+ console.cooked do
36
+ instance.initial_setup!
37
+
38
+ yield
39
+ end if block_given?
40
+ end
41
+ alias_method :open_cooked, :cooked
42
+
43
+ def raw(instance, &block)
44
+ console.raw do
45
+ instance.initial_setup!
46
+
47
+ yield
48
+ end if block_given?
49
+ end
50
+ alias_method :open_raw, :raw
51
+
52
+ def console
53
+ IO.console
54
+ end
55
+
56
+ def clear_screen
57
+ output(Esc.reset)
58
+ output(Esc.clear)
59
+ end
60
+
61
+ def clear_line(index)
62
+ output(Position.set(index, 0))
63
+ output(" " * width)
64
+ end
65
+
66
+ def show_cursor
67
+ output(Esc.show_cursor)
68
+ end
69
+
70
+ def hide_cursor
71
+ output(Esc.hide_cursor)
72
+ end
73
+ end
74
+
75
+ def initialize(options = {}, &block)
76
+ @options = options
77
+
78
+ yield self if block_given?
79
+ end
80
+
81
+ def open(&block)
82
+ terminal_mode(&block).fetch(mode, noop).call
83
+ end
84
+
85
+ def initial_setup!
86
+ Terminal.clear_screen if clear_screen?
87
+ set_cursor
88
+ output(Position.reset)
89
+ end
90
+
91
+ private
92
+
93
+ def terminal_mode(&block)
94
+ {
95
+ cooked: Proc.new { Terminal.cooked(self, &block) },
96
+ raw: Proc.new { Terminal.raw(self, &block) }
97
+ }
98
+ end
99
+
100
+ def cursor_mode
101
+ {
102
+ show: Proc.new { Terminal.show_cursor },
103
+ hide: Proc.new { Terminal.hide_cursor }
104
+ }
105
+ end
106
+
107
+ def set_cursor
108
+ cursor_mode.fetch(cursor).call
109
+ end
110
+
111
+ def cursor
112
+ options.fetch(:cursor, :show)
113
+ end
114
+
115
+ def mode
116
+ options.fetch(:mode, :cooked)
117
+ end
118
+
119
+ def clear_screen?
120
+ options.fetch(:clear, true)
121
+ end
122
+
123
+ def noop
124
+ Proc.new {}
125
+ end
126
+
127
+ def options
128
+ defaults.merge!(@options)
129
+ end
130
+
131
+ def defaults
132
+ {
133
+ mode: :cooked, # or :raw
134
+ clear: true, # or false (clears the screen if true)
135
+ cursor: :show, # or :hide
136
+ }
137
+ end
138
+ end
139
+ end