highline 1.2.0 → 1.2.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,15 @@
2
2
 
3
3
  Below is a complete listing of changes for each revision of HighLine.
4
4
 
5
+ == 1.2.1
6
+
7
+ * Applied Justin Bailey's fix for the page_print() infinite loop bug.
8
+ * Made a SystemExtensions module to expose OS level functionality other
9
+ libraries may want to access.
10
+ * Publicly exposed the get_character() method, per user requests.
11
+ * Added terminal_size(), output_cols(), and output_rows() methods.
12
+ * Added :auto setting for warp_at=() and page_at=().
13
+
5
14
  == 1.2.0
6
15
 
7
16
  * Improved RubyForge and gem spec project descriptions.
data/Rakefile CHANGED
@@ -4,6 +4,10 @@ require "rake/gempackagetask"
4
4
 
5
5
  require "rubygems"
6
6
 
7
+ dir = File.dirname(__FILE__)
8
+ lib = File.join(dir, "lib", "highline.rb")
9
+ version = File.read(lib)[/^\s*VERSION\s*=\s*(['"])(\d\.\d\.\d)\1/, 2]
10
+
7
11
  task :default => [:test]
8
12
 
9
13
  Rake::TestTask.new do |test|
@@ -32,7 +36,7 @@ end
32
36
 
33
37
  spec = Gem::Specification.new do |spec|
34
38
  spec.name = "highline"
35
- spec.version = "1.2.0"
39
+ spec.version = version
36
40
  spec.platform = Gem::Platform::RUBY
37
41
  spec.summary = "HighLine is a high-level command-line IO library."
38
42
  spec.files = Dir.glob("{examples,lib,test}/**/*.rb").
@@ -45,11 +49,8 @@ spec = Gem::Specification.new do |spec|
45
49
  spec.rdoc_options << '--title' << 'HighLine Documentation' <<
46
50
  '--main' << 'README'
47
51
 
48
- ### Removed due to Windows' install problems ###
49
- # spec.add_dependency("termios", ">= 0.9.4")
50
-
51
52
  spec.require_path = 'lib'
52
- spec.autorequire = "highline"
53
+
53
54
  spec.author = "James Edward Gray II"
54
55
  spec.email = "james@grayproductions.net"
55
56
  spec.rubyforge_project = "highline"
@@ -74,3 +75,8 @@ task :stats do
74
75
  ["Functionals", "examples"],
75
76
  ["Units", "test"] ).to_s
76
77
  end
78
+
79
+ desc "Add new files to Subversion"
80
+ task :add_to_svn do
81
+ sh %Q{svn status | ruby -nae 'system "svn add \#{$F[1]}" if $F[0] == "?"' }
82
+ end
@@ -7,8 +7,9 @@
7
7
  #
8
8
  # See HighLine for documentation.
9
9
  #
10
- # This is Free Software. See LICENSE and COPYING for details
10
+ # This is Free Software. See LICENSE and COPYING for details.
11
11
 
12
+ require "highline/system_extensions"
12
13
  require "highline/question"
13
14
  require "highline/menu"
14
15
  require "erb"
@@ -27,7 +28,7 @@ require "abbrev"
27
28
  #
28
29
  class HighLine
29
30
  # The version of the installed library.
30
- VERSION = "1.2.0".freeze
31
+ VERSION = "1.2.1".freeze
31
32
 
32
33
  # An internal HighLine error. User code does not need to trap this.
33
34
  class QuestionError < StandardError
@@ -111,8 +112,9 @@ class HighLine
111
112
  wrap_at = nil, page_at = nil )
112
113
  @input = input
113
114
  @output = output
114
- @wrap_at = wrap_at
115
- @page_at = page_at
115
+
116
+ self.wrap_at = wrap_at
117
+ self.page_at = page_at
116
118
 
117
119
  @question = nil
118
120
  @answer = nil
@@ -124,16 +126,12 @@ class HighLine
124
126
  @key = nil
125
127
  end
126
128
 
127
- #
128
- # Set to an integer value to cause HighLine to wrap output lines at the
129
- # indicated character limit. When +nil+, the default, no wrapping occurs.
130
- #
131
- attr_accessor :wrap_at
132
- #
133
- # Set to an integer value to cause HighLine to page output lines over the
134
- # indicated line limit. When +nil+, the default, no paging occurs.
135
- #
136
- attr_accessor :page_at
129
+ include HighLine::SystemExtensions
130
+
131
+ # The current column setting for wrapping output.
132
+ attr_reader :wrap_at
133
+ # The current row setting for paging output.
134
+ attr_reader :page_at
137
135
 
138
136
  #
139
137
  # A shortcut to HighLine.ask() a question that only accepts "yes" or "no"
@@ -414,6 +412,48 @@ class HighLine
414
412
  end
415
413
  end
416
414
 
415
+ #
416
+ # Set to an integer value to cause HighLine to wrap output lines at the
417
+ # indicated character limit. When +nil+, the default, no wrapping occurs. If
418
+ # set to <tt>:auto</tt>, HighLine will attempt to determing the columns
419
+ # available for the <tt>@output</tt> or use a sensible default.
420
+ #
421
+ def wrap_at=( setting )
422
+ @wrap_at = setting == :auto ? output_cols : setting
423
+ end
424
+
425
+ #
426
+ # Set to an integer value to cause HighLine to page output lines over the
427
+ # indicated line limit. When +nil+, the default, no paging occurs. If
428
+ # set to <tt>:auto</tt>, HighLine will attempt to determing the rows available
429
+ # for the <tt>@output</tt> or use a sensible default.
430
+ #
431
+ def page_at=( setting )
432
+ @page_at = setting == :auto ? output_rows : setting
433
+ end
434
+
435
+ #
436
+ # Returns the number of columns for the console, or a default it they cannot
437
+ # be determined.
438
+ #
439
+ def output_cols
440
+ return 80 unless @output.tty?
441
+ terminal_size.first
442
+ rescue
443
+ return 80
444
+ end
445
+
446
+ #
447
+ # Returns the number of rows for the console, or a default if they cannot be
448
+ # determined.
449
+ #
450
+ def output_rows
451
+ return 24 unless @output.tty?
452
+ terminal_size.last
453
+ rescue
454
+ return 24
455
+ end
456
+
417
457
  private
418
458
 
419
459
  #
@@ -475,69 +515,6 @@ class HighLine
475
515
 
476
516
  @answers
477
517
  end
478
-
479
- #
480
- # This section builds a character reading function to suit the proper
481
- # platform we're running on. Be warned: Here be dragons!
482
- #
483
- begin
484
- require "Win32API" # See if we're on Windows.
485
-
486
- CHARACTER_MODE = "Win32API" # For Debugging purposes only.
487
-
488
- #
489
- # Windows savvy getc().
490
- #
491
- # *WARNING*: This method ignores <tt>@input</tt> and reads one
492
- # character from +STDIN+!
493
- #
494
- def get_character
495
- Win32API.new("crtdll", "_getch", [ ], "L").Call
496
- end
497
- rescue LoadError # If we're not on Windows try...
498
- begin
499
- require "termios" # Unix, first choice.
500
-
501
- CHARACTER_MODE = "termios" # For Debugging purposes only.
502
-
503
- #
504
- # Unix savvy getc(). (First choice.)
505
- #
506
- # *WARNING*: This method requires the "termios" library!
507
- #
508
- def get_character
509
- old_settings = Termios.getattr(@input)
510
-
511
- new_settings = old_settings.dup
512
- new_settings.c_lflag &= ~(Termios::ECHO | Termios::ICANON)
513
-
514
- begin
515
- Termios.setattr(@input, Termios::TCSANOW, new_settings)
516
- @input.getc
517
- ensure
518
- Termios.setattr(@input, Termios::TCSANOW, old_settings)
519
- end
520
- end
521
- rescue LoadError # If our first choice fails, default.
522
- CHARACTER_MODE = "stty" # For Debugging purposes only.
523
-
524
- #
525
- # Unix savvy getc(). (Second choice.)
526
- #
527
- # *WARNING*: This method requires the external "stty" program!
528
- #
529
- def get_character
530
- state = `stty -g`
531
-
532
- begin
533
- system "stty raw -echo cbreak"
534
- @input.getc
535
- ensure
536
- system "stty #{state}"
537
- end
538
- end
539
- end
540
- end
541
518
 
542
519
  #
543
520
  # Read a line of input from the input stream and process whitespace as
@@ -596,7 +573,7 @@ class HighLine
596
573
  get_line
597
574
  else
598
575
  line = ""
599
- while character = get_character
576
+ while character = get_character(@input)
600
577
  line << character.chr
601
578
  # looking for carriage return (decimal 13) or
602
579
  # newline (decimal 10) in raw input
@@ -610,7 +587,7 @@ class HighLine
610
587
  elsif @question.character == :getc
611
588
  @question.change_case(@input.getc.chr)
612
589
  else
613
- response = get_character.chr
590
+ response = get_character(@input).chr
614
591
  echo = if @question.echo == true
615
592
  response
616
593
  elsif @question.echo != false
@@ -636,7 +613,7 @@ class HighLine
636
613
  while lines.size > @page_at
637
614
  @output.puts lines.slice!(0...@page_at).join
638
615
  @output.puts
639
- ask("-- press enter/return to continue -- ")
616
+ HighLine.new(@input, @output).ask("-- press enter/return to continue -- ")
640
617
  @output.puts
641
618
  end
642
619
  return lines.join
@@ -666,6 +643,10 @@ class HighLine
666
643
  return wrapped.join
667
644
  end
668
645
 
646
+ #
647
+ # Returns the length of the passed +string_with_escapes+, minus and color
648
+ # sequence escapes.
649
+ #
669
650
  def actual_length( string_with_escapes )
670
651
  string_with_escapes.gsub(/\e\[\d{1,2}m/, "").length
671
652
  end
@@ -5,7 +5,7 @@
5
5
  # Created by James Edward Gray II on 2005-04-26.
6
6
  # Copyright 2005 Gray Productions. All rights reserved.
7
7
  #
8
- # This is Free Software. See LICENSE and COPYING for details
8
+ # This is Free Software. See LICENSE and COPYING for details.
9
9
 
10
10
  require "highline"
11
11
  require "forwardable"
@@ -5,7 +5,7 @@
5
5
  # Created by Gregory Thomas Brown on 2005-05-10.
6
6
  # Copyright 2005. All rights reserved.
7
7
  #
8
- # This is Free Software. See LICENSE and COPYING for details
8
+ # This is Free Software. See LICENSE and COPYING for details.
9
9
 
10
10
  require "highline/question"
11
11
 
@@ -5,7 +5,7 @@
5
5
  # Created by James Edward Gray II on 2005-04-26.
6
6
  # Copyright 2005 Gray Productions. All rights reserved.
7
7
  #
8
- # This is Free Software. See LICENSE and COPYING for details
8
+ # This is Free Software. See LICENSE and COPYING for details.
9
9
 
10
10
  require "optparse"
11
11
  require "date"
@@ -0,0 +1,103 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # import.rb
4
+ #
5
+ # Created by James Edward Gray II on 2006-06-14.
6
+ # Copyright 2006 Gray Productions. All rights reserved.
7
+ #
8
+ # This is Free Software. See LICENSE and COPYING for details.
9
+
10
+ class HighLine
11
+ module SystemExtensions
12
+ module_function
13
+
14
+ #
15
+ # This section builds character reading and terminal size functions
16
+ # to suit the proper platform we're running on. Be warned: Here be
17
+ # dragons!
18
+ #
19
+ begin
20
+ require "Win32API" # See if we're on Windows.
21
+
22
+ CHARACTER_MODE = "Win32API" # For Debugging purposes only.
23
+
24
+ #
25
+ # Windows savvy getc().
26
+ #
27
+ # *WARNING*: This method ignores <tt>input</tt> and reads one
28
+ # character from +STDIN+!
29
+ #
30
+ def get_character( input = STDIN )
31
+ Win32API.new("crtdll", "_getch", [ ], "L").Call
32
+ end
33
+
34
+ # A Windows savvy method to fetch the console columns, and rows.
35
+ def terminal_size
36
+ m_GetStdHandle = Win32API.new( 'kernel32',
37
+ 'GetStdHandle',
38
+ ['L'],
39
+ 'L' )
40
+ m_GetConsoleScreenBufferInfo = Win32API.new(
41
+ 'kernel32', 'GetConsoleScreenBufferInfo', ['L', 'P'], 'L'
42
+ )
43
+
44
+ format = 'SSSSSssssSS'
45
+ buf = ([0] * format.size).pack(format)
46
+ stdout_handle = m_GetStdHandle.call(0xFFFFFFF5)
47
+
48
+ m_GetConsoleScreenBufferInfo.call(stdout_handle, buf)
49
+ bufx, bufy, curx, cury, wattr,
50
+ left, top, right, bottom, maxx, maxy = buf.unpack(format)
51
+ return right - left + 1, bottom - top + 1
52
+ end
53
+ rescue LoadError # If we're not on Windows try...
54
+ begin
55
+ require "termios" # Unix, first choice.
56
+
57
+ CHARACTER_MODE = "termios" # For Debugging purposes only.
58
+
59
+ #
60
+ # Unix savvy getc(). (First choice.)
61
+ #
62
+ # *WARNING*: This method requires the "termios" library!
63
+ #
64
+ def get_character( input = STDIN )
65
+ old_settings = Termios.getattr(input)
66
+
67
+ new_settings = old_settings.dup
68
+ new_settings.c_lflag &= ~(Termios::ECHO | Termios::ICANON)
69
+
70
+ begin
71
+ Termios.setattr(input, Termios::TCSANOW, new_settings)
72
+ input.getc
73
+ ensure
74
+ Termios.setattr(input, Termios::TCSANOW, old_settings)
75
+ end
76
+ end
77
+ rescue LoadError # If our first choice fails, default.
78
+ CHARACTER_MODE = "stty" # For Debugging purposes only.
79
+
80
+ #
81
+ # Unix savvy getc(). (Second choice.)
82
+ #
83
+ # *WARNING*: This method requires the external "stty" program!
84
+ #
85
+ def get_character( input = STDIN )
86
+ state = `stty -g`
87
+
88
+ begin
89
+ system "stty raw -echo cbreak"
90
+ input.getc
91
+ ensure
92
+ system "stty #{state}"
93
+ end
94
+ end
95
+ end
96
+
97
+ # A Unix savvy method to fetch the console columns, and rows.
98
+ def terminal_size
99
+ `stty size`.split.map { |x| x.to_i }.reverse
100
+ end
101
+ end
102
+ end
103
+ end
@@ -12,6 +12,15 @@ require "test/unit"
12
12
  require "highline"
13
13
  require "stringio"
14
14
 
15
+ if HighLine::CHARACTER_MODE == "Win32API"
16
+ class HighLine
17
+ # Override Windows' character reading so it's not tied to STDIN.
18
+ def get_character( input = STDIN )
19
+ input.getc
20
+ end
21
+ end
22
+ end
23
+
15
24
  class TestHighLine < Test::Unit::TestCase
16
25
  def setup
17
26
  @input = StringIO.new
@@ -374,9 +383,7 @@ class TestHighLine < Test::Unit::TestCase
374
383
  end
375
384
 
376
385
  def test_mode
377
- # *WARNING*: These tests wil only complete is "stty" mode!
378
- assert_equal( "stty", HighLine::CHARACTER_MODE,
379
- "Tests require \"stty\" mode." )
386
+ assert(%w[Win32API termios stty].include?(HighLine::CHARACTER_MODE))
380
387
  end
381
388
 
382
389
  class NameClass
@@ -395,4 +395,15 @@ class TestMenu < Test::Unit::TestCase
395
395
  end
396
396
  assert_equal(:quit, selected)
397
397
  end
398
+
399
+ def test_paged_print_infinite_loop_bug
400
+ @terminal.page_at = 5
401
+ # Will page twice, so start with two new lines
402
+ @input << "\n\n3\n"
403
+ @input.rewind
404
+
405
+ # Sadly this goes into an infinite loop without the fix to page_print
406
+ selected = @terminal.choose(* 1..10)
407
+ assert_equal(selected, 3)
408
+ end
398
409
  end
@@ -6,6 +6,7 @@
6
6
  # Copyright 2005 Gray Productions. All rights reserved.
7
7
  #
8
8
  # This is Free Software. See LICENSE and COPYING for details.
9
+
9
10
  require "test/unit"
10
11
 
11
12
  require "tc_highline"
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: highline
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.2.0
7
- date: 2006-03-22 00:00:00 -06:00
6
+ version: 1.2.1
7
+ date: 2006-06-14 00:00:00 -05:00
8
8
  summary: HighLine is a high-level command-line IO library.
9
9
  require_paths:
10
10
  - lib
@@ -12,7 +12,7 @@ email: james@grayproductions.net
12
12
  homepage: http://highline.rubyforge.org
13
13
  rubyforge_project: highline
14
14
  description: A high-level IO library that provides validation, type conversion, and more for command-line interfaces. HighLine also includes a complete menu system that can crank out anything from simple list selection to complete shells with just minutes of work.
15
- autorequire: highline
15
+ autorequire:
16
16
  default_executable:
17
17
  bindir: bin
18
18
  has_rdoc: true
@@ -40,6 +40,7 @@ files:
40
40
  - lib/highline/import.rb
41
41
  - lib/highline/menu.rb
42
42
  - lib/highline/question.rb
43
+ - lib/highline/system_extensions.rb
43
44
  - test/tc_highline.rb
44
45
  - test/tc_import.rb
45
46
  - test/tc_menu.rb