Repository: JEG2/highline (ruby)

Issue:
Does not support CTRL-U in password mode
Type "helloCTRL-Uworld"

``` ruby
ask("Usrename: ")                            -> "world"
ask("Password: "){|q| q.echo = false}  -> "hello\x15world"
```



Discussion:
Wow, you really type passwords like that?  :)

It's true that we have to setup some special terminal modes to avoid echoing the password.  That swallows some key combinations.  I have found that to be a problem thus far, but I'll take patches from people it bothers who can find a way around it.

Hi @GutenYe , just to be sure I'm understanding correctly. Are you expecting HighLine to "delete" all the line and come back to "home", so it would return only "world", not "hello\u0015world" ?

If so, I think we could try to do this. 
But, should we try to emulate all control keys from the terminal?

For most common purposes of the **echo = false** use cases, handling backspace correctly is enough.

Yeah, I'm not sure how much it's HighLine's responsibility to emulate full terminal behavior.  It seems weird to me that a simple HighLine call might erase my terminal screen.

We are currently planning the next major version of HighLine.  We will include a discussion of where to draw these lines in the plans we make for that release.

> Are you expecting HighLine to "delete" all the line 

Yes, that's what I wanted. 

Hi @gutenye,

Most projects that I know just delete (deprecate) old issues. But it's not the case here in HighLine. We don't give up! :smile: 
This issue has **more than 10 years**! Oh - MY - GOD!

The first release of "io/console" was 0.3 at October 16, 2011 (6,5 KB). But, not mature, and in a time that some of the releases were yanked.

The first "usable" release that I have notice is 0.4.1 at February 04, 2013 (8,5 KB) **AFTER** the opening of this issue.

You can see the whole release history at https://rubygems.org/gems/io-console/versions

The good news is that we currently have an "io/console" more mature with more features we could rely on so we don't have to take all the responsibilities for the console inside HighLine's code.

I've just merged a PR that solves handling "CTRL-C" by relying on "io/console" functionalities that were released with Ruby version 2.7.0 at December, 2019 (when this issue had 7 years old.
Then I remembered about this old issue over here and this improvements in "io/console" gave me some hope.
I can't promise, but I'll be trying to solve it.

Is there any GitHub badge for solving a 10 years old issue? :smile: 

Hey @JEG2 keep an eye on this? Perhaps we take a picture of an "anniversary cake" for the issue. 

Patch:
diff --git a/lib/highline.rb b/lib/highline.rb
--- a/lib/highline.rb
+++ b/lib/highline.rb
@@ -546,6 +546,9 @@ def get_line_raw_no_echo_mode(question)
         if character == "\b" || character == "\u007F"
           chopped = line.chop!
           output_erase_char if chopped && question.echo
+        elsif character == "\cU"
+          line.size.times { output_erase_char } if question.echo
+          line = ""
         elsif character == "\e"
           ignore_arrow_key
         else


Test patch:
diff --git a/test/test_highline.rb b/test/test_highline.rb
--- a/test/test_highline.rb
+++ b/test/test_highline.rb
@@ -349,6 +349,44 @@ def test_after_some_chars_backspace_does_not_enter_prompt_when_utf8
     assert_equal(4, @output.string.count("\b"))
   end
 
+  def test_erase_line_does_not_enter_prompt
+    @input << "\cU\cU\cU\cU\cU\cU\cU\cU\cU"
+    @input.rewind
+    answer = @terminal.ask("Please enter your password: ") do |q|
+      q.echo = "*"
+    end
+    assert_equal("", answer)
+    assert_equal("Please enter your password: \n", @output.string)
+
+    # There's no backspaces as the line is already empty
+    assert_equal(0, @output.string.count("\b"))
+  end
+
+  def test_after_some_chars_erase_line_does_not_enter_prompt_when_ascii
+    @input << "apple\cU\cU\cU\cU\cU\cU\cU\cU"
+    @input.rewind
+    answer = @terminal.ask("Please enter your password: ") do |q|
+      q.echo = "*"
+    end
+    assert_equal("", answer)
+
+    # There's only enough backspaces to clear the given string
+    assert_equal(5, @output.string.count("\b"))
+  end
+
+
+  def test_after_some_chars_erase_line_does_not_enter_prompt_when_utf8
+    @input << "maçã\cU\cU\cU\cU\cU\cU\cU\cU"
+    @input.rewind
+    answer = @terminal.ask("Please enter your password: ") do |q|
+      q.echo = "*"
+    end
+    assert_equal("", answer)
+
+    # There's only enough backspaces to clear the given string
+    assert_equal(4, @output.string.count("\b"))
+  end
+
   def test_readline_mode
     #
     # Rubinius (and JRuby) seems to be ignoring