tty-reader 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'io/console'
5
+
6
+ module TTY
7
+ class Reader
8
+ class Mode
9
+ # Initialize a Terminal
10
+ #
11
+ # @api public
12
+ def initialize(input = $stdin)
13
+ @input = input
14
+ end
15
+
16
+ # Echo given block
17
+ #
18
+ # @param [Boolean] is_on
19
+ #
20
+ # @api public
21
+ def echo(is_on = true, &block)
22
+ if is_on || !@input.tty?
23
+ yield
24
+ else
25
+ @input.noecho(&block)
26
+ end
27
+ end
28
+
29
+ # Use raw mode in the given block
30
+ #
31
+ # @param [Boolean] is_on
32
+ #
33
+ # @api public
34
+ def raw(is_on = true, &block)
35
+ if is_on && @input.tty?
36
+ @input.raw(&block)
37
+ else
38
+ yield
39
+ end
40
+ end
41
+ end # Mode
42
+ end # Reader
43
+ end # TTY
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ module TTY
4
+ class Reader
5
+ VERSION = "0.1.0"
6
+ end # Reader
7
+ end # TTY
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'fiddle'
5
+
6
+ module TTY
7
+ class Reader
8
+ module WinAPI
9
+ include Fiddle
10
+
11
+ Handle = RUBY_VERSION >= "2.0.0" ? Fiddle::Handle : DL::Handle
12
+
13
+ CRT_HANDLE = Handle.new("msvcrt") rescue Handle.new("crtdll")
14
+
15
+ # Get a character from the console without echo.
16
+ #
17
+ # @return [String]
18
+ # return the character read
19
+ #
20
+ # @api public
21
+ def getch
22
+ @@getch ||= Fiddle::Function.new(CRT_HANDLE["_getch"], [], TYPE_INT)
23
+ @@getch.call
24
+ end
25
+ module_function :getch
26
+
27
+ # Gets a character from the console with echo.
28
+ #
29
+ # @return [String]
30
+ # return the character read
31
+ #
32
+ # @api public
33
+ def getche
34
+ @@getche ||= Fiddle::Function.new(CRT_HANDLE["_getche"], [], TYPE_INT)
35
+ @@getche.call
36
+ end
37
+ module_function :getche
38
+
39
+ # Check the console for recent keystroke. If the function
40
+ # returns a nonzero value, a keystroke is waiting in the buffer.
41
+ #
42
+ # @return [Integer]
43
+ # return a nonzero value if a key has been pressed. Otherwirse,
44
+ # it returns 0.
45
+ #
46
+ # @api public
47
+ def kbhit
48
+ @@kbhit ||= Fiddle::Function.new(CRT_HANDLE["_kbhit"], [], TYPE_INT)
49
+ @@kbhit.call
50
+ end
51
+ module_function :kbhit
52
+ end # WinAPI
53
+ end # Reader
54
+ end # TTY
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require_relative 'codes'
5
+
6
+ module TTY
7
+ class Reader
8
+ class WinConsole
9
+ ESC = "\e".freeze
10
+ NUL_HEX = "\x00".freeze
11
+ EXT_HEX = "\xE0".freeze
12
+
13
+ # Key codes
14
+ #
15
+ # @return [Hash[Symbol]]
16
+ #
17
+ # @api public
18
+ attr_reader :keys
19
+
20
+ # Escape codes
21
+ #
22
+ # @return [Array[Integer]]
23
+ #
24
+ # @api public
25
+ attr_reader :escape_codes
26
+
27
+ def initialize(input)
28
+ require_relative 'win_api'
29
+ @input = input
30
+ @keys = Codes.win_keys
31
+ @escape_codes = [[NUL_HEX.ord], [ESC.ord], EXT_HEX.bytes.to_a]
32
+ end
33
+
34
+ # Get a character from console blocking for input
35
+ #
36
+ # @param [Hash[Symbol]] options
37
+ # @option options [Symbol] :echo
38
+ # the echo mode toggle
39
+ # @option options [Symbol] :raw
40
+ # the raw mode toggle
41
+ #
42
+ # @return [String]
43
+ #
44
+ # @api private
45
+ def get_char(options)
46
+ if options[:raw] && options[:echo]
47
+ if options[:nonblock]
48
+ get_char_echo_non_blocking
49
+ else
50
+ get_char_echo_blocking
51
+ end
52
+ elsif options[:raw] && !options[:echo]
53
+ options[:nonblock] ? get_char_non_blocking : get_char_blocking
54
+ elsif !options[:raw] && !options[:echo]
55
+ options[:nonblock] ? get_char_non_blocking : get_char_blocking
56
+ else
57
+ @input.getc
58
+ end
59
+ end
60
+
61
+ # Get the char for last key pressed, or if no keypress return nil
62
+ #
63
+ # @api private
64
+ def get_char_non_blocking
65
+ input_ready? ? get_char_blocking : nil
66
+ end
67
+
68
+ def get_char_echo_non_blocking
69
+ input_ready? ? get_char_echo_blocking : nil
70
+ end
71
+
72
+ def get_char_blocking
73
+ WinAPI.getch.chr
74
+ end
75
+
76
+ def get_char_echo_blocking
77
+ WinAPI.getche.chr
78
+ end
79
+
80
+ # Check if IO has user input
81
+ #
82
+ # @return [Boolean]
83
+ #
84
+ # @api private
85
+ def input_ready?
86
+ !WinAPI.kbhit.zero?
87
+ end
88
+ end # Console
89
+ end # Reader
90
+ end # TTY
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ desc 'Load gem inside irb console'
4
+ task :console do
5
+ require 'irb'
6
+ require 'irb/completion'
7
+ require File.join(__FILE__, '../../lib/tty-reader')
8
+ ARGV.clear
9
+ IRB.start
10
+ end
11
+ task c: %w[ console ]
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ desc 'Measure code coverage'
4
+ task :coverage do
5
+ begin
6
+ original, ENV['COVERAGE'] = ENV['COVERAGE'], 'true'
7
+ Rake::Task['spec'].invoke
8
+ ensure
9
+ ENV['COVERAGE'] = original
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc 'Run all specs'
7
+ RSpec::Core::RakeTask.new(:spec) do |task|
8
+ task.pattern = 'spec/{unit,integration}{,/*/**}/*_spec.rb'
9
+ end
10
+
11
+ namespace :spec do
12
+ desc 'Run unit specs'
13
+ RSpec::Core::RakeTask.new(:unit) do |task|
14
+ task.pattern = 'spec/unit{,/*/**}/*_spec.rb'
15
+ end
16
+
17
+ desc 'Run integration specs'
18
+ RSpec::Core::RakeTask.new(:integration) do |task|
19
+ task.pattern = 'spec/integration{,/*/**}/*_spec.rb'
20
+ end
21
+ end
22
+
23
+ rescue LoadError
24
+ %w[spec spec:unit spec:integration].each do |name|
25
+ task name do
26
+ $stderr.puts "In order to run #{name}, do `gem install rspec`"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "tty/reader/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tty-reader"
8
+ spec.version = TTY::Reader::VERSION
9
+ spec.authors = ["Piotr Murach"]
10
+ spec.email = [""]
11
+ spec.summary = %q{Provides a set of methods for processing keyboard input in character, line and multiline modes.}
12
+ spec.description = %q{Provides a set of methods for processing keyboard input in character, line and multiline modes. In addition it maintains history of entered input with an ability to recall and re-edit those inputs and register to listen for keystrokes.}
13
+ spec.homepage = "https://piotrmurach.github.io/tty"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency "wisper", "~> 2.0.0"
24
+
25
+ spec.add_development_dependency "bundler", ">= 1.5.0", "< 2.0"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "rspec", "~> 3.0"
28
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tty-reader
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Piotr Murach
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-08-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: wisper
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.5.0
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '2.0'
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.5.0
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '2.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '10.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '10.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.0'
75
+ description: Provides a set of methods for processing keyboard input in character,
76
+ line and multiline modes. In addition it maintains history of entered input with
77
+ an ability to recall and re-edit those inputs and register to listen for keystrokes.
78
+ email:
79
+ - ''
80
+ executables: []
81
+ extensions: []
82
+ extra_rdoc_files: []
83
+ files:
84
+ - ".gitignore"
85
+ - ".rspec"
86
+ - ".travis.yml"
87
+ - CHANGELOG.md
88
+ - CODE_OF_CONDUCT.md
89
+ - Gemfile
90
+ - LICENSE.txt
91
+ - README.md
92
+ - Rakefile
93
+ - appveyor.yml
94
+ - bin/console
95
+ - bin/setup
96
+ - lib/tty-reader.rb
97
+ - lib/tty/reader.rb
98
+ - lib/tty/reader/codes.rb
99
+ - lib/tty/reader/console.rb
100
+ - lib/tty/reader/history.rb
101
+ - lib/tty/reader/key_event.rb
102
+ - lib/tty/reader/line.rb
103
+ - lib/tty/reader/mode.rb
104
+ - lib/tty/reader/version.rb
105
+ - lib/tty/reader/win_api.rb
106
+ - lib/tty/reader/win_console.rb
107
+ - tasks/console.rake
108
+ - tasks/coverage.rake
109
+ - tasks/spec.rake
110
+ - tty-reader.gemspec
111
+ homepage: https://piotrmurach.github.io/tty
112
+ licenses:
113
+ - MIT
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.5.1
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Provides a set of methods for processing keyboard input in character, line
135
+ and multiline modes.
136
+ test_files: []
137
+ has_rdoc: