highline 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  Below is a complete listing of changes for each revision of HighLine.
4
4
 
5
+ == 1.5.1
6
+
7
+ * Fixed the long standing echo true bug.
8
+ (reported by Lauri Tuominen)
9
+ * Improved Windows API calls to support the redirection of STDIN.
10
+ (patch by Aaron Simmons)
11
+ * Updated gem specification to avoid a deprecated call.
12
+ * Made a minor documentation clarification about character mode support.
13
+ * Worked around some API changes in Ruby's standard library in Ruby 1.9.
14
+ (patch by Jake Benilov)
15
+
5
16
  == 1.5.0
6
17
 
7
18
  * Fixed a bug that would prevent Readline from showing all completions.
data/Rakefile CHANGED
@@ -43,7 +43,7 @@ spec = Gem::Specification.new do |spec|
43
43
  delete_if { |item| item.include?("CVS") } +
44
44
  ["Rakefile", "setup.rb"]
45
45
 
46
- spec.test_suite_file = "test/ts_all.rb"
46
+ spec.test_files = "test/ts_all.rb"
47
47
  spec.has_rdoc = true
48
48
  spec.extra_rdoc_files = %w{README INSTALL TODO CHANGELOG LICENSE}
49
49
  spec.rdoc_options << '--title' << 'HighLine Documentation' <<
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby -w
2
+
3
+ # limit.rb
4
+ #
5
+ # Created by James Edward Gray II on 2008-11-12.
6
+ # Copyright 2008 Gray Productions. All rights reserved.
7
+
8
+ require "rubygems"
9
+ require "highline/import"
10
+
11
+ text = ask("Enter text (max 10 chars): ") { |q| q.limit = 10 }
12
+ puts "You entered: #{text}!"
@@ -9,14 +9,16 @@
9
9
  #
10
10
  # This is Free Software. See LICENSE and COPYING for details.
11
11
 
12
- require "highline/system_extensions"
13
- require "highline/question"
14
- require "highline/menu"
15
- require "highline/color_scheme"
16
12
  require "erb"
17
13
  require "optparse"
18
14
  require "stringio"
19
15
  require "abbrev"
16
+ require "highline/compatibility"
17
+ require "highline/system_extensions"
18
+ require "highline/question"
19
+ require "highline/menu"
20
+ require "highline/color_scheme"
21
+
20
22
 
21
23
  #
22
24
  # A HighLine object is a "high-level line oriented" shell over an input and an
@@ -29,7 +31,7 @@ require "abbrev"
29
31
  #
30
32
  class HighLine
31
33
  # The version of the installed library.
32
- VERSION = "1.5.0".freeze
34
+ VERSION = "1.5.1".freeze
33
35
 
34
36
  # An internal HighLine error. User code does not need to trap this.
35
37
  class QuestionError < StandardError
@@ -247,16 +249,20 @@ class HighLine
247
249
  end
248
250
  rescue QuestionError
249
251
  retry
250
- rescue ArgumentError
251
- explain_error(:invalid_type)
252
+ rescue ArgumentError, NameError => error
253
+ raise if error.is_a?(NoMethodError)
254
+ if error.message =~ /ambiguous/
255
+ # the assumption here is that OptionParser::Completion#complete
256
+ # (used for ambiguity resolution) throws exceptions containing
257
+ # the word 'ambiguous' whenever resolution fails
258
+ explain_error(:ambiguous_completion)
259
+ else
260
+ explain_error(:invalid_type)
261
+ end
252
262
  retry
253
263
  rescue Question::NoAutoCompleteMatch
254
264
  explain_error(:no_completion)
255
265
  retry
256
- rescue NameError
257
- raise if $!.is_a?(NoMethodError)
258
- explain_error(:ambiguous_completion)
259
- retry
260
266
  ensure
261
267
  @question = nil # Reset Question object.
262
268
  end
@@ -619,11 +625,11 @@ class HighLine
619
625
  else
620
626
  raw_no_echo_mode if stty = CHARACTER_MODE == "stty"
621
627
 
622
- line = ""
628
+ line = ""
623
629
  backspace_limit = 0
624
630
  begin
625
631
 
626
- while character = (stty ? @input.getc : get_character(@input))
632
+ while character = (stty ? @input.getbyte : get_character(@input))
627
633
  # honor backspace and delete
628
634
  if character == 127 or character == 8
629
635
  line.slice!(-1, 1)
@@ -646,7 +652,11 @@ class HighLine
646
652
  # do nothing
647
653
  end
648
654
  else
649
- @output.print(@question.echo)
655
+ if @question.echo == true
656
+ @output.print(character.chr)
657
+ else
658
+ @output.print(@question.echo)
659
+ end
650
660
  end
651
661
  @output.flush
652
662
  end
@@ -664,7 +674,7 @@ class HighLine
664
674
  @question.change_case(@question.remove_whitespace(line))
665
675
  end
666
676
  elsif @question.character == :getc
667
- @question.change_case(@input.getc.chr)
677
+ @question.change_case(@input.getbyte.chr)
668
678
  else
669
679
  response = get_character(@input).chr
670
680
  if @question.overwrite
@@ -719,9 +729,9 @@ class HighLine
719
729
  # newlines will not be affected by this process, but additional newlines
720
730
  # may be added.
721
731
  #
722
- def wrap( lines )
732
+ def wrap( text )
723
733
  wrapped = [ ]
724
- lines.each do |line|
734
+ text.each_line do |line|
725
735
  while line =~ /([^\n]{#{@wrap_at + 1},})/
726
736
  search = $1.dup
727
737
  replace = $1.dup
@@ -0,0 +1,17 @@
1
+ unless STDIN.respond_to?(:getbyte)
2
+ class IO
3
+ alias_method :getbyte, :getc
4
+ end
5
+
6
+ class StringIO
7
+ alias_method :getbyte, :getc
8
+ end
9
+ end
10
+
11
+ unless "".respond_to?(:each_line)
12
+
13
+ # Not a perfect translation, but sufficient for our needs.
14
+ class String
15
+ alias_method :each_line, :each
16
+ end
17
+ end
@@ -69,8 +69,9 @@ class HighLine
69
69
  #
70
70
  # Can be set to +true+ to use HighLine's cross-platform character reader
71
71
  # instead of fetching an entire line of input. (Note: HighLine's
72
- # character reader *ONLY* supports STDIN on Windows and Unix.) Can also
73
- # be set to <tt>:getc</tt> to use that method on the input stream.
72
+ # character reader *ONLY* supports STDIN on Windows and Unix and may not
73
+ # work correctly if STDIN is redirected.) Can also be set to <tt>:getc</tt>
74
+ # to use that method on the input stream.
74
75
  #
75
76
  # *WARNING*: The _echo_ and _overwrite_ attributes for a question are
76
77
  # ignored when using the <tt>:getc</tt> method.
@@ -27,32 +27,95 @@ class HighLine
27
27
  #
28
28
  # Windows savvy getc().
29
29
  #
30
- # *WARNING*: This method ignores <tt>input</tt> and reads one
31
- # character from +STDIN+!
32
30
  #
33
31
  def get_character( input = STDIN )
34
- Win32API.new("crtdll", "_getch", [ ], "L").Call
32
+ @stdin_handle ||= GetStdHandle(STD_INPUT_HANDLE)
33
+
34
+ begin
35
+ SetConsoleEcho(@stdin_handle, false)
36
+ input.getbyte
37
+ ensure
38
+ SetConsoleEcho(@stdin_handle, true)
39
+ end
35
40
  end
36
41
 
37
42
  # A Windows savvy method to fetch the console columns, and rows.
38
43
  def terminal_size
39
- m_GetStdHandle = Win32API.new( 'kernel32',
40
- 'GetStdHandle',
41
- ['L'],
42
- 'L' )
43
- m_GetConsoleScreenBufferInfo = Win32API.new(
44
- 'kernel32', 'GetConsoleScreenBufferInfo', ['L', 'P'], 'L'
45
- )
46
-
47
- format = 'SSSSSssssSS'
48
- buf = ([0] * format.size).pack(format)
49
- stdout_handle = m_GetStdHandle.call(0xFFFFFFF5)
44
+ stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE)
50
45
 
51
- m_GetConsoleScreenBufferInfo.call(stdout_handle, buf)
52
- bufx, bufy, curx, cury, wattr,
53
- left, top, right, bottom, maxx, maxy = buf.unpack(format)
46
+ bufx, bufy, curx, cury, wattr, left, top, right, bottom, maxx, maxy =
47
+ GetConsoleScreenBufferInfo(stdout_handle)
54
48
  return right - left + 1, bottom - top + 1
55
49
  end
50
+
51
+ # windows savvy console echo toggler
52
+ def SetConsoleEcho( console_handle, on )
53
+ mode = GetConsoleMode(console_handle)
54
+
55
+ # toggle the console echo bit
56
+ if on
57
+ mode |= ENABLE_ECHO_INPUT
58
+ else
59
+ mode &= ~ENABLE_ECHO_INPUT
60
+ end
61
+
62
+ ok = SetConsoleMode(console_handle, mode)
63
+ end
64
+
65
+ # win32 console APIs
66
+
67
+ STD_INPUT_HANDLE = -10
68
+ STD_OUTPUT_HANDLE = -11
69
+ STD_ERROR_HANDLE = -12
70
+
71
+ ENABLE_PROCESSED_INPUT = 0x0001
72
+ ENABLE_LINE_INPUT = 0x0002
73
+ ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002
74
+ ENABLE_ECHO_INPUT = 0x0004
75
+ ENABLE_WINDOW_INPUT = 0x0008
76
+ ENABLE_MOUSE_INPUT = 0x0010
77
+ ENABLE_INSERT_MODE = 0x0020
78
+ ENABLE_QUICK_EDIT_MODE = 0x0040
79
+
80
+ @@apiGetStdHandle = nil
81
+ @@apiGetConsoleMode = nil
82
+ @@apiSetConsoleMode = nil
83
+ @@apiGetConsoleScreenBufferInfo = nil
84
+
85
+ def GetStdHandle( handle_type )
86
+ @@apiGetStdHandle ||= Win32API.new( "kernel32", "GetStdHandle",
87
+ ['L'], 'L' )
88
+
89
+ @@apiGetStdHandle.call( handle_type )
90
+ end
91
+
92
+ def GetConsoleMode( console_handle )
93
+ @@apiGetConsoleMode ||= Win32API.new( "kernel32", "GetConsoleMode",
94
+ ['L', 'P'], 'I' )
95
+
96
+ mode = ' ' * 4
97
+ @@apiGetConsoleMode.call(console_handle, mode)
98
+ mode.unpack('L')[0]
99
+ end
100
+
101
+ def SetConsoleMode( console_handle, mode )
102
+ @@apiSetConsoleMode ||= Win32API.new( "kernel32", "SetConsoleMode",
103
+ ['L', 'L'], 'I' )
104
+
105
+ @@apiSetConsoleMode.call(console_handle, mode) != 0
106
+ end
107
+
108
+ def GetConsoleScreenBufferInfo( console_handle )
109
+ @@apiGetConsoleScreenBufferInfo ||=
110
+ Win32API.new( "kernel32", "GetConsoleScreenBufferInfo",
111
+ ['L', 'P'], 'L' )
112
+
113
+ format = 'SSSSSssssSS'
114
+ buf = ([0] * format.size).pack(format)
115
+ @@apiGetConsoleScreenBufferInfo.call(console_handle, buf)
116
+ buf.unpack(format)
117
+ end
118
+
56
119
  rescue LoadError # If we're not on Windows try...
57
120
  begin
58
121
  require "termios" # Unix, first choice.
@@ -73,7 +136,7 @@ class HighLine
73
136
 
74
137
  begin
75
138
  Termios.setattr(input, Termios::TCSANOW, new_settings)
76
- input.getc
139
+ input.getbyte
77
140
  ensure
78
141
  Termios.setattr(input, Termios::TCSANOW, old_settings)
79
142
  end
@@ -90,7 +153,7 @@ class HighLine
90
153
  raw_no_echo_mode
91
154
 
92
155
  begin
93
- input.getc
156
+ input.getbyte
94
157
  ensure
95
158
  restore_mode
96
159
  end
@@ -670,14 +670,14 @@ class TestHighLine < Test::Unit::TestCase
670
670
  assert_equal(animal, answer)
671
671
 
672
672
  @input.truncate(@input.rewind)
673
- @input << "6/16/76\n"
673
+ @input << "16th June 1976\n"
674
674
  @input.rewind
675
675
 
676
676
  answer = @terminal.ask("Enter your birthday.", Date)
677
677
  assert_instance_of(Date, answer)
678
678
  assert_equal(16, answer.day)
679
679
  assert_equal(6, answer.month)
680
- assert_equal(76, answer.year)
680
+ assert_equal(1976, answer.year)
681
681
 
682
682
  @input.truncate(@input.rewind)
683
683
  pattern = "^yes|no$"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: highline
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Edward Gray II
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-05 00:00:00 -06:00
12
+ date: 2009-05-07 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -30,6 +30,7 @@ files:
30
30
  - examples/asking_for_arrays.rb
31
31
  - examples/basic_usage.rb
32
32
  - examples/color_scheme.rb
33
+ - examples/limit.rb
33
34
  - examples/menus.rb
34
35
  - examples/overwrite.rb
35
36
  - examples/page_and_wrap.rb
@@ -37,6 +38,7 @@ files:
37
38
  - examples/trapping_eof.rb
38
39
  - examples/using_readline.rb
39
40
  - lib/highline/color_scheme.rb
41
+ - lib/highline/compatibility.rb
40
42
  - lib/highline/import.rb
41
43
  - lib/highline/menu.rb
42
44
  - lib/highline/question.rb