vedeu 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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