tty-screen 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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](https://badges.gitter.im/Join%20Chat.svg)][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: []
|