mini_term 0.1.0

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.
@@ -0,0 +1,71 @@
1
+ # coding: utf-8
2
+
3
+ # Link Ruby to the Windows API calls needed by MiniTerm
4
+ module MiniTerm
5
+
6
+ # The magic numbers for the handles.
7
+ STDIN_ID = -10
8
+ STDOUT_ID = -11
9
+
10
+ # MiniTerm needs to retrieve standard handles.
11
+ get_handle_proc = Win32API.new("kernel32", "GetStdHandle", ['L'], 'L')
12
+
13
+ define_singleton_method(:get_handle) do |handle_index|
14
+ get_handle_proc.call(handle_index)
15
+ end
16
+
17
+ # Well, stdout's handle in particular.
18
+ def self.stdout_handle
19
+ get_handle(STDOUT_ID)
20
+ end
21
+
22
+ # Well, stdin's handle in particular.
23
+ def self.stdin_handle
24
+ get_handle(STDIN_ID)
25
+ end
26
+
27
+ # MiniTerm needs to get the current stdin mode
28
+ get_mode_proc = Win32API.new("kernel32", "GetConsoleMode", ['L', 'P'], 'I')
29
+
30
+ define_singleton_method(:get_console_mode) do |buffer|
31
+ get_mode_proc.call(stdin_handle, buffer)
32
+ end
33
+
34
+ # MiniTerm needs to set the current stdin mode
35
+ set_mode_proc = Win32API.new("kernel32", "SetConsoleMode", ['L', 'L'], 'I')
36
+
37
+ define_singleton_method(:set_console_mode) do |new_mode|
38
+ set_mode_proc.call(stdin_handle, new_mode)
39
+ end
40
+
41
+ # MiniTerm needs to retrieve screen info.
42
+ get_screen_info_proc = Win32API.new("kernel32",
43
+ "GetConsoleScreenBufferInfo",
44
+ ['L','P'], 'L')
45
+
46
+ define_singleton_method(:get_screen_info) do |buffer|
47
+ get_screen_info_proc.call(stdout_handle, buffer)
48
+ end
49
+
50
+ # MiniTerm needs to move the cursor about.
51
+ set_cursor_posn_proc = Win32API.new("kernel32",
52
+ "SetConsoleCursorPosition",
53
+ ['L','L'], 'L')
54
+
55
+ define_singleton_method(:set_cursor_posn) do |position|
56
+ set_cursor_posn_proc.call(stdout_handle, position)
57
+ end
58
+
59
+ # MiniTerm needs to know if any keystrokes are waiting.
60
+ getch_proc = Win32API.new("msvcrt", "_getch", [], 'I')
61
+ define_singleton_method(:getch) { getch_proc.call.chr }
62
+
63
+ # MiniTerm needs to get a single character in raw mode.
64
+ kbhit_proc = Win32API.new("msvcrt", "_kbhit", [], 'I')
65
+ define_singleton_method(:kbhit) { kbhit_proc.call }
66
+
67
+ # MiniTerm needs to make some noise.
68
+ beep_proc = Win32API.new("user32", "MessageBeep", ['L'], '0')
69
+ define_singleton_method(:beep) { beep_proc.call(0); self }
70
+
71
+ end
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+
3
+ # MiniTerm needs to put text on the screen! (Windows Specific Code)
4
+ module MiniTerm
5
+
6
+ # Put some text onto the screen.
7
+ def self.print(text)
8
+ STDOUT.print(text)
9
+ self
10
+ end
11
+
12
+ # See link.rb for the beep method.
13
+
14
+ # Clear the screen and home the cursor
15
+ def self.clear_screen
16
+ system("cls")
17
+ self
18
+ end
19
+
20
+ end
@@ -0,0 +1,50 @@
1
+ # coding: utf-8
2
+
3
+ # Get input from the user in raw mode. (Windows Specific Code)
4
+ module MiniTerm
5
+
6
+ # The sleep interval waiting for a key to be pressed.
7
+ WAIT_SLEEP = 0.02
8
+ TERM_MODE_MASK = 0xFFFFFFFF
9
+ ENABLE_LINE_INPUT = 0x00000002
10
+ ENABLE_PROCESSED_INPUT = 0x00000001
11
+
12
+ # Is there a character waiting?
13
+ def self.has_raw_char?
14
+ raw { kbhit != 0 }
15
+ end
16
+
17
+ # Get a uncooked character keystroke.
18
+ def self.get_raw_char
19
+ fail MiniTermNotRaw, "Not in raw mode." unless raw?
20
+
21
+ while (kbhit == 0)
22
+ sleep(WAIT_SLEEP)
23
+ end
24
+
25
+ getch
26
+ end
27
+
28
+ private
29
+
30
+ # Get user input uncooked, with no echo or buffering.
31
+ def self.begin_raw_input
32
+ @saved_mode = get_term_mode
33
+
34
+ mask = TERM_MODE_MASK ^
35
+ (@options[:pass_ctrl_s] ? ENABLE_LINE_INPUT : 0) ^
36
+ (@options[:pass_ctrl_c] ? ENABLE_PROCESSED_INPUT : 0)
37
+
38
+ # Clear the ENABLE_LINE_INPUT and ENABLE_PROCESSED_INPUT flags.
39
+ # See https://docs.microsoft.com/en-us/windows/console/setconsolemode
40
+ set_term_mode(@saved_mode & mask)
41
+ @raw_input = true
42
+ end
43
+
44
+ # Done with raw mode for now.
45
+ def self.end_raw_input
46
+ set_term_mode(@saved_mode)
47
+ @raw_input = false
48
+ end
49
+
50
+ end
@@ -0,0 +1,12 @@
1
+ # coding: utf-8
2
+
3
+ # Give MiniTerm control of the cursor position. (Windows Specific Code)
4
+ module MiniTerm
5
+
6
+ # Set the row (optional) and column of the cursor.
7
+ def self.set_posn(row: get_cursor_row, column:)
8
+ set_cursor_posn(row * 65536 + column)
9
+ self
10
+ end
11
+
12
+ end
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+
3
+ # Get size info about the console window. (Windows Specific Code)
4
+ module MiniTerm
5
+
6
+ # Get term_info [rows, cols]
7
+ def self.term_info
8
+ raw_buffer = 0.chr * 24
9
+ get_screen_info(raw_buffer)
10
+
11
+ width = (raw_buffer[0,2].unpack('S'))[0]
12
+ _left, top, _right, bottom = raw_buffer[10,8].unpack('SSSS')
13
+
14
+ [bottom - top + 1, width]
15
+ end
16
+
17
+ private
18
+
19
+ # Get the current terminal mode.
20
+ def self.get_term_mode
21
+ raw_buffer = 0.chr * 8
22
+ get_console_mode(raw_buffer)
23
+ raw_buffer[0,4].unpack('L')[0]
24
+ end
25
+
26
+ # Get the current terminal mode.
27
+ def self.set_term_mode(new_mode)
28
+ set_console_mode(new_mode)
29
+ end
30
+
31
+ # Get the current row of the cursor.
32
+ def self.get_cursor_row
33
+ raw_buffer = 0.chr * 24
34
+ get_screen_info(raw_buffer)
35
+ (raw_buffer[6,2].unpack('S'))[0]
36
+ end
37
+
38
+ end
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+
3
+ # Replacement support for deprecated win_32_api gem, with thanks to the
4
+ # ConnorAtherton/rb-readline project from where this code originates.
5
+ module MiniTerm
6
+
7
+ require 'fiddle'
8
+
9
+ #The classic Win32API gem is deprecated, so we emulate it with fiddle.
10
+ class Win32API
11
+ DLL = {}
12
+ TYPES = {"0" => Fiddle::TYPE_VOID,
13
+ "S" => Fiddle::TYPE_VOIDP,
14
+ "I" => Fiddle::TYPE_LONG}
15
+
16
+ def initialize(dll_name, func, import, export = "0", _ct = nil)
17
+ @proto = import.join.tr("VPpNnLlIi", "0SSI").chomp('0').split('')
18
+ handle = DLL[dll_name] ||= Fiddle.dlopen(dll_name)
19
+ @func = Fiddle::Function.new(handle[func], TYPES.values_at(*@proto), 1)
20
+ end
21
+
22
+ def call(*args)
23
+ args.each_with_index do |x, i|
24
+ if @proto[i] == "S"
25
+ args[i] = [x == 0 ? nil : x].pack("p").unpack("l!*")[0]
26
+ end
27
+ end
28
+
29
+ @func.call(*args).to_i
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+
3
+ # Get appropriate access to Windows API calls
4
+ if MiniTerm.java?
5
+ require 'win32api'
6
+ else
7
+ require_relative 'windows/win_32_api'
8
+ end
9
+
10
+ require_relative 'windows/link'
11
+ require_relative 'windows/term_info'
12
+ require_relative 'windows/set_posn'
13
+ require_relative 'windows/raw_input'
14
+ require_relative 'windows/output'
15
+
16
+ module MiniTerm
17
+
18
+ # What options are supported in this Windows?
19
+ VALID_OPTIONS = [:quiet, :strict, :pass_ctrl_s, :pass_ctrl_c].freeze
20
+
21
+ end
data/lib/mini_term.rb ADDED
@@ -0,0 +1,62 @@
1
+ # coding: utf-8
2
+
3
+ require 'rbconfig'
4
+
5
+ require_relative "mini_term/common/char_defs"
6
+ require_relative "mini_term/common/term_info"
7
+ require_relative "mini_term/common/raw_input"
8
+ require_relative "mini_term/common/mapper"
9
+ require_relative "mini_term/common/mapped_input"
10
+ require_relative "mini_term/version"
11
+
12
+ # A simple, portable terminal interface object. (Common Code)
13
+ module MiniTerm
14
+ host_os = RbConfig::CONFIG['host_os']
15
+
16
+ #What operating platform is in effect?
17
+ TERM_PLATFORM =
18
+ case host_os
19
+ when /mswin|msys|mingw|bccwin|wince|emc/
20
+ :windows
21
+ when /cygwin/
22
+ :cygwin
23
+ when /darwin|mac os/
24
+ :macosx
25
+ when /linux/
26
+ :linux
27
+ when /solaris|bsd/
28
+ :unix
29
+ else
30
+ raise "Unknown os: #{host_os.inspect}"
31
+ end
32
+
33
+ TERM_TYPE = (TERM_PLATFORM == :windows) ? :windows : :ansi
34
+
35
+ #Is Java present in the environment?
36
+ TERM_JAVA = (RUBY_PLATFORM =~ /java/) ? true : false
37
+
38
+ # Is this Windows?
39
+ def self.windows?
40
+ TERM_TYPE == :windows
41
+ end
42
+
43
+ # Is this ANSI?
44
+ def self.ansi?
45
+ TERM_TYPE == :ansi
46
+ end
47
+
48
+ # Are we running under Java?
49
+ def self.java?
50
+ TERM_JAVA
51
+ end
52
+ end
53
+
54
+ # Load in the appropriate code.
55
+ if MiniTerm.windows?
56
+ require_relative 'mini_term/windows'
57
+ elsif MiniTerm.ansi?
58
+ require_relative 'mini_term/ansi'
59
+ else
60
+ # This should never happen unless incorrect changes are made.
61
+ fail MiniTermWTF, "Invalid terminal type: #{MiniTerm::TERM_TYPE.inspect}"
62
+ end
data/mini_term.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "mini_term/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mini_term"
8
+ spec.version = MiniTerm::VERSION
9
+ spec.authors = ["PeterCamilleri"]
10
+ spec.email = ["peter.c.camilleri@gmail.com"]
11
+ spec.homepage = "https://github.com/PeterCamilleri/mini_term"
12
+
13
+ spec.summary = %q{A portable encapsulation of the console terminal.}
14
+ spec.description = %q{A portable encapsulation of the console terminal. } +
15
+ %q{Supports Linux, Mac, Windows, and Cygwin. }
16
+ spec.license = "MIT"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ f.match(%r{^(test|docs)/})
20
+ end
21
+
22
+ spec.require_paths = ["lib"]
23
+ spec.bindir = "exe"
24
+ spec.executables = spec
25
+ .files
26
+ .reject { |f| f.downcase == 'exe/readme.md'}
27
+ .grep(%r{^exe/}) { |f| File.basename(f) }
28
+
29
+ spec.required_ruby_version = '>=2.0'
30
+
31
+ spec.add_development_dependency "bundler", "~> 1.15"
32
+ spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_development_dependency "minitest", "~> 5.0"
34
+ spec.add_development_dependency 'minitest_visible', "~> 0.1"
35
+ spec.add_development_dependency 'reek', "~> 5.0.2"
36
+ end
data/rakefile.rb ADDED
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+ require 'rake/testtask'
3
+ require "bundler/gem_tasks"
4
+
5
+ Rake::TestTask.new(:test) do |t|
6
+ t.libs << "test"
7
+ t.libs << "lib"
8
+ t.test_files = FileList["test/**/*_test.rb"]
9
+ end
10
+
11
+ task :default => :test
12
+
13
+ desc "Run a scan for smelly code!"
14
+ task :reek do |t|
15
+ `reek --no-color lib > reek.txt`
16
+ end
17
+
18
+ desc "Fire up an IRB session with mini_term preloaded."
19
+ task :console do
20
+ system "ruby irbt.rb local"
21
+ end
22
+
23
+ desc "What version of mini_term is this?"
24
+ task :vers do |t|
25
+ puts
26
+ puts "mini_term version = #{MiniTerm::VERSION}"
27
+ end
28
+
29
+ desc "Alternative test procedure"
30
+ task :alt_test, :target do |t, args|
31
+ args.with_defaults(:target => 'test')
32
+ here = File.dirname(__FILE__)
33
+ target = "#{here}/#{args[:target]}/*.rb"
34
+ puts "Target files = #{target}"
35
+ puts
36
+
37
+ block = "{|file| require file if File.basename(file) =~ /test/}"
38
+ code = "Dir['#{target}'].each #{block}"
39
+
40
+ system "ruby -e\"#{code}\""
41
+ end
@@ -0,0 +1,30 @@
1
+ # A sample test map for use with the mapped_key_test program.
2
+ # These demonstrate overriding the mappings built into the program.
3
+
4
+ $mini_term_exit_info = {}
5
+
6
+ MiniTerm.add_map(:windows) do |map|
7
+
8
+ # Make local copies of the prefixes for brevity.
9
+ x00 = MiniTerm::PREFIX_00
10
+ xe0 = MiniTerm::PREFIX_E0
11
+
12
+ #The Cancel key
13
+ map["\e"] = :cancel
14
+
15
+ #End of Input
16
+ map["\x1A"] = :end_of_input
17
+
18
+ $mini_term_exit_info[:windows] = [:end_of_input, "Ctrl+z"]
19
+ end
20
+
21
+ MiniTerm.add_map(:ansi) do |map|
22
+
23
+ #The Cancel key
24
+ map["\f"] = :cancel
25
+
26
+ #End of Input
27
+ map["\ez"] = :end_of_input
28
+
29
+ $mini_term_exit_info[:ansi] = [:end_of_input, "Alt+z"]
30
+ end
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mini_term
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - PeterCamilleri
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-11-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.15'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.15'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest_visible
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: reek
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 5.0.2
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 5.0.2
83
+ description: 'A portable encapsulation of the console terminal. Supports Linux, Mac,
84
+ Windows, and Cygwin. '
85
+ email:
86
+ - peter.c.camilleri@gmail.com
87
+ executables:
88
+ - mapped_key_test
89
+ - mini_term_blizzard
90
+ - mini_term_code_points
91
+ - raw_key_test
92
+ extensions: []
93
+ extra_rdoc_files: []
94
+ files:
95
+ - ".gitignore"
96
+ - CODE_OF_CONDUCT.md
97
+ - Gemfile
98
+ - LICENSE.txt
99
+ - README.md
100
+ - exe/README.md
101
+ - exe/mapped_key_test
102
+ - exe/mini_term_blizzard
103
+ - exe/mini_term_code_points
104
+ - exe/raw_key_test
105
+ - irbt.rb
106
+ - lib/mini_term.rb
107
+ - lib/mini_term/ansi.rb
108
+ - lib/mini_term/ansi/output.rb
109
+ - lib/mini_term/ansi/raw_input.rb
110
+ - lib/mini_term/ansi/set_posn.rb
111
+ - lib/mini_term/ansi/term_info.rb
112
+ - lib/mini_term/common/char_defs.rb
113
+ - lib/mini_term/common/mapped_input.rb
114
+ - lib/mini_term/common/mapper.rb
115
+ - lib/mini_term/common/raw_input.rb
116
+ - lib/mini_term/common/term_info.rb
117
+ - lib/mini_term/exceptions.rb
118
+ - lib/mini_term/version.rb
119
+ - lib/mini_term/windows.rb
120
+ - lib/mini_term/windows/link.rb
121
+ - lib/mini_term/windows/output.rb
122
+ - lib/mini_term/windows/raw_input.rb
123
+ - lib/mini_term/windows/set_posn.rb
124
+ - lib/mini_term/windows/term_info.rb
125
+ - lib/mini_term/windows/win_32_api.rb
126
+ - mini_term.gemspec
127
+ - rakefile.rb
128
+ - samples/test_map.rb
129
+ homepage: https://github.com/PeterCamilleri/mini_term
130
+ licenses:
131
+ - MIT
132
+ metadata: {}
133
+ post_install_message:
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '2.0'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project:
149
+ rubygems_version: 2.5.2
150
+ signing_key:
151
+ specification_version: 4
152
+ summary: A portable encapsulation of the console terminal.
153
+ test_files: []