highline icon indicating copy to clipboard operation
highline copied to clipboard

Surprising behavior for character = true resp. character = :getc with stty

Open stomar opened this issue 12 years ago • 10 comments

I am trying to get a single character from the user in a "cleaner" way than with SystemExtensions.get_character, which is not well documented and feels rather like a hack to me (see also issue #50).

While playing around with the echo and character settings, I stumbled over two issues(?):

  1. The documentation is not very clear (at least to me) about the difference between character = true and character = :getc. When to choose which? Are they supposed to behave differently or is this only an implementation detail?
  2. I do not understand the behavior of character = true in the example code below (newline and indentation; examples one and three behave as expected).

Output:

Your password?
password: 12345
Answer [ynaq]?
               key: q (character = true)
Answer [ynaq]? key: q (character = :getc)

Code:

require 'rubygems'
require 'highline/import'

answer = ask("Your password? ") do |q|
           q.echo = false
         end
puts "password: #{answer}"

key = ask("Answer [ynaq]? ") do |q|
        q.echo = false
        q.character = true
      end
puts "key: #{key} (character = true)"

key = ask("Answer [ynaq]? ") do |q|
        q.character = :getc
      end
puts "key: #{key} (character = :getc)"

stomar avatar Dec 05 '12 12:12 stomar

Can you share the output of the following?

$ ruby -r highline -ve 'p [HighLine::VERSION, HighLine::SystemExtensions::CHARACTER_MODE]'

JEG2 avatar Dec 05 '12 14:12 JEG2

ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux]
["1.6.15", "stty"]

Same behavior with 1.9.3p327, 1.8.7p371 (using rvm) and system ruby (1.9.3p0)

stomar avatar Dec 05 '12 16:12 stomar

Thanks. I'll try to look into this when I get a chance.

JEG2 avatar Dec 05 '12 16:12 JEG2

Small update: I finally got termios installed (I used the wrong gem and gave up too early), and as you probably already know, with termios it works, the only difference between character = true and character = :getc is the newline in the former case, but there is no indentation.

stomar avatar Dec 06 '12 16:12 stomar

Yeah, termios is preferred. Still, stty should work better.

JEG2 avatar Dec 06 '12 16:12 JEG2

fyi I was having trouble with gem install termios and needed to do gem install ruby-termios instead... see this SO answer for more details

alexch avatar Jan 25 '13 19:01 alexch

Hi! I'm hitting what I think is the same problem… with character = true, I get indentation on the next puts

Code

require 'highline/import'

ask("question: ") { |q| q.character = true}
puts "text"

Output

❯ ./test.rb
question: y
           text
❯ ruby -r highline -ve 'p [HighLine::VERSION, HighLine::SystemExtensions::CHARACTER_MODE]'
ruby 2.0.0p481 (2014-05-08 revision 45883) [universal.x86_64-darwin14]
["1.7.2", "stty"]

I tried q.character = :getc but then I needed to add a newline the the next print… is there a way to work around this?

carlosefonseca avatar Jul 16 '15 09:07 carlosefonseca

A quick (and dirty) way to work around the issue is to prepend "\r" to the next string.

require 'highline/import'

ask("question: ") { |q| q.character = true }
puts "\rtext"

I'll be looking forward to fix it to the "reasonable expected behaviour". Thanks for reporting!

abinoam avatar Jul 16 '15 17:07 abinoam

@carlosefonseca I've just merged the workaround into 1-7-stable and into master Please tell me if it worked for you. When @JEG2 come back from vacation he'll make a gem release of them. But you are already able to install them manually if you like. I'll keep this issue open, as I'll review it later.

abinoam avatar Jul 16 '15 18:07 abinoam

The test above now works with the manual installation of highline! Thanks!

carlosefonseca avatar Jul 16 '15 18:07 carlosefonseca