Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Carriage return is missing on asynchronous output while waiting for input #137

Closed
joe-p opened this issue May 17, 2020 · 1 comment
Closed

Comments

@joe-p
Copy link

joe-p commented May 17, 2020

Describe the problem

Anything written to STDOUT while waiting for input from the user will not have a carriage return, which results in strange formatting of the data written to STDOUT.

Steps to reproduce the problem

To reproduce this, send multiple lines of data to STDOUT while waiting for some user input (ie. TTY::Prompt#ask).

t = Thread.new do
  TTY::Prompt.new.ask('=>')
end

sleep 2

puts "one with no \\r"
puts "two with no \\r"
puts "three with no \\r"

puts "\rone with \\r"
puts "\rtwo with \\r"
puts "\rthree with \\r"
t.join

I thought this might have to do with malformed escapes for coloring, so I disabled color on the prompt and still had the same results.

Actual behaviour

=> one with no \r
                 two with no \r
                               three with no \r
one with \r
two with \r
three with \r

Expected behaviour

This is output from same code, except TTY::Prompt.new.ask('=>') has been replaced with print =>; readline

=>one with no \r
two with no \r
three with no \r
one with \r
two with \r
three with \r

Describe your environment

  • OS version: WSL2 Ubuntu (kernel 4.19.84-microsoft-standard)
  • Ruby version: 2.7.0p0
  • TTY version: 0.21.0
@piotrmurach
Copy link
Owner

Thanks for reporting and using tty-prompt.

This is consistent with how Ruby input works in the terminal raw mode. In order to process any keystroke, tty-prompt accepts input in a raw mode. Basically, the input is taken as is without any interpretation - a newline doesn't have any meaning apart from literal characters. This allows tty-prompt to provide nice editor behaviour like back and forward movement with arrow keys. You cannot do this in cooked mode. It's rather limited.

Here is your example changed to use raw mode:

t = Thread.new do
  $stdin.raw do
    print "=>"; $stdin.getc
  end
end

sleep 2

puts "one with no \\r"
puts "two with no \\r"
puts "three with no \\r"

puts "\rone with \\r"
puts "\rtwo with \\r"
puts "\rthree with \\r"
t.join

Which produces:

=>one with no \r
                two with no \r
                              three with no \r
one with \r
two with \r
three with \r

And here is the same script in cooked mode:

t = Thread.new do
  print "=>"; $stdin.getc
end

sleep 2

puts "one with no \\r"
puts "two with no \\r"
puts "three with no \\r"

puts "\rone with \\r"
puts "\rtwo with \\r"
puts "\rthree with \\r"
t.join

Which produces:

=>one with no \r
two with no \r
three with no \r
one with \r
two with \r
three with \r

Unfortunately, this is not a bug. It may not be ideal in your case but I don't see a way out of it apart from you using carriage return character.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants