highline 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +9 -0
- data/Rakefile +11 -5
- data/lib/highline.rb +61 -80
- data/lib/highline/import.rb +1 -1
- data/lib/highline/menu.rb +1 -1
- data/lib/highline/question.rb +1 -1
- data/lib/highline/system_extensions.rb +103 -0
- data/test/tc_highline.rb +10 -3
- data/test/tc_menu.rb +11 -0
- data/test/ts_all.rb +1 -0
- metadata +4 -3
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 =
|
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
|
-
|
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
|
data/lib/highline.rb
CHANGED
@@ -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.
|
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
|
-
|
115
|
-
|
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
|
-
|
129
|
-
#
|
130
|
-
|
131
|
-
|
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
|
data/lib/highline/import.rb
CHANGED
@@ -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"
|
data/lib/highline/menu.rb
CHANGED
data/lib/highline/question.rb
CHANGED
@@ -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
|
data/test/tc_highline.rb
CHANGED
@@ -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
|
-
|
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
|
data/test/tc_menu.rb
CHANGED
@@ -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
|
data/test/ts_all.rb
CHANGED
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.
|
7
|
-
date: 2006-
|
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:
|
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
|