Giter Club home page Giter Club logo

tty-screen's Introduction

TTY Toolkit logo

TTY::Screen

Gem Version Actions CI Build status Code Climate Coverage Status

Terminal screen size detection that works on Linux, macOS and Windows systems and supports Ruby MRI, JRuby, TruffleRuby and Rubinius interpreters.

TTY::Screen provides a terminal screen size detection component for the TTY toolkit.

Installation

Add this line to your application's Gemfile:

gem "tty-screen"

And then execute:

$ bundle

Or install it yourself as:

$ gem install tty-screen

1. Usage

Use the size method to detect terminal screen size. It will result in a [height, width] array:

TTY::Screen.size  # => [51, 280]

Use the width, columns or cols method to detect terminal screen width:

TTY::Screen.width    # => 280
TTY::Screen.columns  # => 280
TTY::Screen.cols     # => 280

Use the height, lines or rows method to detect terminal screen height:

TTY::Screen.height  # => 51
TTY::Screen.lines   # => 51
TTY::Screen.rows    # => 51

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

Contributing

  1. Fork it ( https://github.com/piotrmurach/tty-screen/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the TTY::Screen project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

Copyright

Copyright (c) 2014 Piotr Murach. See LICENSE.txt for further details.

tty-screen's People

Contributors

kowal avatar luxflux avatar piotrmurach avatar tank-bohr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

tty-screen's Issues

"TTY::Screen#size_from_ioctl reads terminal size" test fails on big endian systems

Failures:

  1) TTY::Screen#size_from_ioctl reads terminal size
     Failure/Error: expect(screen.size_from_ioctl).to eq([51, 211])
     
       expected: [51, 211]
            got: [13056, 54016]
     
       (compared using ==)
     # ./spec/unit/screen_spec.rb:115:in `block (4 levels) in <top (required)>'
     # ./spec/unit/screen_spec.rb:108:in `replace_streams'
     # ./spec/unit/screen_spec.rb:114:in `block (3 levels) in <top (required)>'

According to our arch team testers this is an endianess error, when you take the numbers as big endian uint16 and convert them to little endian they match the expected values.

This can be reproduced by running the specs on a big-endian system such as hppa or sparc.

  • OS version: Gentoo Linux
  • Ruby version: 2.6.8
  • TTY::Screen version: 0.8.1

Our Gentoo downstream bug report for reference: https://bugs.gentoo.org/808174

Question re: screen resizing

What is the best way to get notified when the console screen is resized?

I've tried 'Signal.trap' w/o success.

I'm using Tmux and Terminator consoles.

Error with 0.8.0 - NoMethodError: undefined method `ioctl' for #<StringIO>

Problem

The new 0.8.0 version breaks some use case of tty-prompt.
I am not using tty-screen directly, but rather using tty-prompt. Until version 0.7.1 things worked, but with 0.8.0 I am getting the below error (pasted with a part of the backtrace, collapsed).

A little background: In all my CLIs that use TTY Prompt, I am testing by suppressing the STDOUT of the menu, and injecting keystrokes to STDIN. This approach breaks with 0.8.0, as demonstrated below.

NoMethodError: undefined method `ioctl' for #<StringIO:0x000055b7af74a2e0\>
     # /store/gems/ruby-2.7.0/gems/tty-screen-0.8.0/lib/tty/screen.rb:216:in `io
ctl?'
     # /store/gems/ruby-2.7.0/gems/tty-screen-0.8.0/lib/tty/screen.rb:199:in `si
ze_from_ioctl'
     # /store/gems/ruby-2.7.0/gems/tty-screen-0.8.0/lib/tty/screen.rb:64:in `siz
e'
     # /store/gems/ruby-2.7.0/gems/tty-screen-0.8.0/lib/tty/screen.rb:76:in `wid
th'
     # /store/gems/ruby-2.7.0/gems/tty-reader-0.7.0/lib/tty/reader.rb:337:in `co
unt_screen_lines'
     # /store/gems/ruby-2.7.0/gems/tty-prompt-0.21.0/lib/tty/prompt/list.rb:427:
in `block in question_lines_count'
     # /store/gems/ruby-2.7.0/gems/tty-prompt-0.21.0/lib/tty/prompt/list.rb:426:
in `each'
     # /store/gems/ruby-2.7.0/gems/tty-prompt-0.21.0/lib/tty/prompt/list.rb:426:
in `reduce'

Steps to reproduce the problem

Run ruby test.rb with the below test file:

# test.rb
require 'bundler/inline'
require 'stringio'

gemfile do
  source "https://rubygems.org"
  gem 'tty-prompt'
  # gem 'tty-screen', '= 0.7.1'  # works
  gem 'tty-screen', '= 0.8.0'    # BROKEN
  gem 'rspec'
end

class StringIO
  def wait_readable(*)
    true
  end

  ### tty-screen 0.8.0 works with this extra hack
  ### is this the best "solution?"
  # def ioctl(*)
  #   80
  # end
end

def stdin_send(*args)
  begin
    $stdin = StringIO.new
    $stdin.puts(args.shift) until args.empty?
    $stdin.rewind
    yield
  ensure
    $stdin = STDIN
  end
end

def supress_output
  original_stdout = $stdout
  $stdout = StringIO.new
  begin
    yield
  ensure
    $stdout = original_stdout
  end
end

down_arrow = "\e[B"
result = nil

supress_output do
  stdin_send "#{down_arrow}#{down_arrow}\n" do
    result = TTY::Prompt.new.select "Choose", [1,2,3]
  end
end

p "#{result} == 3"

Environment

See environment
$ uname -a
Linux vagrant 4.15.0-101-generic #102-Ubuntu SMP Mon May 11 10:07:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

$ ruby --version
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux]

$ gem list tty

*** LOCAL GEMS ***

pretty_trace (0.2.5)
tty-box (0.5.0)
tty-color (0.5.1)
tty-command (0.9.0)
tty-cursor (0.7.1)
tty-markdown (0.6.0)
tty-progressbar (0.17.0)
tty-prompt (0.21.0)
tty-reader (0.7.0)
tty-screen (0.8.0, 0.7.1)
tty-table (0.11.0)

Support reline after retiring ext/readline in ruby 3.3

Describe the problem

Ruby 3.3 retired ext/readline with reline https://www.ruby-lang.org/en/news/2023/12/25/ruby-3-3-0-released/

ext/readline is retired
- We have reline that is pure Ruby implementation compatible with ext/readline API. We rely on reline in the future. If you need to use ext/readline, you can install ext/readline via rubygems.org with gem install readline-ext.
- We no longer need to install libraries like libreadline or libedit.

Usage of readline, without explicitly installing ext/readline now raises an error

Drawbacks

Can you see any potential drawbacks?

I don't really know how would I implement that, should it be backward compatible or should we replace readline in every occurrence, as it is apparently the same API?

`TTY::Screen#size_from_ioctl reads terminal size` is failing in s390x

Describe the problem

The test TTY::Screen#size_from_ioctl reads terminal size is failing in s390x. This is happening in Debian and Ubuntu CI infrastructure:

https://ci.debian.net/data/autopkgtest/unstable/s390x/r/ruby-tty-screen/21749140/log.gz
https://autopkgtest.ubuntu.com/results/autopkgtest-kinetic/kinetic/s390x/r/ruby-tty-screen/20220519_210736_eb090@/log.gz

Steps to reproduce the problem

Run the test in a s390x machine.

Actual behaviour

Failures:

  1) TTY::Screen#size_from_ioctl reads terminal size
     Failure/Error: expect(screen.size_from_ioctl).to eq([51, 211])

       expected: [51, 211]
            got: [13056, 54016]

       (compared using ==)
     # ./spec/unit/screen_spec.rb:115:in `block (4 levels) in <top (required)>'
     # ./spec/unit/screen_spec.rb:108:in `replace_streams'
     # ./spec/unit/screen_spec.rb:114:in `block (3 levels) in <top (required)>'

Top 2 slowest examples (0.01432 seconds, 67.2% of total time):
  TTY::Screen#size_from_tput doesn't run command if outside of terminal
    0.00727 seconds ./spec/unit/screen_spec.rb:125
  TTY::Screen#size_from_ioctl reads terminal size
    0.00705 seconds ./spec/unit/screen_spec.rb:113

Finished in 0.02131 seconds (files took 0.07922 seconds to load)
26 examples, 1 failure

Expected behaviour

The test passes also in s390x.

Describe your environment

  • OS version: Debian unstable and Ubuntu 22.10
  • Ruby version: 3.0
  • TTY::Screen version: 0.8.1

tty/version.rb in both tty-screen and tty-cursor

I am trying to create debian packages for tty-cursor and tty-screen, yet both of them have a file tty/version.rb so that one will overwrite the other.
I would suggest to using tty/screen/version.rb and tty/cursor/version.rb instead.

Method size returns [1,1] on Windows (mingw) when no TTY is present

Describe the problem

Method size returns [1,1] on Windows (mingw) when no TTY is present. Caused by Readline.get_screen_size returning [1,1]

Steps to reproduce the problem

ssh my-windows-server 'ruby -e \"require \\\"tty-screen\\\"; puts TTY::Screen.size\"'

Actual behaviour

returns [1,1]

Expected behaviour

returns DEFAULT_SIZE

Describe your environment

  • OS version: Window 2019, SSH enabled, and the default shell is git-bash
  • Ruby version: 3.1.2p20 (2022-04-12 revision 4491bb740a)
  • TTY::Screen version: 0.8.1

Spurious "stty: standard input" output on stderr from TTY::Screen.size when running on Alpine Linux within a PTY.spawn process from within rspec

Under some circumstances, a ruby program using TTY::Screen.size can generate spurious stty-related output on stderr. So far I've only seen this happening on the very specific combination of Alpine Linux + rspec + Kommando.run (using PTY.spawn). It does not happen on Ubuntu xenial, presumably because of the different libc/coreutils implementation. It does not happen without rspec either.. no idea why, really.

This specific combination leads to spurious stty: standard input output in our e2e tests, causing them to fail: kontena/kontena#3058

I think the fix would be to have TTY::Screen#run_command suppress all stderr output (:err => '/dev/null').

Repro case

https://gist.github.com/SpComb/96f770d67922f384a9146c5520378e2c

The rspecs in this test case only fail when run in the Alpine Linux container. The same rspecs pass when run directly on e.g. Ubuntu xenial.

Usage

$ git clone https://gist.github.com/96f770d67922f384a9146c5520378e2c.git tty-screen-stty && cd tty-screen-stty
$ docker build -t test/tty-screen-stty .
$ docker run --rm --privileged test/tty-screen-stty

Example

kommando + stty
  outputs size when run with kommando (FAILED - 1)
  does not output stty errors (FAILED - 2)
  does not print to stderr when run directly
  runs with a pty

Failures:

  1) kommando + stty outputs size when run with kommando
     Failure/Error: expect(k.out).to match /\d+ \d+/

       expected "stty: standard input\r\n" to match /\d+ \d+/
       Diff:
       @@ -1,2 +1,2 @@
       -/\d+ \d+/
       +stty: standard input
     # /test_spec.rb:11:in `block (2 levels) in <top (required)>'

  2) kommando + stty does not output stty errors
     Failure/Error: expect(k.out).to_not match /stty: standard input/

       expected "execve(\"/bin/stty\", [\"stty\", \"size\"], [/* 3 vars */]) = 0\r\narch_prctl(ARCH_SET_FS, 0x7f8cf53...andard input\r\n)  = 21\r\nexit_group(0)                           = ?\r\n+++ exited with   0 +++\r\n" not to match /stty: standard input/
       Diff:
       @@ -1,2 +1,13 @@
       -/stty: standard input/
       +execve("/bin/stty", ["stty", "size"], [/* 3 vars */]) = 0
       +arch_prctl(ARCH_SET_FS, 0x7f8cf531ab48) = 0
       +set_tid_address(0x7f8cf531ab80)         = 13
       +mprotect(0x7f8cf5317000, 4096, PROT_READ) = 0
       +mprotect(0x5581f08e8000, 16384, PROT_READ) = 0
       +getuid()                                = 0
       +ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
       +ioctl(0, TIOCGWINSZ, {ws_row=0, ws_col=0, ws_xpixel=0, ws_ypixel=0}) = 0
       +write(2, "stty: standard input\n", 21stty: standard input
       +)  = 21
       +exit_group(0)                           = ?
       ++++ exited with 0 +++
     # /test_spec.rb:17:in `block (2 levels) in <top (required)>'

Finished in 0.08799 seconds (files took 0.13452 seconds to load)
4 examples, 2 failures

Failed examples:

rspec /test_spec.rb:9 # kommando + stty outputs size when run with kommando
rspec /test_spec.rb:14 # kommando + stty does not output stty errors

TTY::Screen.width not respecting my Terminal window size

Describe the problem

While using Fastlane, the width of the table when Fastlane displays the commands is defaulted to 80.

I know this repository is not fastlane, but it seems like the culprit is in print_table.rb > def transform_output(rows, transform: :newline) > number_of_cols = TTY::Screen.width.

I tried to fix this issue but to no avail with my given time. Tried debugging with logs such as:

def transform_output(rows, transform: :newline)
  ...
  number_of_cols = TTY::Screen.width
  puts "hello"
  puts number_of_cols

The above always prints out 80 even when I set my Terminal window to different size and width.

Steps to reproduce the problem

Run fastlane and the width of the available command is confined to 80, and it makes things hard to read.

Actual behaviour

The table width when I type fastlane is always the width of 80.

Expected behaviour

When I change my window width to X, the width should be X instead of 80.

Describe your environment

fastlane 2.108.0
macOS Terminal 2.9.1 (421.1)

  • OS version: macOS 10.14.1 Mojave
  • Ruby version: ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-darwin18]
  • TTY::Screen version: v0.6.5

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.