io-console 0.9.2-java → 0.9.3-java

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1fd5a5305181bf526a7053c3303f099b0fa0e47d8791fa35c310e5af5ed5d5b9
4
- data.tar.gz: 9db378bc55068b6c1ca6e79b57be5955013d577307d8a5faf50f4869ac3e5108
3
+ metadata.gz: 81030a79e741f9fbea14484f4849da9e6efc1daf0784d6d9b7fc067cc3a95357
4
+ data.tar.gz: f3c862f8495b89a129d0547177530875456cb44fcdf4f7b76d9ddb81c110b08b
5
5
  SHA512:
6
- metadata.gz: 24b6dac4157c567a4caa5d6228375f38aa091de553ab8971dfe31c8a0c5af25c57c6b3c0235b6ba41ffc95711d8dfe85224c6486da85a50ceabddc57048a46fc
7
- data.tar.gz: 577c04bb5a8ff5808418a74bd7835c7a795c8998b0fecbe71954ffe166f47fdc9f66c3fbe018b37232b91cb567d207a65679d1a084e2131528a429fb2fae749c
6
+ metadata.gz: 6441ea13e62add5a11937381834077352406e0fd96a4cd7ded00e6fbcdc08a4c0e1376aa9b42ec35a3aba9b68ca7a6e5b0b8eddd4086cec960cabc1d6a1565f4
7
+ data.tar.gz: 28f42664fef6544ae6cffcf2ebc09e921155c302c8cf8da85e3ff584697d5a98bf1893bccddf76cfe68fa391a3b7f86ebb97ffb2ab6eb6dd299ecdf19b055c3b
@@ -102,13 +102,19 @@ module IO::Console
102
102
  end
103
103
  private :ttymode_yield
104
104
 
105
- TTY_RAW = Proc.new do |t, min: 1, time: nil, intr: nil|
105
+ TTY_SET_MIN = Proc.new do |t, min|
106
+ t[:c_cc][LibC::VMIN] = min ? min.to_i.clamp(0, 255) : 1
107
+ end
108
+
109
+ TTY_SET_TIME = Proc.new do |t, time|
110
+ t[:c_cc][LibC::VTIME] = time ? (time * 10).to_i.clamp(0, 255) : 0
111
+ end
112
+
113
+ TTY_RAW = Proc.new do |t, min: nil, time: nil, intr: nil|
106
114
  LibC.cfmakeraw(t.pointer)
107
115
  t[:c_lflag] &= ~(LibC::ECHOE|LibC::ECHOK)
108
- if min >= 0
109
- t[:c_cc][LibC::VMIN] = min
110
- end
111
- t[:c_cc][LibC::VTIME] = (time&.to_i || 0) * 10
116
+ TTY_SET_MIN[t, min]
117
+ TTY_SET_TIME[t, time]
112
118
  if intr
113
119
  t[:c_iflag] |= LibC::BRKINT
114
120
  t[:c_lflag] |= LibC::ISIG
@@ -116,18 +122,19 @@ module IO::Console
116
122
  end
117
123
  end
118
124
 
119
- def raw(*, min: 1, time: nil, intr: nil, &block)
125
+ def raw(*, min: nil, time: nil, intr: nil, &block)
120
126
  ttymode_yield(block, min:, time:, intr:, &TTY_RAW)
121
127
  end
122
128
 
123
- def raw!(*)
124
- ttymode(&TTY_RAW)
129
+ def raw!(*, min: 1, time: nil, intr: nil)
130
+ ttymode { |t| TTY_RAW.call(t, min:, time:, intr:) }
131
+ self
125
132
  end
126
133
 
127
134
  TTY_COOKED = Proc.new do |t|
128
135
  t[:c_iflag] |= (LibC::BRKINT|LibC::ISTRIP|LibC::ICRNL|LibC::IXON)
129
136
  t[:c_oflag] |= LibC::OPOST
130
- t[:c_lflag] |= (LibC::ECHO|LibC::ECHOE|LibC::ECHOK|LibC::ECHONL|LibC::ICANON|LibC::ISIG|LibC::IEXTEN)
137
+ t[:c_lflag] |= (TTY_ECHO|LibC::ICANON|LibC::ISIG|LibC::IEXTEN)
131
138
  end
132
139
 
133
140
  def cooked(*, &block)
@@ -157,6 +164,8 @@ module IO::Console
157
164
  ttymode_yield(block) { |t| t[:c_lflag] &= ~(TTY_ECHO) }
158
165
  end
159
166
 
167
+ private_constant :TTY_SET_TIME, :TTY_SET_MIN, :TTY_RAW, :TTY_COOKED, :TTY_ECHO
168
+
160
169
  class Mode
161
170
  attr_reader :termios
162
171
 
@@ -168,6 +177,11 @@ module IO::Console
168
177
  @termios = m.termios.dup
169
178
  end
170
179
 
180
+ def echo?
181
+ !(@termios[:c_lflag] & TTY_ECHO).zero?
182
+ end
183
+ alias echo echo?
184
+
171
185
  def echo=(echo)
172
186
  if echo
173
187
  @termios[:c_lflag] |= TTY_ECHO
@@ -186,6 +200,22 @@ module IO::Console
186
200
  TTY_RAW[new_mode.termios, min:, time:, intr:]
187
201
  new_mode
188
202
  end
203
+
204
+ def min
205
+ @termios[:c_cc][LibC::VMIN]
206
+ end
207
+
208
+ def min=(min)
209
+ TTY_SET_MIN[@termios, min]
210
+ end
211
+
212
+ def time
213
+ @termios[:c_cc][LibC::VTIME].quo(10)
214
+ end
215
+
216
+ def time=(time)
217
+ TTY_SET_TIME[@termios, time]
218
+ end
189
219
  end
190
220
 
191
221
  def console_mode
@@ -245,4 +275,5 @@ end
245
275
 
246
276
  class IO
247
277
  include Console
278
+ prepend PlatformTty if instance_method(:tty?).arity == 0
248
279
  end
@@ -118,11 +118,30 @@ end
118
118
 
119
119
  IO.prepend(IO::Console::Windows::TTY)
120
120
 
121
- class IO::ConsoleMode
121
+ class IO::Console::Mode
122
122
  def initialize(mode)
123
123
  @mode = mode
124
124
  end
125
125
 
126
+ def echo?
127
+ end
128
+ alias echo echo?
129
+
130
+ def echo=(echo)
131
+ end
132
+
133
+ def min
134
+ end
135
+
136
+ def min=(min)
137
+ end
138
+
139
+ def time
140
+ end
141
+
142
+ def time=(time)
143
+ end
144
+
126
145
  def virtual_terminal_processing?
127
146
  @mode & IO::Console::Windows::ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0
128
147
  end
@@ -151,7 +170,7 @@ end
151
170
 
152
171
  class IO
153
172
  def console_mode
154
- IO::ConsoleMode.new(IO::Console::Windows.console_mode(self))
173
+ IO::Console::Mode.new(IO::Console::Windows.console_mode(self))
155
174
  end
156
175
 
157
176
  def console_mode=(mode)
@@ -8,37 +8,97 @@ raise LoadError, "stty command not found" unless IO::Console::STTY
8
8
  warn "io/console on JRuby shells out to stty for most operations" if $VERBOSE
9
9
 
10
10
  class IO::Console::Mode
11
- def initialize(saved)
12
- @saved = saved
11
+ STTY_PATTERNS = /
12
+ (?<a>[a-z]\w*)\s(?:=\s(?:(?<n>\d+)|(?<c>\^.|.)|<undef>)|(?<n>\d+)(?:\s+\w+)?); |
13
+ (?<n>\d+)\s+(?<a>[a-z]\w*); |
14
+ (?<f>-)?(?<a>[a-z]\w*)(?=\s|$)
15
+ /x
16
+ private_constant :STTY_PATTERNS
17
+
18
+ def initialize(saved, attrs)
19
+ @saved = saved.chomp
20
+ @attrs = {}
21
+ attrs.scan(STTY_PATTERNS) do
22
+ m = $~
23
+ case attr = m[:a]
24
+ when "echo"
25
+ @attrs[attr.to_sym] = !m[:f]
26
+ when "min", "time"
27
+ @attrs[attr.to_sym] = m[:n]&.to_i
28
+ when *%w[brkint icanon isig opost]
29
+ @attrs[attr.to_sym] = !m[:f]
30
+ end
31
+ end
13
32
  @args = []
33
+ @changes = {}
14
34
  end
15
35
 
16
36
  def initialize_copy(mode)
17
37
  super
18
- @saved = mode.__send__(:saved).dup
19
- @args = mode.__send__(:args).dup
38
+ @attrs = @attrs.dup
39
+ @saved = @saved.dup
40
+ @args = @args.dup
41
+ @changes = @changes.dup
42
+ end
43
+
44
+ def arguments
45
+ [
46
+ @saved,
47
+ *@args,
48
+ *@changes.flat_map {|a, v|
49
+ case v
50
+ when true
51
+ a.to_s
52
+ when false
53
+ "-#{a}"
54
+ when nil
55
+ else
56
+ [a.to_s, v.to_s]
57
+ end
58
+ },
59
+ ]
20
60
  end
21
61
 
62
+ def echo?
63
+ @changes.fetch(:echo) {@attrs[:echo]}
64
+ end
65
+ alias echo echo?
66
+
22
67
  def echo=(echo)
23
- @args << (echo ? 'echo' : '-echo')
24
- echo
68
+ @changes[:echo] = echo
25
69
  end
26
70
 
27
- def raw(min: 1, time: nil, intr: nil)
71
+ def raw(min: nil, time: nil, intr: nil)
28
72
  dup.raw!(min:, time:, intr:)
29
73
  end
30
74
 
31
- def raw!(min: 1, time: nil, intr: nil)
75
+ def raw!(min: nil, time: nil, intr: nil)
32
76
  @args << 'raw'
33
- @args.push('min', min.to_s) if min >= 0
34
- @args.push('time', ((time || 0) * 10).to_i.to_s)
35
- @args.concat(%w[brkint isig opost]) if intr
77
+ self.min = min
78
+ self.time = time
79
+ %i[brkint isig opost].each {|a| @changes[a] = true} if intr
36
80
  self
37
81
  end
38
82
 
83
+ def min
84
+ @changes.fetch(:min) {@attrs[:min]}
85
+ end
86
+
87
+ def min=(min)
88
+ @changes[:min] = (min || 1).to_i.clamp(0, 255)
89
+ end
90
+
91
+ def time
92
+ @changes.fetch(:time) {@attrs[:time]}&.quo(10)
93
+ end
94
+
95
+ def time=(time)
96
+ @changes[:time] = ((time || 0) * 10).to_i.clamp(0, 255)
97
+ end
98
+
39
99
  private
40
100
 
41
- attr_reader :saved, :args
101
+ attr_reader :attrs, :saved, :args, :changes
42
102
  end
43
103
 
44
104
  # Non-Windows assumes stty command is available
@@ -72,8 +132,9 @@ class IO
72
132
  self.console_mode = saved if saved
73
133
  end
74
134
 
75
- def raw!(*)
76
- _io_console_stty('raw')
135
+ def raw!(*, min: 1, time: nil, intr: nil)
136
+ self.console_mode = console_mode.raw(min:, time:, intr:)
137
+ self
77
138
  end
78
139
 
79
140
  def cooked(*)
@@ -105,20 +166,20 @@ class IO
105
166
  end
106
167
 
107
168
  def console_mode
108
- Console::Mode.new(_io_console_stty('-g').chomp)
169
+ Console::Mode.new(_io_console_stty('-g'), _io_console_stty('-a'))
109
170
  end
110
171
 
111
172
  def console_mode=(mode)
112
- _io_console_stty(mode.__send__(:saved), *mode.__send__(:args))
173
+ _io_console_stty(*mode.arguments)
113
174
  mode
114
175
  end
115
176
 
116
- # Not all systems return same format of stty -a output
117
- IEEE_STD_1003_2 = '(?<rows>\d+) rows; (?<columns>\d+) columns'
118
- UBUNTU = 'rows (?<rows>\d+); columns (?<columns>\d+)'
119
-
120
177
  def winsize
121
- match = _io_console_stty('-a').match(/#{IEEE_STD_1003_2}|#{UBUNTU}/o)
178
+ # Pattern for rows/columns; all systems may not return in these formats.
179
+ match = /
180
+ (?<rows>\d+)\s+rows;\s*(?<columns>\d+)\s+columns |
181
+ rows\s+(?<rows>\d+);\s*columns\s+(?<columns>\d+)
182
+ /x.match(_io_console_stty('-a'))
122
183
  [match[:rows].to_i, match[:columns].to_i]
123
184
  end
124
185
 
@@ -127,7 +188,7 @@ class IO
127
188
  sizelen = size.size
128
189
 
129
190
  if sizelen != 2 && sizelen != 4
130
- raise ArgumentError.new("wrong number of arguments (given #{sizelen}, expected 2 or 4)")
191
+ raise ArgumentError, "wrong number of arguments (given #{sizelen}, expected 2 or 4)"
131
192
  end
132
193
 
133
194
  if sizelen == 4
@@ -147,4 +208,6 @@ class IO
147
208
 
148
209
  def ioflush
149
210
  end
211
+
212
+ prepend PlatformTty
150
213
  end
@@ -27,6 +27,18 @@ class IO
27
27
  yield self
28
28
  end
29
29
 
30
+ def min
31
+ end
32
+
33
+ def min=(n)
34
+ end
35
+
36
+ def time
37
+ end
38
+
39
+ def time=(t)
40
+ end
41
+
30
42
  def winsize
31
43
  [25, 80]
32
44
  end
@@ -6,7 +6,7 @@ end
6
6
 
7
7
  class IO
8
8
  # TODO: Windows version uses "conin$" and "conout$" instead of /dev/tty
9
- def self.console(sym = nil, *args)
9
+ def self.console(sym = nil, *args, **opts)
10
10
  raise TypeError, "expected Symbol, got #{sym.class}" unless sym.nil? || sym.kind_of?(Symbol)
11
11
 
12
12
  # klass = self == IO ? File : self
@@ -43,7 +43,8 @@ class IO
43
43
  @console = con
44
44
  end
45
45
 
46
- return con.send(sym, *args) if sym
46
+ return nil unless con
47
+ return con.send(sym, *args, **opts) if sym
47
48
  return con
48
49
  end
49
50
 
@@ -57,14 +58,11 @@ class IO
57
58
  wio = self == $stdin ? $stderr : self
58
59
  wio.write(prompt) if prompt
59
60
  begin
60
- str = nil
61
- noecho do
62
- str = gets
63
- end
61
+ str = noecho {gets("\n")}
64
62
  ensure
65
- puts($/)
63
+ puts
66
64
  end
67
- str.chomp
65
+ str&.chomp("\n")
68
66
  end
69
67
 
70
68
  def input_pending?
@@ -108,6 +106,7 @@ class IO
108
106
  end
109
107
  end
110
108
 
109
+ return nil unless b && result.length == 2
111
110
  result.map(&:pred)
112
111
  end
113
112
  end
@@ -162,9 +161,26 @@ class IO
162
161
 
163
162
  def getpass(prompt = nil)
164
163
  write(prompt) if prompt
165
- str = gets.chomp
166
- puts($/)
164
+ str = gets("\n")&.chomp("\n")
165
+ puts
167
166
  str
168
167
  end
169
168
  end
169
+
170
+ module PlatformTty # :nodoc:
171
+ def tty?(*modes)
172
+ modes.each do |mode|
173
+ case mode
174
+ when nil
175
+ when :any
176
+ when Symbol
177
+ raise ArgumentError, "unknown tty type: #{mode.inspect}"
178
+ else
179
+ raise TypeError, "wrong argument type #{mode.class} (expected Symbol)"
180
+ end
181
+ end
182
+ super()
183
+ end
184
+ end
185
+ private_constant :PlatformTty
170
186
  end
@@ -1,5 +1,5 @@
1
1
  class IO
2
2
  module Console
3
- VERSION = "0.9.2"
3
+ VERSION = "0.9.3"
4
4
  end
5
5
  end
@@ -37,6 +37,9 @@ class IO
37
37
  end
38
38
 
39
39
  backends = []
40
+ ENV["IO_CONSOLE_BACKEND"]&.then do |be|
41
+ backends.concat(be.split(",").map {|b| b.split(":")})
42
+ end&.first ||
40
43
  # If Linux or BSD, try to load the native version
41
44
  case RbConfig::CONFIG['host_os']
42
45
  when /darwin|openbsd|freebsd|netbsd/i
@@ -44,9 +47,7 @@ when /darwin|openbsd|freebsd|netbsd/i
44
47
  when /linux/i
45
48
  backends << %w[ffi/termios linux] << %w[stty]
46
49
  when /mswin|win32|ming/i
47
- require_relative 'console/constants/windows'
48
- require_relative 'console/backend/ffi/windows'
49
- return
50
+ backends << %w[ffi/windows windows]
50
51
  else
51
52
  backends << %w[stty]
52
53
  end
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: false
2
2
  # fallback to console window size
3
3
  def IO.default_console_size
4
+ lines = ENV["LINES"].to_i
5
+ columns = ENV["COLUMNS"].to_i
4
6
  [
5
- ENV["LINES"].to_i.nonzero? || 25,
6
- ENV["COLUMNS"].to_i.nonzero? || 80,
7
+ lines.positive? ? lines : 25,
8
+ columns.positive? ? columns : 80,
7
9
  ]
8
10
  end
9
11
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: io-console
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.3
5
5
  platform: java
6
6
  authors:
7
7
  - Nobu Nakada
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-08-10 00:00:00.000000000 Z
10
+ date: 2026-09-14 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: add console capabilities to IO instances.
13
13
  email: nobu@ruby-lang.org