Search code examples
rubycarriage-returngets

How to overwrite the current console line after gets in Ruby?


I have this piece of code:

def wait_for_input regex
  print "> ".red
  someInput = gets
  
  while (regex =~ someInput).is_a? NilClass do
    print "\r> ".red
    someInput = gets
    
    STDOUT.flush
  end
  
  someInput
end

The carriage return is supposed to overwrite the current line in console, but instead doesn't and the ">" goes in new line.

I tried removing the color from the string (library colorize) and writing $stdout.flush or STDOUT.flush following this topic with no luck.

Then I realized that it works if I remove the gets instruction.

How to overwrite the current line after gets?


Solution

  • Overwriting current line (printing "\r") works just fine with gets. The thing is, gets reads a line until (and including) a linebreak. So it is you, pressing ENTER, who moves cursor to a next line. And then this next, already empty, line is rewinded by \r.

    Moving to a previous line is not possible in the regular mode. (see comments) You need to use a lower-level terminal window access. curses is a popular library. Ruby has bindings for it. I suggest you start with this blog post (and follow-ups to it): http://graysoftinc.com/terminal-tricks/random-access-terminal