tty-screen 0.7.1 → 0.8.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/README.md +2 -2
- data/lib/tty/screen.rb +177 -115
- data/lib/tty/screen/version.rb +1 -1
- metadata +35 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e17bafe91486f49afff31f04968d8515502eb3065f3739a796f987bd0ffed96
|
4
|
+
data.tar.gz: 80112f9584cfc84a1c76eeeff88e08cac08853714c4d6e179aa92ad753bb9175
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3a00a8c1cfa355c988f7999fdd2d3bd49b903cf7be4d3446cb50e8fa5bc8c17b96b9a6be7f329299ba0f6eb58a54744c2a64ccec9d9a3255498c02bbb37d876
|
7
|
+
data.tar.gz: 73a02084a05564198f93fc5bc09b1db6d2eb90d426fbc0ce0d93f965b487c240d5a5c303f651c8afacc6b688c0e0780a1bc0953c0d39fca534432d8aca8eaf44
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## [v0.8.0] - 2020-05-28
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* Add #windows? platform check
|
7
|
+
* Add #command_exist? to see if an executable exists before running it
|
8
|
+
* Add performance tests
|
9
|
+
|
10
|
+
### Changed
|
11
|
+
* Change #jruby? method to hoist within module
|
12
|
+
* Change #size_from_win_api to check only on windows platform and
|
13
|
+
hoist definition within module
|
14
|
+
* Change #size_from_java to hoist within module
|
15
|
+
* Change #size_from_ioctl to:
|
16
|
+
* check solaris-like system
|
17
|
+
* scan all streams to see if any attached to a terminal
|
18
|
+
* hoist definition within module
|
19
|
+
* Change #size_from_io_console to perform check on JRuby as well
|
20
|
+
* Change #size_from_readline to attempt to load readline gem
|
21
|
+
* Change #run_command to execute command directly without sub shell or temp files
|
22
|
+
|
3
23
|
## [v0.7.1] - 2020-02-02
|
4
24
|
|
5
25
|
### Changed
|
@@ -111,6 +131,7 @@
|
|
111
131
|
### Fixed
|
112
132
|
* Fix bug with screen detection from_io_console by @luxflux
|
113
133
|
|
134
|
+
[v0.8.0]: https://github.com/piotrmurach/tty-screen/compare/v0.7.1...v0.8.0
|
114
135
|
[v0.7.1]: https://github.com/piotrmurach/tty-screen/compare/v0.7.0...v0.7.1
|
115
136
|
[v0.7.0]: https://github.com/piotrmurach/tty-screen/compare/v0.6.5...v0.7.0
|
116
137
|
[v0.6.5]: https://github.com/piotrmurach/tty-screen/compare/v0.6.4...v0.6.5
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
<div align="center">
|
2
|
-
<a href="https://piotrmurach.github.io/tty" target="_blank"><img width="130" src="https://
|
2
|
+
<a href="https://piotrmurach.github.io/tty" target="_blank"><img width="130" src="https://github.com/piotrmurach/tty/raw/master/images/tty.png" alt="tty logo" /></a>
|
3
3
|
</div>
|
4
4
|
|
5
5
|
# TTY::Screen [][gitter]
|
@@ -19,7 +19,7 @@
|
|
19
19
|
[coverage]: https://coveralls.io/r/piotrmurach/tty-screen
|
20
20
|
[inchpages]: http://inch-ci.org/github/piotrmurach/tty-screen
|
21
21
|
|
22
|
-
> Terminal screen size detection which works on Linux, OS X and Windows/Cygwin platforms and supports MRI, JRuby and Rubinius interpreters.
|
22
|
+
> Terminal screen size detection which works on Linux, OS X and Windows/Cygwin platforms and supports MRI, JRuby, TruffleRuby and Rubinius interpreters.
|
23
23
|
|
24
24
|
**TTY::Screen** provides independent terminal screen size detection component for [TTY](https://github.com/piotrmurach/tty) toolkit.
|
25
25
|
|
data/lib/tty/screen.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
begin
|
4
|
+
require "rbconfig"
|
5
|
+
rescue LoadError
|
6
|
+
end
|
7
|
+
|
8
|
+
require_relative "screen/version"
|
4
9
|
|
5
10
|
module TTY
|
6
11
|
# Used for detecting screen properties
|
@@ -13,6 +18,22 @@ module TTY
|
|
13
18
|
private_class_method(name)
|
14
19
|
end
|
15
20
|
|
21
|
+
case (defined?(::RbConfig) ? ::RbConfig::CONFIG["host_os"] : ::RUBY_PLATFORM)
|
22
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
23
|
+
def windows?; true end
|
24
|
+
else
|
25
|
+
def windows?; false end
|
26
|
+
end
|
27
|
+
module_function :windows?
|
28
|
+
|
29
|
+
case (defined?(::RbConfig) ? ::RbConfig::CONFIG["ruby_install_name"] : ::RUBY_ENGINE)
|
30
|
+
when /jruby/
|
31
|
+
def jruby?; true end
|
32
|
+
else
|
33
|
+
def jruby?; false end
|
34
|
+
end
|
35
|
+
module_function :jruby?
|
36
|
+
|
16
37
|
# Default terminal size
|
17
38
|
#
|
18
39
|
# @api public
|
@@ -22,10 +43,11 @@ module TTY
|
|
22
43
|
@output = $stderr
|
23
44
|
|
24
45
|
class << self
|
46
|
+
# Holds the environment variables
|
47
|
+
# @api public
|
25
48
|
attr_accessor :env
|
26
49
|
|
27
50
|
# Specifies an output stream
|
28
|
-
#
|
29
51
|
# @api public
|
30
52
|
attr_accessor :output
|
31
53
|
end
|
@@ -33,20 +55,20 @@ module TTY
|
|
33
55
|
# Get terminal rows and columns
|
34
56
|
#
|
35
57
|
# @return [Array[Integer, Integer]]
|
36
|
-
# return rows
|
58
|
+
# return rows and columns
|
37
59
|
#
|
38
60
|
# @api public
|
39
|
-
def size
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
61
|
+
def size(verbose: false)
|
62
|
+
size_from_java(verbose: verbose) ||
|
63
|
+
size_from_win_api(verbose: verbose) ||
|
64
|
+
size_from_ioctl ||
|
65
|
+
size_from_io_console(verbose: verbose) ||
|
66
|
+
size_from_readline(verbose: verbose) ||
|
67
|
+
size_from_tput ||
|
68
|
+
size_from_stty ||
|
69
|
+
size_from_env ||
|
70
|
+
size_from_ansicon ||
|
71
|
+
size_from_default
|
50
72
|
end
|
51
73
|
module_function :size
|
52
74
|
|
@@ -70,35 +92,49 @@ module TTY
|
|
70
92
|
module_function :rows
|
71
93
|
module_function :lines
|
72
94
|
|
73
|
-
|
95
|
+
# Default size for the terminal
|
96
|
+
#
|
97
|
+
# @return [Array[Integer, Integer]]
|
98
|
+
#
|
99
|
+
# @api private
|
100
|
+
def size_from_default
|
101
|
+
DEFAULT_SIZE
|
102
|
+
end
|
103
|
+
module_function :size_from_default
|
74
104
|
|
75
105
|
# Determine terminal size with a Windows native API
|
76
106
|
#
|
77
107
|
# @return [nil, Array[Integer, Integer]]
|
78
108
|
#
|
79
109
|
# @api private
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
kernel32[
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
110
|
+
if windows?
|
111
|
+
STDOUT_HANDLE = 0xFFFFFFF5
|
112
|
+
|
113
|
+
def size_from_win_api(verbose: false)
|
114
|
+
require "fiddle" unless defined?(Fiddle)
|
115
|
+
|
116
|
+
kernel32 = Fiddle::Handle.new("kernel32")
|
117
|
+
get_std_handle = Fiddle::Function.new(kernel32["GetStdHandle"],
|
118
|
+
[-Fiddle::TYPE_INT], Fiddle::TYPE_INT)
|
119
|
+
get_console_buffer_info = Fiddle::Function.new(
|
120
|
+
kernel32["GetConsoleScreenBufferInfo"],
|
121
|
+
[Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
|
122
|
+
|
123
|
+
format = "SSSSSssssSS"
|
124
|
+
buffer = ([0] * format.size).pack(format)
|
125
|
+
stdout_handle = get_std_handle.(STDOUT_HANDLE)
|
126
|
+
|
127
|
+
get_console_buffer_info.(stdout_handle, buffer)
|
128
|
+
_, _, _, _, _, left, top, right, bottom, = buffer.unpack(format)
|
129
|
+
size = [bottom - top + 1, right - left + 1]
|
130
|
+
return size if nonzero_column?(size[1] - 1)
|
131
|
+
rescue LoadError
|
132
|
+
warn "no native fiddle module found" if verbose
|
133
|
+
rescue Fiddle::DLError
|
134
|
+
# non windows platform or no kernel32 lib
|
135
|
+
end
|
136
|
+
else
|
137
|
+
def size_from_win_api(verbose: false); nil end
|
102
138
|
end
|
103
139
|
module_function :size_from_win_api
|
104
140
|
|
@@ -107,15 +143,19 @@ module TTY
|
|
107
143
|
# @return [nil, Array[Integer, Integer]]
|
108
144
|
#
|
109
145
|
# @api private
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
146
|
+
if jruby?
|
147
|
+
def size_from_java(verbose: false)
|
148
|
+
require "java"
|
149
|
+
|
150
|
+
java_import "jline.TerminalFactory"
|
151
|
+
terminal = TerminalFactory.get
|
152
|
+
size = [terminal.get_height, terminal.get_width]
|
153
|
+
return size if nonzero_column?(size[1])
|
154
|
+
rescue
|
155
|
+
warn "failed to import java terminal package" if verbose
|
156
|
+
end
|
157
|
+
else
|
158
|
+
def size_from_java(verbose: false); nil end
|
119
159
|
end
|
120
160
|
module_function :size_from_java
|
121
161
|
|
@@ -128,62 +168,75 @@ module TTY
|
|
128
168
|
# @return [nil, Array[Integer, Integer]]
|
129
169
|
#
|
130
170
|
# @api private
|
131
|
-
def size_from_io_console(verbose:
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
rescue Errno::EOPNOTSUPP
|
141
|
-
# no support for winsize on output
|
142
|
-
end
|
171
|
+
def size_from_io_console(verbose: false)
|
172
|
+
require "io/console" unless IO.method_defined?(:winsize)
|
173
|
+
|
174
|
+
return unless @output.tty? && @output.respond_to?(:winsize)
|
175
|
+
|
176
|
+
size = @output.winsize
|
177
|
+
size if nonzero_column?(size[1])
|
178
|
+
rescue Errno::EOPNOTSUPP
|
179
|
+
# no support for winsize on output
|
143
180
|
rescue LoadError
|
144
|
-
warn
|
181
|
+
warn "no native io/console support or io-console gem" if verbose
|
145
182
|
end
|
146
183
|
module_function :size_from_io_console
|
147
184
|
|
148
|
-
|
149
|
-
|
185
|
+
if !jruby? && @output.respond_to?(:ioctl)
|
186
|
+
TIOCGWINSZ = 0x5413 # linux
|
187
|
+
TIOCGWINSZ_PPC = 0x40087468 # macos, freedbsd, netbsd, openbsd
|
188
|
+
TIOCGWINSZ_SOL = 0x5468 # solaris
|
150
189
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
190
|
+
# Read terminal size from Unix ioctl
|
191
|
+
#
|
192
|
+
# @return [nil, Array[Integer, Integer]]
|
193
|
+
#
|
194
|
+
# @api private
|
195
|
+
def size_from_ioctl
|
196
|
+
format = "SSSS"
|
197
|
+
buffer = ([0] * format.size).pack(format)
|
198
|
+
|
199
|
+
if ioctl?(TIOCGWINSZ, buffer) ||
|
200
|
+
ioctl?(TIOCGWINSZ_PPC, buffer) ||
|
201
|
+
ioctl?(TIOCGWINSZ_SOL, buffer)
|
202
|
+
|
203
|
+
rows, cols, = buffer.unpack(format)[0..1]
|
204
|
+
return [rows, cols] if nonzero_column?(cols)
|
205
|
+
end
|
165
206
|
end
|
166
|
-
end
|
167
|
-
module_function :size_from_ioctl
|
168
207
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
208
|
+
# Check if ioctl can be called and any of the streams is
|
209
|
+
# attached to a terminal.
|
210
|
+
#
|
211
|
+
# @return [Boolean]
|
212
|
+
# True if any of the streams is attached to a terminal, false otherwise.
|
213
|
+
#
|
214
|
+
# @api private
|
215
|
+
def ioctl?(control, buf)
|
216
|
+
($stdout.ioctl(control, buf) >= 0) ||
|
217
|
+
($stdin.ioctl(control, buf) >= 0) ||
|
218
|
+
($stderr.ioctl(control, buf) >= 0)
|
219
|
+
rescue SystemCallError
|
220
|
+
false
|
221
|
+
end
|
222
|
+
module_function :ioctl?
|
223
|
+
else
|
224
|
+
def size_from_ioctl; nil end
|
176
225
|
end
|
177
|
-
module_function :
|
226
|
+
module_function :size_from_ioctl
|
178
227
|
|
179
228
|
# Detect screen size using Readline
|
180
229
|
#
|
181
230
|
# @api private
|
182
|
-
def size_from_readline
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
231
|
+
def size_from_readline(verbose: false)
|
232
|
+
require "readline" unless defined?(::Readline)
|
233
|
+
|
234
|
+
return unless ::Readline.respond_to?(:get_screen_size)
|
235
|
+
|
236
|
+
size = ::Readline.get_screen_size
|
237
|
+
size if nonzero_column?(size[1])
|
238
|
+
rescue LoadError
|
239
|
+
warn "no readline gem" if verbose
|
187
240
|
rescue NotImplementedError
|
188
241
|
end
|
189
242
|
module_function :size_from_readline
|
@@ -192,11 +245,13 @@ module TTY
|
|
192
245
|
#
|
193
246
|
# @api private
|
194
247
|
def size_from_tput
|
195
|
-
return unless @output.tty?
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
248
|
+
return unless @output.tty? && command_exist?("tput")
|
249
|
+
|
250
|
+
lines = run_command("tput", "lines")
|
251
|
+
return unless lines
|
252
|
+
|
253
|
+
cols = run_command("tput", "cols")
|
254
|
+
[lines.to_i, cols.to_i] if nonzero_column?(lines)
|
200
255
|
end
|
201
256
|
module_function :size_from_tput
|
202
257
|
|
@@ -204,12 +259,13 @@ module TTY
|
|
204
259
|
#
|
205
260
|
# @api private
|
206
261
|
def size_from_stty
|
207
|
-
return unless @output.tty?
|
208
|
-
|
262
|
+
return unless @output.tty? && command_exist?("stty")
|
263
|
+
|
264
|
+
out = run_command("stty", "size")
|
209
265
|
return unless out
|
266
|
+
|
210
267
|
size = out.split.map(&:to_i)
|
211
268
|
size if nonzero_column?(size[1])
|
212
|
-
rescue IOError, SystemCallError
|
213
269
|
end
|
214
270
|
module_function :size_from_stty
|
215
271
|
|
@@ -224,8 +280,9 @@ module TTY
|
|
224
280
|
#
|
225
281
|
# @api private
|
226
282
|
def size_from_env
|
227
|
-
return unless @env[
|
228
|
-
|
283
|
+
return unless @env["COLUMNS"] =~ /^\d+$/
|
284
|
+
|
285
|
+
size = [(@env["LINES"] || @env["ROWS"]).to_i, @env["COLUMNS"].to_i]
|
229
286
|
size if nonzero_column?(size[1])
|
230
287
|
end
|
231
288
|
module_function :size_from_env
|
@@ -234,24 +291,34 @@ module TTY
|
|
234
291
|
#
|
235
292
|
# @api private
|
236
293
|
def size_from_ansicon
|
237
|
-
return unless @env[
|
294
|
+
return unless @env["ANSICON"] =~ /\((.*)x(.*)\)/
|
295
|
+
|
238
296
|
size = [$2, $1].map(&:to_i)
|
239
297
|
size if nonzero_column?(size[1])
|
240
298
|
end
|
241
299
|
module_function :size_from_ansicon
|
242
300
|
|
301
|
+
# Check if command exists
|
302
|
+
#
|
303
|
+
# @return [Boolean]
|
304
|
+
#
|
305
|
+
# @api private
|
306
|
+
def command_exist?(command)
|
307
|
+
exts = env.fetch("PATHEXT", "").split(::File::PATH_SEPARATOR)
|
308
|
+
env.fetch("PATH", "").split(File::PATH_SEPARATOR).any? do |dir|
|
309
|
+
file = ::File.join(dir, command)
|
310
|
+
::File.exist?(file) || exts.any? { |ext| ::File.exist?("#{file}#{ext}") }
|
311
|
+
end
|
312
|
+
end
|
313
|
+
private_module_function :command_exist?
|
314
|
+
|
243
315
|
# Runs command silently capturing the output
|
244
316
|
#
|
245
317
|
# @api private
|
246
318
|
def run_command(*args)
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
return if result.nil?
|
251
|
-
out.rewind
|
252
|
-
out.read
|
253
|
-
ensure
|
254
|
-
out.close if out
|
319
|
+
%x(#{args.join(" ")})
|
320
|
+
rescue IOError, SystemCallError
|
321
|
+
nil
|
255
322
|
end
|
256
323
|
private_module_function :run_command
|
257
324
|
|
@@ -264,10 +331,5 @@ module TTY
|
|
264
331
|
column.to_i > 0
|
265
332
|
end
|
266
333
|
private_module_function :nonzero_column?
|
267
|
-
|
268
|
-
def jruby?
|
269
|
-
RbConfig::CONFIG['ruby_install_name'] == 'jruby'
|
270
|
-
end
|
271
|
-
private_module_function :jruby?
|
272
334
|
end # Screen
|
273
335
|
end # TTY
|
data/lib/tty/screen/version.rb
CHANGED
metadata
CHANGED
@@ -1,17 +1,45 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tty-screen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
12
|
-
dependencies:
|
11
|
+
date: 2020-05-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
13
41
|
description: Terminal screen size detection which works on Linux, OS X and Windows/Cygwin
|
14
|
-
platforms and supports MRI, JRuby and Rubinius interpreters.
|
42
|
+
platforms and supports MRI, JRuby, TruffleRuby and Rubinius interpreters.
|
15
43
|
email:
|
16
44
|
- piotr@piotrmurach.com
|
17
45
|
executables: []
|
@@ -19,6 +47,7 @@ extensions: []
|
|
19
47
|
extra_rdoc_files:
|
20
48
|
- README.md
|
21
49
|
- CHANGELOG.md
|
50
|
+
- LICENSE.txt
|
22
51
|
files:
|
23
52
|
- CHANGELOG.md
|
24
53
|
- LICENSE.txt
|
@@ -55,5 +84,5 @@ rubygems_version: 3.1.2
|
|
55
84
|
signing_key:
|
56
85
|
specification_version: 4
|
57
86
|
summary: Terminal screen size detection which works on Linux, OS X and Windows/Cygwin
|
58
|
-
platforms and supports MRI, JRuby and Rubinius interpreters.
|
87
|
+
platforms and supports MRI, JRuby, TruffleRuby and Rubinius interpreters.
|
59
88
|
test_files: []
|