highline 1.5.0 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
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