highline 2.1.0 → 3.0.0.pre.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0bb41764d2e42ab3b3c52ca1735f0cd6a587ff5ed3bb4525d0e7703dc4ccb61f
4
- data.tar.gz: 0424d1467c1f787881abfe6558afdc0aceeb0e854d05efac8c5c6db9d07ba3cf
3
+ metadata.gz: 00a520ba256dca588d4af090b8a9c41d808bd208966d3d3eabaf17a5e5516ad1
4
+ data.tar.gz: c0ab504488edce75cb6e290a119467ffb91ebbd9abbab3acedcc3da7198ad554
5
5
  SHA512:
6
- metadata.gz: df0dd1fa4d206aace9512f7ad414bc1e6bdcbfe804fd91b3811a2bc5860dbe7862d3ab81a502fc812747134be1122a647ac9fdd8e95e88e3f9388f7a05f38c22
7
- data.tar.gz: 70cbe01e01aeff63d8321a4768caaa43992082030ad4e3f93533693d7f7908b30175852c11286fe3a744c4a3a3be63ad3328e7b5b605a045ad4f634887e1340d
6
+ metadata.gz: '09efdc10dabb3dfedf2155faff822c845f819119f18abdcaa298607df6cf279ed955d693e31db5038509a16dbbee35f61fa18dc88591cfa6d2aa9543213d0129'
7
+ data.tar.gz: c0a80e2ed2caaada155c2b66433dcafec06e0abb63bfe206470e65697b46f8a9888bbc7d2c64bb21f7cbf46218b5561a00f62f115f9d4355d098cbf911cf1523
@@ -13,11 +13,6 @@ jobs:
13
13
  - '3.2'
14
14
  - '3.1'
15
15
  - '3.0'
16
- - '2.7'
17
- - '2.6'
18
- - '2.5'
19
- - '2.4'
20
- - '2.3'
21
16
  - jruby
22
17
  - jruby-head
23
18
  - truffleruby
data/Changelog.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  Below is a complete listing of changes for each revision of HighLine.
4
4
 
5
+ ### 3.0.0.pre.1 / 2023-04-27
6
+ * PR #263 - Release 3.0.0.pre.1
7
+ * Raise minimum Ruby version requirement to 3.0
8
+ * PR #262 - Do not call stty on non-tty (@kbrock)
9
+ * PR #260 / I #43 - Ctrl-U (erase line) handling (@abinoam, issue by @gutenye)
10
+ * PR #259 / I #236 - Handle Ctrl-C when Question#echo = false (@abinoam, @Fahhetah, issue by @aspyct)
11
+ * PR #258 / I #246 - Add validation class support (@abinoam, issue by @Joshfindit)
12
+ * Make it dry-types compatible through the use of `#valid?`
13
+ * Solve the multiple answers in one line problem with a combination of custom coercion (parser) and custom validation
14
+ * PR #257 / I #233 - Show Question#default hint for non String values (@abinoam, issue by @branch14)
15
+ * Add Question#default_hint_show to allow disabling it.
16
+ * PR #256 / I #249 - Fix Array validation in Question#in (@abinoam, issue by @esotericpig)
17
+
5
18
  ### 2.1.0 / 2022-12-31
6
19
  * PR #255 - Change minimum Ruby version requirement to 2.3 (@abinoam)
7
20
  * PR #254 - Improve Github Actions file (@abinoam)
data/README.md CHANGED
@@ -43,12 +43,48 @@ puts "You have answered: #{answer}"
43
43
 
44
44
  cli.ask("Company? ") { |q| q.default = "none" }
45
45
 
46
+ ## Disable default value hint showing
47
+
48
+ my_special_default_object = Object.new
49
+
50
+ cli.ask("Question? ") do |q|
51
+ q.default = my_special_default_object
52
+ q.default_hint_show = false
53
+ end
54
+
46
55
 
47
56
  # Validation
48
57
 
49
58
  cli.ask("Age? ", Integer) { |q| q.in = 0..105 }
50
59
  cli.ask("Name? (last, first) ") { |q| q.validate = /\A\w+, ?\w+\Z/ }
51
60
 
61
+ ## Validation with custom class
62
+ class ZeroToTwentyFourValidator
63
+ def self.valid?(answer)
64
+ (0..24).include? answer.to_i
65
+ end
66
+
67
+ def self.inspect
68
+ "(0..24) rule"
69
+ end
70
+ end
71
+
72
+ cli.ask("What hour of the day is it?: ", Integer) do |q|
73
+ q.validate = ZeroToTwentyFourValidator
74
+ end
75
+
76
+ ## Validation with Dry::Types
77
+ ## `Dry::Types` provides a `valid?` method so it can be used effortlessly
78
+
79
+ require 'dry-type'
80
+
81
+ module Types
82
+ include Dry.Types
83
+ end
84
+
85
+ cli.ask("Type an integer:", Integer) do |q|
86
+ q.validate = Types::Coercible::Integer
87
+ end
52
88
 
53
89
  # Type conversion for answers:
54
90
 
@@ -0,0 +1,39 @@
1
+ require 'highline'
2
+
3
+ cli = HighLine.new
4
+
5
+ # The parser
6
+ class ArrayOfNumbersFromString
7
+ def self.parse(string)
8
+ string.scan(/\d+/).map(&:to_i)
9
+ end
10
+ end
11
+
12
+ # The validator
13
+ class ArrayOfNumbersFromStringInRange
14
+ def self.in?(range)
15
+ new(range)
16
+ end
17
+
18
+ attr_reader :range
19
+
20
+ def initialize(range)
21
+ @range = range
22
+ end
23
+
24
+ def valid?(answer)
25
+ ary = ArrayOfNumbersFromString.parse(answer)
26
+ ary.all? ->(number) { range.include? number }
27
+ end
28
+
29
+ def inspect
30
+ "in range #@range validator"
31
+ end
32
+ end
33
+
34
+ answer = cli.ask("Which number? (0 or <Enter> to skip): ", ArrayOfNumbersFromString) { |q|
35
+ q.validate = ArrayOfNumbersFromStringInRange.in?(0..10)
36
+ q.default = 0
37
+ }
38
+
39
+ puts "Your answer was: #{answer} and it was correctly validated and coerced into an #{answer.class}"
data/highline.gemspec CHANGED
@@ -27,9 +27,10 @@ DESCRIPTION
27
27
 
28
28
  spec.extra_rdoc_files = %w[README.md TODO Changelog.md LICENSE]
29
29
 
30
- spec.required_ruby_version = ">= 2.3"
30
+ spec.required_ruby_version = ">= 3.0"
31
31
 
32
32
  spec.add_development_dependency "bundler"
33
33
  spec.add_development_dependency "rake"
34
34
  spec.add_development_dependency "minitest"
35
+ spec.add_development_dependency "dry-types"
35
36
  end
@@ -13,7 +13,7 @@ require "tempfile"
13
13
  #
14
14
 
15
15
  module IOConsoleCompatible
16
- def getch
16
+ def getch(min:nil, time:nil, intr: nil)
17
17
  getc
18
18
  end
19
19
 
@@ -9,7 +9,7 @@ class HighLine
9
9
  extend Forwardable
10
10
 
11
11
  def_delegators :@question,
12
- :answer, :answer=, :check_range,
12
+ :answer, :answer=,
13
13
  :directory, :answer_type, :choices_complete
14
14
 
15
15
  # It should be initialized with a Question object.
@@ -26,10 +26,7 @@ class HighLine
26
26
  # it makes the conversion and returns the answer.
27
27
  # @return [Object] the converted answer.
28
28
  def convert
29
- return unless answer_type
30
-
31
- self.answer = convert_by_answer_type
32
- check_range
29
+ self.answer = convert_by_answer_type if answer_type
33
30
  answer
34
31
  end
35
32
 
@@ -56,6 +56,7 @@ class HighLine
56
56
  @completion = @answer_type
57
57
 
58
58
  @echo = true
59
+ @default_hint_show = true
59
60
  @whitespace = :strip
60
61
  @case = nil
61
62
  @in = nil
@@ -136,10 +137,17 @@ class HighLine
136
137
  attr_accessor :case
137
138
  # Used to provide a default answer to this question.
138
139
  attr_accessor :default
140
+ # Set it to a truthy or falsy value to enable or disable showing the default
141
+ # value hint between vertical bars (pipes) when asking the question.
142
+ # Defaults to +true+
143
+ attr_accessor :default_hint_show
139
144
  #
140
145
  # If set to a Regexp, the answer must match (before type conversion).
141
146
  # Can also be set to a Proc which will be called with the provided
142
147
  # answer to validate with a +true+ or +false+ return.
148
+ # It's possible to use a custom validator class. It must respond to
149
+ # `#valid?`. The result of `#inspect` will be used in error messages.
150
+ # See README.md for details.
143
151
  #
144
152
  attr_accessor :validate
145
153
  # Used to control range checks for answer.
@@ -252,7 +260,7 @@ class HighLine
252
260
  # Same as {#answer_type}.
253
261
 
254
262
  def build_responses(message_source = answer_type)
255
- append_default if [::String, Symbol].include? default.class
263
+ append_default_to_template if default_hint_show
256
264
 
257
265
  new_hash = build_responses_new_hash(message_source)
258
266
  # Update our internal responses with the new hash
@@ -497,7 +505,8 @@ class HighLine
497
505
  def valid_answer?
498
506
  !validate ||
499
507
  (validate.is_a?(Regexp) && answer =~ validate) ||
500
- (validate.is_a?(Proc) && validate[answer])
508
+ (validate.is_a?(Proc) && validate[answer]) ||
509
+ (validate.respond_to?(:valid?) && validate.valid?(answer))
501
510
  end
502
511
 
503
512
  #
@@ -607,15 +616,20 @@ class HighLine
607
616
  # Trailing whitespace is preserved so the function of HighLine.say() is
608
617
  # not affected.
609
618
  #
610
- def append_default
619
+ def append_default_to_template
620
+ return unless default.respond_to? :to_s
621
+
622
+ default_str = default.to_s
623
+ return if default_str.empty?
624
+
611
625
  if template =~ /([\t ]+)\Z/
612
- template << "|#{default}|#{Regexp.last_match(1)}"
626
+ template << "|#{default_str}|#{Regexp.last_match(1)}"
613
627
  elsif template == ""
614
- template << "|#{default}| "
628
+ template << "|#{default_str}| "
615
629
  elsif template[-1, 1] == "\n"
616
- template[-2, 0] = " |#{default}|"
630
+ template[-2, 0] = " |#{default_str}|"
617
631
  else
618
- template << " |#{default}|"
632
+ template << " |#{default_str}|"
619
633
  end
620
634
  end
621
635
 
@@ -31,6 +31,7 @@ class HighLine
31
31
  raise NotValidQuestionError unless question.valid_answer?
32
32
 
33
33
  question.convert
34
+ question.check_range
34
35
 
35
36
  if question.confirm
36
37
  confirmation = @highline.send(:confirm, question)
@@ -27,7 +27,7 @@ class HighLine
27
27
 
28
28
  # (see Terminal#get_character)
29
29
  def get_character
30
- input.getch # from ruby io/console
30
+ input.getch(intr: true) # from ruby io/console
31
31
  rescue Errno::ENOTTY
32
32
  input.getc
33
33
  end
@@ -20,7 +20,9 @@ class HighLine
20
20
  rescue LoadError
21
21
  end
22
22
 
23
- if /solaris/ =~ RUBY_PLATFORM &&
23
+ if !@output.tty?
24
+ [80, 24]
25
+ elsif /solaris/ =~ RUBY_PLATFORM &&
24
26
  `stty` =~ /\brows = (\d+).*\bcolumns = (\d+)/
25
27
  [Regexp.last_match(2), Regexp.last_match(1)].map(&:to_i)
26
28
  elsif `stty size` =~ /^(\d+)\s(\d+)$/
@@ -32,13 +34,13 @@ class HighLine
32
34
 
33
35
  # (see Terminal#raw_no_echo_mode)
34
36
  def raw_no_echo_mode
35
- @state = `stty -g`
36
- system "stty raw -echo -icanon isig"
37
+ save_stty
38
+ system "stty raw -echo -icanon isig" if input.tty?
37
39
  end
38
40
 
39
41
  # (see Terminal#restore_mode)
40
42
  def restore_mode
41
- system "stty #{@state}"
43
+ restore_stty
42
44
  print "\r"
43
45
  end
44
46
 
@@ -176,7 +176,7 @@ class HighLine
176
176
  # Saves terminal state using shell stty command.
177
177
  def save_stty
178
178
  @stty_save = begin
179
- `stty -g`.chomp
179
+ `stty -g`.chomp if input.tty?
180
180
  rescue StandardError
181
181
  nil
182
182
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  class HighLine
4
4
  # The version of the installed library.
5
- VERSION = "2.1.0".freeze
5
+ VERSION = "3.0.0.pre.1".freeze
6
6
  end
data/lib/highline.rb CHANGED
@@ -538,6 +538,7 @@ class HighLine
538
538
  terminal.raw_no_echo_mode_exec do
539
539
  loop do
540
540
  character = terminal.get_character
541
+ raise Interrupt if character == "\u0003"
541
542
  break unless character
542
543
  break if ["\n", "\r"].include? character
543
544
 
@@ -545,6 +546,9 @@ class HighLine
545
546
  if character == "\b" || character == "\u007F"
546
547
  chopped = line.chop!
547
548
  output_erase_char if chopped && question.echo
549
+ elsif character == "\cU"
550
+ line.size.times { output_erase_char } if question.echo
551
+ line = ""
548
552
  elsif character == "\e"
549
553
  ignore_arrow_key
550
554
  else
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: highline
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 3.0.0.pre.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Edward Gray II
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-31 00:00:00.000000000 Z
11
+ date: 2023-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: dry-types
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: |
56
70
  A high-level IO library that provides validation, type conversion, and more for
57
71
  command-line interfaces. HighLine also includes a complete menu system that can
@@ -83,6 +97,7 @@ files:
83
97
  - examples/asking_for_arrays.rb
84
98
  - examples/basic_usage.rb
85
99
  - examples/color_scheme.rb
100
+ - examples/custom_parser_custom_validator.rb
86
101
  - examples/get_character.rb
87
102
  - examples/limit.rb
88
103
  - examples/menus.rb
@@ -136,14 +151,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
136
151
  requirements:
137
152
  - - ">="
138
153
  - !ruby/object:Gem::Version
139
- version: '2.3'
154
+ version: '3.0'
140
155
  required_rubygems_version: !ruby/object:Gem::Requirement
141
156
  requirements:
142
- - - ">="
157
+ - - ">"
143
158
  - !ruby/object:Gem::Version
144
- version: '0'
159
+ version: 1.3.1
145
160
  requirements: []
146
- rubygems_version: 3.4.1
161
+ rubygems_version: 3.4.6
147
162
  signing_key:
148
163
  specification_version: 4
149
164
  summary: HighLine is a high-level command-line IO library.