2

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?

Community
  • 1
  • 1
Nomid
  • 91
  • 8
  • `.is_a? NilClass` - why? There's only one instance of `NilClass` and that's `nil`. If you want to be explicit - you don't have to be - use `== nil` or `.nil?`. – cremno Jun 27 '15 at 16:22
  • @cremno because according to the documentation (http://ruby-doc.org/core-2.2.0/Regexp.html) for 2.2.0, the `=~` operator returns nil... So using `.nil?` would check it, thanks. – Nomid Jun 27 '15 at 16:30

1 Answers1

3

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

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
  • Ok, I got it, I need to move up a line. – Nomid Jun 27 '15 at 16:35
  • Thanks, Sergio. Does this work for both Windows and Linux terminals? – Nomid Jun 27 '15 at 16:42
  • on a posix terminal it should work. windows - I think not. It's not a real terminal, you know :) – Sergio Tulentsev Jun 27 '15 at 16:47
  • 1
    ANSI escape sequences are even supported on Windows (by any modern CRuby version at least): `print "\e[A\e[2K"` (moves cursor one line up and clears the line). Of course, using `curses` or `highline` (a more high level library) might be preferable. – cremno Jun 27 '15 at 16:48
  • @cremno Hm, didn't know about this escape code. Want to post an answer? :) – Sergio Tulentsev Jun 27 '15 at 16:51
  • @cremno I'll give a look to `curses` and `highline` – Nomid Jun 27 '15 at 16:51
  • @cremno `print "\e[A\e[2K"` doesn't work... I tried it, and Ubuntu's console just shows `[A[2K> ` – Nomid Jun 27 '15 at 16:58
  • @cremno I faced up the problem, `print` is not the right function. `$stdout.write` does the trick. – Nomid Jun 27 '15 at 17:10
  • @Nomid: That's weird but good to hear that you've found a solution. `colorize` also uses them (see `p "> ".red`) but maybe your shell differentiates between color and cursor ones. I'd recommend looking at [`highline`](https://github.com/JEG2/highline) anyway. – cremno Jun 27 '15 at 17:14
  • Ok, I'll check them. I don't know why `print` doesn't work. – Nomid Jun 27 '15 at 17:22