summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG6
-rw-r--r--lib/highline.rb32
-rw-r--r--lib/highline/system_extensions.rb2
-rw-r--r--test/tc_highline.rb26
4 files changed, 60 insertions, 6 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 00b750a..4e35d20 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,10 +2,16 @@
Below is a complete listing of changes for each revision of HighLine.
+== 1.2.8
+
+* Fixed backspacing past the prompt and interrupting a prompt bugs.
+ (patch by Jeremy Hinegardner)
+
== 1.2.7
* Fixed the stty indent bug.
* Fixed the echo backspace bug.
+* Added HighLine::track_eof=() setting to work are threaded eof?() calls.
== 1.2.6
diff --git a/lib/highline.rb b/lib/highline.rb
index ce5dcd6..2b1e4bd 100644
--- a/lib/highline.rb
+++ b/lib/highline.rb
@@ -29,7 +29,7 @@ require "abbrev"
#
class HighLine
# The version of the installed library.
- VERSION = "1.2.7".freeze
+ VERSION = "1.2.8".freeze
# An internal HighLine error. User code does not need to trap this.
class QuestionError < StandardError
@@ -48,6 +48,19 @@ class HighLine
def self.use_color?
@@use_color
end
+
+ # The setting used to disable EOF tracking.
+ @@track_eof = true
+
+ # Pass +false+ to _setting_ to turn off HighLine's EOF tracking.
+ def self.track_eof=( setting )
+ @@track_eof = setting
+ end
+
+ # Returns true if HighLine is currently tracking EOF for input.
+ def self.track_eof?
+ @@track_eof
+ end
# The setting used to control color schemes.
@@color_scheme = nil
@@ -575,7 +588,8 @@ class HighLine
answer
else
- raise EOFError, "The input stream is exhausted." if @input.eof?
+ raise EOFError, "The input stream is exhausted." if @@track_eof and
+ @input.eof?
@question.change_case(@question.remove_whitespace(@input.gets))
end
@@ -600,21 +614,31 @@ class HighLine
raw_no_echo_mode if stty = CHARACTER_MODE == "stty"
line = ""
+ backspace_limit = 0
begin
+
while character = (stty ? @input.getc : get_character(@input))
# honor backspace and delete
if character == 127 or character == 8
line.slice!(-1, 1)
+ backspace_limit -= 1
else
line << character.chr
+ backspace_limit += 1
end
# looking for carriage return (decimal 13) or
# newline (decimal 10) in raw input
break if character == 13 or character == 10 or
(@question.limit and line.size == @question.limit)
if @question.echo != false
- if character == 127 or character == 8
- @output.print("\b#{ERASE_CHAR}")
+ if character == 127 or character == 8
+ # only backspace if we have characters on the line to
+ # eliminate, otherwise we'll tromp over the prompt
+ if backspace_limit >= 0 then
+ @output.print("\b#{ERASE_CHAR}")
+ else
+ # do nothing
+ end
else
@output.print(@question.echo)
end
diff --git a/lib/highline/system_extensions.rb b/lib/highline/system_extensions.rb
index 6f1e335..96d5aed 100644
--- a/lib/highline/system_extensions.rb
+++ b/lib/highline/system_extensions.rb
@@ -103,7 +103,7 @@ class HighLine
#
def raw_no_echo_mode
@state = `stty -g`
- system "stty raw -echo cbreak"
+ system "stty raw -echo cbreak isig"
end
#
diff --git a/test/tc_highline.rb b/test/tc_highline.rb
index 08ddb6b..2bddae7 100644
--- a/test/tc_highline.rb
+++ b/test/tc_highline.rb
@@ -132,6 +132,16 @@ class TestHighLine < Test::Unit::TestCase
assert_equal(2, answer)
assert_equal("Select an option (1, 2 or 3): *\n", @output.string)
end
+
+ def test_backspace_does_not_enter_prompt
+ @input << "\b\b"
+ @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)
+ end
def test_character_reading
# WARNING: This method does NOT cover Unix and Windows savvy testing!
@@ -143,7 +153,7 @@ class TestHighLine < Test::Unit::TestCase
end
assert_equal(1, answer)
end
-
+
def test_color
@terminal.say("This should be <%= BLUE %>blue<%= CLEAR %>!")
assert_equal("This should be \e[34mblue\e[0m!\n", @output.string)
@@ -771,6 +781,20 @@ class TestHighLine < Test::Unit::TestCase
assert_equal(("-=" * 40 + "\n") + ("-=" * 10 + "\n"), @output.string)
end
+ def test_track_eof
+ assert_raise(EOFError) { @terminal.ask("Any input left? ") }
+
+ # turn EOF tracking
+ old_setting = HighLine.track_eof?
+ assert_nothing_raised(Exception) { HighLine.track_eof = false }
+ begin
+ @terminal.ask("And now? ") # this will still blow up, nothing available
+ rescue
+ assert_not_equal(EOFError, $!.class) # but HighLine's safe guards are off
+ end
+ HighLine.track_eof = old_setting
+ end
+
def test_version
assert_not_nil(HighLine::VERSION)
assert_instance_of(String, HighLine::VERSION)