highline 1.0.4 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  Below is a complete listing of changes for each revision of HighLine.
4
4
 
5
+ == 1.2.0
6
+
7
+ * Improved RubyForge and gem spec project descriptions.
8
+ * Added basic examples to README.
9
+ * Added a VERSION constant.
10
+ * Added support for hidden menu commands.
11
+ * Added Object.or_ask() when using highline/import.
12
+
5
13
  == 1.0.4
6
14
 
7
15
  * Moved the HighLine project to Subversion.
data/README CHANGED
@@ -19,7 +19,39 @@ See HighLine and HighLine::Question for documentation.
19
19
 
20
20
  == Examples
21
21
 
22
- See the examples/ directory of this project for code examples.
22
+ Basic usage:
23
+
24
+ ask("Company? ") { |q| q.default = "none" }
25
+
26
+ Validation:
27
+
28
+ ask("Age? ", Integer) { |q| q.in = 0..105 }
29
+ ask("Name? (last, first) ") { |q| q.validate = /\A\w+, ?\w+\Z/ }
30
+
31
+ Type conversion for answers:
32
+
33
+ ask("Birthday? ", Date)
34
+ ask("Interests? (comma sep list) ", lambda { |str| str.split(/,\s*/) })
35
+
36
+ Reading passwords:
37
+
38
+ ask("Enter your password: ") { |q| q.echo = false }
39
+ ask("Enter your password: ") { |q| q.echo = "x" }
40
+
41
+ ERb based output (with HighLine's ANSI color tools):
42
+
43
+ say("This should be <%= color('bold', BOLD) %>!")
44
+
45
+ Menus:
46
+
47
+ choose do |menu|
48
+ menu.prompt = "Please choose your favorite programming language? "
49
+
50
+ menu.choice(:ruby) { say("Good choice!") }
51
+ menu.choices(:python, :perl) { say("Not from around here, are you?") }
52
+ end
53
+
54
+ For more examples see the examples/ directory of this project.
23
55
 
24
56
  == Installing
25
57
 
data/Rakefile CHANGED
@@ -32,9 +32,9 @@ end
32
32
 
33
33
  spec = Gem::Specification.new do |spec|
34
34
  spec.name = "highline"
35
- spec.version = "1.0.4"
35
+ spec.version = "1.2.0"
36
36
  spec.platform = Gem::Platform::RUBY
37
- spec.summary = "HighLine is a high-level line oriented console interface."
37
+ spec.summary = "HighLine is a high-level command-line IO library."
38
38
  spec.files = Dir.glob("{examples,lib,test}/**/*.rb").
39
39
  delete_if { |item| item.include?("CVS") } +
40
40
  ["Rakefile", "setup.rb"]
@@ -55,9 +55,10 @@ spec = Gem::Specification.new do |spec|
55
55
  spec.rubyforge_project = "highline"
56
56
  spec.homepage = "http://highline.rubyforge.org"
57
57
  spec.description = <<END_DESC
58
- A "high-level line oriented" input/output library that grew out of my solution
59
- to Ruby Quiz #29. This library attempts to make standard console input and
60
- output robust and painless.
58
+ A high-level IO library that provides validation, type conversion, and more for
59
+ command-line interfaces. HighLine also includes a complete menu system that can
60
+ crank out anything from simple list selection to complete shells with just
61
+ minutes of work.
61
62
  END_DESC
62
63
  end
63
64
 
@@ -26,6 +26,9 @@ require "abbrev"
26
26
  # checking, convert types, etc.
27
27
  #
28
28
  class HighLine
29
+ # The version of the installed library.
30
+ VERSION = "1.2.0".freeze
31
+
29
32
  # An internal HighLine error. User code does not need to trap this.
30
33
  class QuestionError < StandardError
31
34
  # do nothing, just creating a unique error type
@@ -581,9 +584,13 @@ class HighLine
581
584
  # Character input will be returned as a single character String,
582
585
  # not an Integer.
583
586
  #
587
+ # This question's _first_answer_ will be returned instead of input, if set.
588
+ #
584
589
  # Raises EOFError if input is exhausted.
585
590
  #
586
591
  def get_response( )
592
+ return @question.first_answer if @question.first_answer?
593
+
587
594
  if @question.character.nil?
588
595
  if @question.echo == true and @question.limit.nil?
589
596
  get_line
@@ -25,3 +25,19 @@ module Kernel
25
25
  extend Forwardable
26
26
  def_delegators :$terminal, :agree, :ask, :choose, :say
27
27
  end
28
+
29
+ class Object
30
+ #
31
+ # Tries this object as a _first_answer_ for a HighLine::Question. See that
32
+ # attribute for details.
33
+ #
34
+ # *Warning*: This Object will be passed to String() before set.
35
+ #
36
+ def or_ask( *args, &details )
37
+ ask(*args) do |question|
38
+ question.first_answer = String(self) unless nil?
39
+
40
+ details.call(question) unless details.nil?
41
+ end
42
+ end
43
+ end
@@ -31,6 +31,7 @@ class HighLine
31
31
  super("Ignored", [ ], &nil) # avoiding passing the block along
32
32
 
33
33
  @items = [ ]
34
+ @hidden_items = [ ]
34
35
  @help = Hash.new("There's no help for that topic.")
35
36
 
36
37
  @index = :number
@@ -150,6 +151,13 @@ class HighLine
150
151
  def choices( *names, &action )
151
152
  names.each { |n| choice(n, &action) }
152
153
  end
154
+
155
+ # Identical to choice(), but the item will not be listed for the user.
156
+ def hidden( name, help = nil, &action )
157
+ @hidden_items << [name, action]
158
+
159
+ @help[name.to_s.downcase] = help unless help.nil?
160
+ end
153
161
 
154
162
  #
155
163
  # Sets the indexing style for this Menu object. Indexes are appended to
@@ -255,6 +263,9 @@ class HighLine
255
263
  # on the settings of _index_ and _select_by_.
256
264
  #
257
265
  def options( )
266
+ # add in any hidden menu commands
267
+ @items.concat(@hidden_items)
268
+
258
269
  by_index = if @index == :letter
259
270
  l_index = "`"
260
271
  @items.map { "#{l_index.succ!}" }
@@ -271,6 +282,9 @@ class HighLine
271
282
  else
272
283
  by_index + by_name
273
284
  end
285
+ ensure
286
+ # make sure the hidden items are removed, before we return
287
+ @items.slice!(@items.size - @hidden_items.size, @hidden_items.size)
274
288
  end
275
289
 
276
290
  #
@@ -279,6 +293,9 @@ class HighLine
279
293
  # selection, it will be executed as described in Menu.choice().
280
294
  #
281
295
  def select( highline_context, selection, details = nil )
296
+ # add in any hidden menu commands
297
+ @items.concat(@hidden_items)
298
+
282
299
  # Find the selected action.
283
300
  name, action = if selection =~ /^\d+$/
284
301
  @items[selection.to_i - 1]
@@ -301,6 +318,9 @@ class HighLine
301
318
  else
302
319
  nil
303
320
  end
321
+ ensure
322
+ # make sure the hidden items are removed, before we return
323
+ @items.slice!(@items.size - @hidden_items.size, @hidden_items.size)
304
324
  end
305
325
 
306
326
  #
@@ -49,6 +49,7 @@ class HighLine
49
49
  @in = nil
50
50
  @confirm = nil
51
51
  @gather = false
52
+ @first_answer = nil
52
53
  @directory = Pathname.new(File.expand_path(File.dirname($0)))
53
54
  @glob = "*"
54
55
  @responses = Hash.new
@@ -144,6 +145,13 @@ class HighLine
144
145
  # question is evaluated, so you can use it in your question.
145
146
  #
146
147
  attr_accessor :gather
148
+ #
149
+ # When set to a non *nil* value, this will be tried as an answer to the
150
+ # question. If this answer passes validations, it will become the result
151
+ # without the user ever being prompted. Otherwise this value is discarded,
152
+ # and this Question is resolved as a normal call to HighLine.ask().
153
+ #
154
+ attr_writer :first_answer
147
155
  #
148
156
  # The directory from which a user will be allowed to select files, when
149
157
  # File or Pathname is specified as an _answer_type_. Initially set to
@@ -323,6 +331,18 @@ class HighLine
323
331
  else expected[0..-2].join(", ") + ", and #{expected.last}"
324
332
  end
325
333
  end
334
+
335
+ # Returns _first_answer_, which will be unset following this call.
336
+ def first_answer( )
337
+ @first_answer
338
+ ensure
339
+ @first_answer = nil
340
+ end
341
+
342
+ # Returns true if _first_answer_ is set.
343
+ def first_answer?( )
344
+ not @first_answer.nil?
345
+ end
326
346
 
327
347
  #
328
348
  # Returns +true+ if the _answer_object_ is greater than the _above_
@@ -763,4 +763,11 @@ class TestHighLine < Test::Unit::TestCase
763
763
  @terminal.say("-=" * 50)
764
764
  assert_equal(("-=" * 40 + "\n") + ("-=" * 10 + "\n"), @output.string)
765
765
  end
766
+
767
+ def test_version
768
+ assert_not_nil(HighLine::VERSION)
769
+ assert_instance_of(String, HighLine::VERSION)
770
+ assert(HighLine::VERSION.frozen?)
771
+ assert_match(/\A\d\.\d\.\d\Z/, HighLine::VERSION)
772
+ end
766
773
  end
@@ -20,9 +20,35 @@ class TestImport < Test::Unit::TestCase
20
20
  assert_respond_to(self, :say)
21
21
  end
22
22
 
23
+ def test_or_ask
24
+ old_terminal = $terminal
25
+
26
+ input = StringIO.new
27
+ output = StringIO.new
28
+ $terminal = HighLine.new(input, output)
29
+
30
+ input << "10\n"
31
+ input.rewind
32
+
33
+ assert_equal(10, nil.or_ask("How much? ", Integer))
34
+
35
+ input.rewind
36
+
37
+ assert_equal(20, "20".or_ask("How much? ", Integer))
38
+ assert_equal(20, 20.or_ask("How much? ", Integer))
39
+
40
+ assert_equal(10, 20.or_ask("How much? ", Integer) { |q| q.in = 1..10 })
41
+ ensure
42
+ $terminal = old_terminal
43
+ end
44
+
23
45
  def test_redirection
46
+ old_terminal = $terminal
47
+
24
48
  $terminal = HighLine.new(nil, (output = StringIO.new))
25
49
  say("Testing...")
26
50
  assert_equal("Testing...\n", output.string)
51
+ ensure
52
+ $terminal = old_terminal
27
53
  end
28
54
  end
@@ -304,6 +304,46 @@ class TestMenu < Test::Unit::TestCase
304
304
  assert_equal("Sample1", selected)
305
305
  end
306
306
 
307
+ def test_hidden
308
+ @input << "Hidden\n4\n"
309
+ @input.rewind
310
+
311
+ selected = @terminal.choose do |menu|
312
+ menu.choice "Sample1"
313
+ menu.choice "Sample2"
314
+ menu.choice "Sample3"
315
+ menu.hidden "Hidden!"
316
+ end
317
+ assert_equal("Hidden!", selected)
318
+ assert_equal("1. Sample1\n2. Sample2\n3. Sample3\n? ", @output.string)
319
+
320
+ @input.rewind
321
+
322
+ selected = @terminal.choose do |menu|
323
+ menu.select_by = :index
324
+
325
+ menu.choice "Sample1"
326
+ menu.choice "Sample2"
327
+ menu.choice "Sample3"
328
+ menu.hidden "Hidden!"
329
+ end
330
+ assert_equal("Hidden!", selected)
331
+
332
+ @input.rewind
333
+
334
+ selected = @terminal.choose do |menu|
335
+ menu.select_by = :name
336
+
337
+ menu.choice "Sample1"
338
+ menu.choice "Sample2"
339
+ menu.choice "Sample3"
340
+ menu.hidden "Hidden!"
341
+ end
342
+ assert_equal("Hidden!", selected)
343
+
344
+ @input.rewind
345
+ end
346
+
307
347
  def test_select_by_letter
308
348
  @input << "b\n"
309
349
  @input.rewind
metadata CHANGED
@@ -3,15 +3,15 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: highline
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.4
7
- date: 2006-02-26 00:00:00 -06:00
8
- summary: HighLine is a high-level line oriented console interface.
6
+ version: 1.2.0
7
+ date: 2006-03-22 00:00:00 -06:00
8
+ summary: HighLine is a high-level command-line IO library.
9
9
  require_paths:
10
10
  - lib
11
11
  email: james@grayproductions.net
12
12
  homepage: http://highline.rubyforge.org
13
13
  rubyforge_project: highline
14
- description: "A \"high-level line oriented\" input/output library that grew out of my solution to Ruby Quiz #29. This library attempts to make standard console input and output robust and painless."
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
15
  autorequire: highline
16
16
  default_executable:
17
17
  bindir: bin