highline 2.0.3 → 3.1.2

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: 8c2652997ba01a32e3b6357a60c0567724e235d3763fa7dd000a6adbf71a6d75
4
- data.tar.gz: 93fa0727991ba6d16e36a3a76f48784b54c15b8d4e8b32a0703a12c665e62601
3
+ metadata.gz: b9d2b093cb533443369ed3d5c31f6c09f1d5fdfd4d5b9f89a1e48d8da20a377a
4
+ data.tar.gz: 150008ffff933909afcc40ebdee9bba538dc1170331a4a58cd5ebff5fc582738
5
5
  SHA512:
6
- metadata.gz: aae3c4c97d87a3b3fd5e12fcb234acc5a3470e3392942db6b369ea42c83fdd2ae90104b8a6957f8250616c35c16f1ab5acb11edeeb585f505f392367293154e9
7
- data.tar.gz: 1dc931251446b234c9fff7c2389cd4d156a2fdd8619dc3f57a74cc06b8b50cf4c10ae7943fdfb6b20c2ef1359721d38faa03c875c5ef973bf38a87942173c060
6
+ metadata.gz: 016dc7d742577f9cb8fbca44a07e14a9911b314afb9ad4974456ae29fb379705a4161e48eb19c73fb2a7afe6ae602272360141b09cc17ad33346eb00a03f34e8
7
+ data.tar.gz: 41d933367b093d1296535eedcf8ffc147c561dd51f07ef81d20d3c044877c93d1c3eb0c96a783e1c0f4cfd444ceb1bbbda26c21509519515571cab87ac3744ba
@@ -0,0 +1,47 @@
1
+ name: Tests
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ test:
7
+ strategy:
8
+ fail-fast: false
9
+ matrix:
10
+ os: [ubuntu-latest]
11
+ ruby-version:
12
+ - head
13
+ - '3.4'
14
+ - '3.3'
15
+ - '3.2'
16
+ - '3.1'
17
+ - '3.0'
18
+ - jruby
19
+ - jruby-head
20
+ - truffleruby
21
+ - truffleruby-head
22
+ - truffleruby+graalvm
23
+ include:
24
+ - os: windows-latest
25
+ ruby-version: head
26
+ - os: windows-latest
27
+ ruby-version: '3.4'
28
+ - os: windows-latest
29
+ ruby-version: mingw
30
+ - os: windows-latest
31
+ ruby-version: mswin
32
+ - os: windows-latest
33
+ ruby-version: ucrt
34
+ - os: macos-latest
35
+ ruby-version: 'head'
36
+ - os: macos-latest
37
+ ruby-version: '3.4'
38
+ runs-on: ${{ matrix.os }}
39
+ steps:
40
+ - uses: actions/checkout@v4
41
+ - name: Set up Ruby ${{ matrix.ruby-version }}
42
+ uses: ruby/setup-ruby@v1
43
+ with:
44
+ ruby-version: ${{ matrix.ruby-version }}
45
+ bundler-cache: true # 'bundle install' and cache
46
+ - name: Run tests
47
+ run: bundle exec rake test
data/.rubocop.yml CHANGED
@@ -4,7 +4,8 @@
4
4
  # https://github.com/bbatsov/rubocop/tree/master/config
5
5
 
6
6
  AllCops:
7
- TargetRubyVersion: 2.1
7
+ TargetRubyVersion: 3.4
8
+ NewCops: enable
8
9
 
9
10
  # General
10
11
 
@@ -58,7 +59,7 @@ Style/OptionalArguments:
58
59
  - 'lib/highline/list_renderer.rb'
59
60
 
60
61
  # TemplateRenderer should never fail on method missing.
61
- Style/MethodMissing:
62
+ Style/MissingRespondToMissing:
62
63
  Exclude:
63
64
  - 'lib/highline/template_renderer.rb'
64
65
 
@@ -73,7 +74,7 @@ Style/SymbolArray:
73
74
  # Cop supports --auto-correct.
74
75
  # Configuration parameters: EnforcedStyle, SupportedStyles.
75
76
  # SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent
76
- Layout/IndentHeredoc:
77
+ Layout/HeredocIndentation:
77
78
  Exclude:
78
79
  - 'examples/page_and_wrap.rb'
79
80
  - 'highline.gemspec'
data/Changelog.md CHANGED
@@ -2,6 +2,44 @@
2
2
 
3
3
  Below is a complete listing of changes for each revision of HighLine.
4
4
 
5
+ ### 3.1.2 / 2025-01-05
6
+ * PR #279 - Upgrades and adjustments for Ruby 3.4 release (@abinoam)
7
+ * PR #278 - Prevent ArgumentError for #col_count_calculate when items exceed 80 chars (@davidjkling, @justintsteele)
8
+
9
+ ### 3.1.1 / 2024-08-18
10
+ * PR #276 - Update #say to always flush the output after a #puts (@blipper)
11
+ * PR #274 / I #273 (@costa)
12
+ * Add Highline#add_to_color_scheme
13
+ * Dockerize the test environment. Just run `bin/test` and voilá!
14
+
15
+ ### 3.1.0 / 2024-07-15
16
+ * PR #272 / I #271 - Readline is now completed deprecated over Reline (@abinoam, issue by @64kramsystem)
17
+ * PR #269 - Provide a 'Changelog' link on rubygems.org/gems/highline (@mark-young-atg)
18
+
19
+ ### 3.0.1 / 2024-01-20
20
+ * PR #268 - Remove unused abbrev dependency (@zvkemp)
21
+
22
+ ### 3.0.0 / 2024-01-05
23
+ * PR #265 - Change Readline for Reline for Ruby 3.3 compat (@abinoam)
24
+ * PR #264 - Add abbrev gem as dependency (@mathieujobin)
25
+ * PR #263 - Release 3.0.0.pre.1
26
+ * Raise minimum Ruby version requirement to 3.0
27
+ * PR #262 - Do not call stty on non-tty (@kbrock)
28
+ * PR #260 / I #43 - Ctrl-U (erase line) handling (@abinoam, issue by @gutenye)
29
+ * PR #259 / I #236 - Handle Ctrl-C when Question#echo = false (@abinoam, @Fahhetah, issue by @aspyct)
30
+ * PR #258 / I #246 - Add validation class support (@abinoam, issue by @Joshfindit)
31
+ * Make it dry-types compatible through the use of `#valid?`
32
+ * Solve the multiple answers in one line problem with a combination of custom coercion (parser) and custom validation
33
+ * PR #257 / I #233 - Show Question#default hint for non String values (@abinoam, issue by @branch14)
34
+ * Add Question#default_hint_show to allow disabling it.
35
+ * PR #256 / I #249 - Fix Array validation in Question#in (@abinoam, issue by @esotericpig)
36
+
37
+ ### 2.1.0 / 2022-12-31
38
+ * PR #255 - Change minimum Ruby version requirement to 2.3 (@abinoam)
39
+ * PR #254 - Improve Github Actions file (@abinoam)
40
+ * PR #253, PR #251 - Setup GitHub Actions and remove Travis (@petergoldstein, rev by @AlexWayfer)
41
+ * PR #250 - Fix file permissions (@bdunne)
42
+
5
43
  ### 2.0.3 / 2019-10-11
6
44
  * PR #245 - Suppress `Psych.safe_load` arg warn (@koic)
7
45
 
data/Gemfile CHANGED
@@ -7,16 +7,15 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
7
7
  # Specify your gem's dependencies in tgem.gemspec
8
8
  gemspec
9
9
 
10
- platform :ruby do
11
- # Running only on MRI
12
- gem "simplecov", group: :test
13
- end
10
+ gem "simplecov", group: :test, require: false
14
11
 
15
12
  group :code_quality do
16
13
  gem "flog", require: false
17
14
  gem "pronto", require: false, platform: :ruby
18
15
  gem "pronto-flay", require: false, platform: :ruby
19
- gem "pronto-poper", require: false, platform: :ruby
16
+ gem "path_expander", "1.1.1", require: false # Remove this lock when path_expander > 1.1.2 and flay > 2.13.3 is released.
17
+ # gem "pronto-poper", require: false, platform: :ruby
20
18
  gem "pronto-reek", require: false, platform: :ruby
21
19
  gem "pronto-rubocop", require: false, platform: :ruby
20
+ gem "base64", require: false
22
21
  end
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  HighLine
2
2
  ========
3
3
 
4
- [![Build Status](https://travis-ci.org/JEG2/highline.svg?branch=master)](https://travis-ci.org/JEG2/highline)
5
- [![Build status](https://ci.appveyor.com/api/projects/status/4p05fijpah77d28x/branch/master?svg=true)](https://ci.appveyor.com/project/JEG2/highline/branch/master)
4
+ [![Tests](https://github.com/JEG2/highline/actions/workflows/ci.yml/badge.svg)](https://github.com/JEG2/highline/actions/workflows/ci.yml)
6
5
  [![Gem Version](https://badge.fury.io/rb/highline.svg)](https://badge.fury.io/rb/highline)
7
6
  [![Code Climate](https://codeclimate.com/github/JEG2/highline/badges/gpa.svg)](https://codeclimate.com/github/JEG2/highline)
8
7
  [![Test Coverage](https://codeclimate.com/github/JEG2/highline/badges/coverage.svg)](https://codeclimate.com/github/JEG2/highline/coverage)
@@ -44,12 +43,48 @@ puts "You have answered: #{answer}"
44
43
 
45
44
  cli.ask("Company? ") { |q| q.default = "none" }
46
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
+
47
55
 
48
56
  # Validation
49
57
 
50
58
  cli.ask("Age? ", Integer) { |q| q.in = 0..105 }
51
59
  cli.ask("Name? (last, first) ") { |q| q.validate = /\A\w+, ?\w+\Z/ }
52
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
53
88
 
54
89
  # Type conversion for answers:
55
90
 
@@ -104,7 +139,7 @@ For more examples see the examples/ directory of this project.
104
139
  Requirements
105
140
  ------------
106
141
 
107
- HighLine from version >= 1.7.0 requires ruby >= 1.9.3
142
+ HighLine from version >= 3.0.0 requires ruby >= 3.0.0
108
143
 
109
144
  Installing
110
145
  ----------
@@ -171,6 +206,9 @@ Contributing
171
206
  - ```rake acceptance```
172
207
  - ```pronto run```
173
208
 
209
+ Alternatively, if you're in a [Docker](https://www.docker.com)ised environment,
210
+ don't care about installing anything locally -- just run `bin/test` instead.
211
+
174
212
  8. Commit your changes
175
213
  - ```git commit -am "Your commit message"```
176
214
 
data/bin/test ADDED
@@ -0,0 +1,11 @@
1
+ #!/bin/bash -e
2
+ test "$#" -ne 0 && echo "Unsupported args: $@" >&2 && exit 145
3
+ cd "$( dirname "${BASH_SOURCE[0]}" )"/..
4
+
5
+ export COMPOSE_FILE=test/docker-compose.yml
6
+ export COMPOSE_PROJECT_NAME=highline_dev
7
+
8
+ docker compose rm -svf
9
+ docker compose build --force-rm
10
+
11
+ docker compose run --rm tester && docker compose rm -svf || ( docker compose logs && exit 1 )
@@ -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,14 @@ DESCRIPTION
27
27
 
28
28
  spec.extra_rdoc_files = %w[README.md TODO Changelog.md LICENSE]
29
29
 
30
- spec.required_ruby_version = ">= 1.9.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"
36
+
37
+ spec.add_runtime_dependency "reline"
38
+
39
+ spec.metadata["changelog_uri"] = spec.homepage + "/blob/master/Changelog.md"
35
40
  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
 
@@ -236,8 +236,8 @@ class HighLine
236
236
  end
237
237
 
238
238
  def col_count_calculate
239
- (line_size_limit + row_join_str_size) /
240
- (items_max_length + row_join_str_size)
239
+ result = (line_size_limit + row_join_str_size) / (items_max_length + row_join_str_size)
240
+ result == 0 ? 1 : result
241
241
  end
242
242
 
243
243
  def col_count
data/lib/highline/menu.rb CHANGED
@@ -374,12 +374,14 @@ class HighLine
374
374
  end
375
375
 
376
376
  def map_items_by_index
377
- if [:letter, :capital_letter].include?(@index)
378
- # @ and ` are the previous ASCII characters to A and a respectively
379
- prev_char = (@index == :capital_letter ? '@' : '`')
380
- all_items.map { prev_char.succ!.dup }
377
+ size = all_items.size
378
+ case @index
379
+ when :letter
380
+ ("a".."z").first(size)
381
+ when :capital_letter
382
+ ("A".."Z").first(size)
381
383
  else
382
- (1..all_items.size).map(&:to_s)
384
+ (1..size).map(&:to_s)
383
385
  end
384
386
  end
385
387
 
@@ -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
@@ -115,7 +116,7 @@ class HighLine
115
116
  #
116
117
  attr_accessor :echo
117
118
  #
118
- # Use the Readline library to fetch input. This allows input editing as
119
+ # Use the Reline library to fetch input. This allows input editing as
119
120
  # well as keeping a history. In addition, tab will auto-complete
120
121
  # within an Array of choices or a file listing.
121
122
  #
@@ -124,6 +125,7 @@ class HighLine
124
125
  # specified _input_ stream.
125
126
  #
126
127
  attr_accessor :readline
128
+
127
129
  #
128
130
  # Used to control whitespace processing for the answer to this question.
129
131
  # See HighLine::Question.remove_whitespace() for acceptable settings.
@@ -136,10 +138,17 @@ class HighLine
136
138
  attr_accessor :case
137
139
  # Used to provide a default answer to this question.
138
140
  attr_accessor :default
141
+ # Set it to a truthy or falsy value to enable or disable showing the default
142
+ # value hint between vertical bars (pipes) when asking the question.
143
+ # Defaults to +true+
144
+ attr_accessor :default_hint_show
139
145
  #
140
146
  # If set to a Regexp, the answer must match (before type conversion).
141
147
  # Can also be set to a Proc which will be called with the provided
142
148
  # answer to validate with a +true+ or +false+ return.
149
+ # It's possible to use a custom validator class. It must respond to
150
+ # `#valid?`. The result of `#inspect` will be used in error messages.
151
+ # See README.md for details.
143
152
  #
144
153
  attr_accessor :validate
145
154
  # Used to control range checks for answer.
@@ -252,7 +261,7 @@ class HighLine
252
261
  # Same as {#answer_type}.
253
262
 
254
263
  def build_responses(message_source = answer_type)
255
- append_default if [::String, Symbol].include? default.class
264
+ append_default_to_template if default_hint_show
256
265
 
257
266
  new_hash = build_responses_new_hash(message_source)
258
267
  # Update our internal responses with the new hash
@@ -497,7 +506,8 @@ class HighLine
497
506
  def valid_answer?
498
507
  !validate ||
499
508
  (validate.is_a?(Regexp) && answer =~ validate) ||
500
- (validate.is_a?(Proc) && validate[answer])
509
+ (validate.is_a?(Proc) && validate[answer]) ||
510
+ (validate.respond_to?(:valid?) && validate.valid?(answer))
501
511
  end
502
512
 
503
513
  #
@@ -571,11 +581,6 @@ class HighLine
571
581
  end
572
582
  end
573
583
 
574
- # readline() needs to handle its own output, but readline only supports
575
- # full line reading. Therefore if question.echo is anything but true,
576
- # the prompt will not be issued. And we have to account for that now.
577
- # Also, JRuby-1.7's ConsoleReader.readLine() needs to be passed the prompt
578
- # to handle line editing properly.
579
584
  # @param highline [HighLine] context
580
585
  # @return [void]
581
586
  def show_question(highline)
@@ -607,15 +612,20 @@ class HighLine
607
612
  # Trailing whitespace is preserved so the function of HighLine.say() is
608
613
  # not affected.
609
614
  #
610
- def append_default
615
+ def append_default_to_template
616
+ return unless default.respond_to? :to_s
617
+
618
+ default_str = default.to_s
619
+ return if default_str.empty?
620
+
611
621
  if template =~ /([\t ]+)\Z/
612
- template << "|#{default}|#{Regexp.last_match(1)}"
622
+ template << "|#{default_str}|#{Regexp.last_match(1)}"
613
623
  elsif template == ""
614
- template << "|#{default}| "
624
+ template << "|#{default_str}| "
615
625
  elsif template[-1, 1] == "\n"
616
- template[-2, 0] = " |#{default}|"
626
+ template[-2, 0] = " |#{default_str}|"
617
627
  else
618
- template << " |#{default}|"
628
+ template << " |#{default_str}|"
619
629
  end
620
630
  end
621
631
 
@@ -24,13 +24,15 @@ class HighLine
24
24
  #
25
25
  # @return [String] answer
26
26
  def ask_once
27
- question.show_question(@highline)
27
+ # If in readline mode, let reline take care of the prompt
28
+ question.show_question(@highline) unless question.readline
28
29
 
29
30
  begin
30
31
  question.get_response_or_default(@highline)
31
32
  raise NotValidQuestionError unless question.valid_answer?
32
33
 
33
34
  question.convert
35
+ question.check_range
34
36
 
35
37
  if question.confirm
36
38
  confirmation = @highline.send(:confirm, question)
File without changes
@@ -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
 
@@ -95,9 +95,9 @@ class HighLine
95
95
  # Get one line using #readline_read
96
96
  # @param (see #get_line)
97
97
  def get_line_with_readline(question, highline)
98
- require "readline" # load only if needed
98
+ require "reline" # load only if needed
99
99
 
100
- raw_answer = readline_read(question)
100
+ raw_answer = readline_read(question, highline)
101
101
 
102
102
  if !raw_answer && highline.track_eof?
103
103
  raise EOFError, "The input stream is exhausted."
@@ -109,20 +109,22 @@ class HighLine
109
109
  # Use readline to read one line
110
110
  # @param question [HighLine::Question] question from where to get
111
111
  # autocomplete candidate strings
112
- def readline_read(question)
112
+ def readline_read(question, highline)
113
113
  # prep auto-completion
114
114
  unless question.selection.empty?
115
- Readline.completion_proc = lambda do |str|
115
+ Reline.completion_proc = lambda do |str|
116
116
  question.selection.grep(/\A#{Regexp.escape(str)}/)
117
117
  end
118
118
  end
119
119
 
120
+ # TODO: Check if this is still needed after Reline
120
121
  # work-around ugly readline() warnings
121
122
  old_verbose = $VERBOSE
122
123
  $VERBOSE = nil
123
124
 
124
125
  raw_answer = run_preserving_stty do
125
- Readline.readline("", true)
126
+ prompt = highline.render_and_ident_statement(question)
127
+ Reline.readline(prompt, true)
126
128
  end
127
129
 
128
130
  $VERBOSE = old_verbose
@@ -176,7 +178,7 @@ class HighLine
176
178
  # Saves terminal state using shell stty command.
177
179
  def save_stty
178
180
  @stty_save = begin
179
- `stty -g`.chomp
181
+ `stty -g`.chomp if input.tty?
180
182
  rescue StandardError
181
183
  nil
182
184
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  class HighLine
4
4
  # The version of the installed library.
5
- VERSION = "2.0.3".freeze
5
+ VERSION = "3.1.2".freeze
6
6
  end
data/lib/highline.rb CHANGED
@@ -14,7 +14,6 @@ require "English"
14
14
  require "erb"
15
15
  require "optparse"
16
16
  require "stringio"
17
- require "abbrev"
18
17
  require "highline/terminal"
19
18
  require "highline/custom_errors"
20
19
  require "highline/question"
@@ -62,6 +61,14 @@ class HighLine
62
61
  true if @color_scheme
63
62
  end
64
63
 
64
+ # Pass a +Hash+ to add +new+ colors to the current scheme.
65
+ def add_to_color_scheme(hash)
66
+ old_hash = (color_scheme || {}).to_hash
67
+ fail "Overlapping color schemes: #{old_hash.keys & hash.keys}" unless
68
+ (old_hash.keys & hash.keys).empty?
69
+ self.color_scheme = ColorScheme.new(old_hash.merge hash)
70
+ end
71
+
65
72
  # Reset color scheme to default (+nil+)
66
73
  def reset_color_scheme
67
74
  self.color_scheme = nil
@@ -371,19 +378,29 @@ class HighLine
371
378
  #
372
379
  # @param statement [Statement, String] what to be said
373
380
  def say(statement)
374
- statement = render_statement(statement)
375
- return if statement.empty?
376
-
377
- statement = (indentation + statement)
381
+ statement = render_and_ident_statement(statement)
382
+ return statement if statement.empty?
378
383
 
379
384
  # Don't add a newline if statement ends with whitespace, OR
380
385
  # if statement ends with whitespace before a color escape code.
381
386
  if /[ \t](\e\[\d+(;\d+)*m)?\Z/ =~ statement
382
387
  output.print(statement)
383
- output.flush
384
388
  else
385
389
  output.puts(statement)
386
390
  end
391
+ output.flush # See: https://github.com/JEG2/highline/pull/276
392
+ end
393
+
394
+ # Renders and indents a statement.
395
+ #
396
+ # Note: extracted here to be used by readline to render its prompt.
397
+ #
398
+ # @param statement [String] The statement to be rendered and indented.
399
+ # @return [String] The rendered and indented statement.
400
+ def render_and_ident_statement(statement)
401
+ statement = render_statement(statement)
402
+ statement = (indentation + statement) unless statement.empty?
403
+ statement
387
404
  end
388
405
 
389
406
  # Renders a statement using {HighLine::Statement}
@@ -538,17 +555,26 @@ class HighLine
538
555
  terminal.raw_no_echo_mode_exec do
539
556
  loop do
540
557
  character = terminal.get_character
541
- break unless character
542
- break if ["\n", "\r"].include? character
543
-
544
- # honor backspace and delete
545
- if character == "\b" || character == "\u007F"
546
- chopped = line.chop!
547
- output_erase_char if chopped && question.echo
548
- elsif character == "\e"
558
+
559
+ case character
560
+ when "\u0003" # Ctrl+C (Interrupt)
561
+ raise Interrupt
562
+ when nil # No character received
563
+ break
564
+ when "\n", "\r" # Newline or carriage return
565
+ break
566
+ when "\b", "\u007F" # Backspace and delete
567
+ unless line.empty?
568
+ line = line.chop
569
+ output_erase_char if question.echo
570
+ end
571
+ when "\cU" # Clear line
572
+ line.size.times { output_erase_char } if question.echo
573
+ line = ""
574
+ when "\e" # Escape key
549
575
  ignore_arrow_key
550
- else
551
- line << character
576
+ else # Any other character
577
+ line += character
552
578
  say_last_char_or_echo_char(line, question)
553
579
  end
554
580
 
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: highline
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 3.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Edward Gray II
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2019-10-11 00:00:00.000000000 Z
10
+ date: 2025-01-06 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bundler
@@ -52,6 +51,34 @@ dependencies:
52
51
  - - ">="
53
52
  - !ruby/object:Gem::Version
54
53
  version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: dry-types
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: reline
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
55
82
  description: |
56
83
  A high-level IO library that provides validation, type conversion, and more for
57
84
  command-line interfaces. HighLine also includes a complete menu system that can
@@ -66,10 +93,10 @@ extra_rdoc_files:
66
93
  - Changelog.md
67
94
  - LICENSE
68
95
  files:
96
+ - ".github/workflows/ci.yml"
69
97
  - ".gitignore"
70
98
  - ".rubocop.yml"
71
99
  - ".simplecov"
72
- - ".travis.yml"
73
100
  - AUTHORS
74
101
  - COPYING
75
102
  - Changelog.md
@@ -78,12 +105,13 @@ files:
78
105
  - README.md
79
106
  - Rakefile
80
107
  - TODO
81
- - appveyor.yml
108
+ - bin/test
82
109
  - doc/.cvsignore
83
110
  - examples/ansi_colors.rb
84
111
  - examples/asking_for_arrays.rb
85
112
  - examples/basic_usage.rb
86
113
  - examples/color_scheme.rb
114
+ - examples/custom_parser_custom_validator.rb
87
115
  - examples/get_character.rb
88
116
  - examples/limit.rb
89
117
  - examples/menus.rb
@@ -128,8 +156,8 @@ files:
128
156
  homepage: https://github.com/JEG2/highline
129
157
  licenses:
130
158
  - Ruby
131
- metadata: {}
132
- post_install_message:
159
+ metadata:
160
+ changelog_uri: https://github.com/JEG2/highline/blob/master/Changelog.md
133
161
  rdoc_options: []
134
162
  require_paths:
135
163
  - lib
@@ -137,15 +165,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
137
165
  requirements:
138
166
  - - ">="
139
167
  - !ruby/object:Gem::Version
140
- version: 1.9.3
168
+ version: '3.0'
141
169
  required_rubygems_version: !ruby/object:Gem::Requirement
142
170
  requirements:
143
171
  - - ">="
144
172
  - !ruby/object:Gem::Version
145
173
  version: '0'
146
174
  requirements: []
147
- rubygems_version: 3.0.6
148
- signing_key:
175
+ rubygems_version: 3.6.2
149
176
  specification_version: 4
150
177
  summary: HighLine is a high-level command-line IO library.
151
178
  test_files: []
data/.travis.yml DELETED
@@ -1,43 +0,0 @@
1
- ---
2
- language: ruby
3
- dist: trusty
4
- cache: bundler
5
- script: "bundle exec rake test"
6
- rvm:
7
- - 2.0
8
- - 2.1
9
- - 2.2
10
- - 2.3
11
- - 2.4
12
- - jruby-19mode # JRuby in 1.9 mode
13
- - jruby-head
14
-
15
- notifications:
16
- email: false
17
- matrix:
18
- allow_failures:
19
- - rvm: 1.9
20
- - rvm: ruby-head
21
- - rvm: rbx-3.81
22
- - rvm: jruby-19mode # JRuby in 1.9 mode
23
- - rvm: jruby-head
24
- fast_finish: true
25
- include:
26
- - rvm: 1.9
27
- before_install:
28
- - "gem update --system -N"
29
- - "gem update bundler -N"
30
- - rvm: 2.5
31
- before_install:
32
- - gem install bundler
33
- - rvm: 2.6
34
- before_install:
35
- - gem install bundler
36
- - rvm: ruby-head
37
- before_install:
38
- - gem install bundler
39
- - rvm: rbx-3.81
40
- before_install:
41
- - gem install bundler
42
-
43
- bundler_args: --without code_quality
data/appveyor.yml DELETED
@@ -1,37 +0,0 @@
1
- version: 2.0.{build}-{branch}
2
-
3
- cache:
4
- - vendor/bundle
5
-
6
- environment:
7
- matrix:
8
- - RUBY_VERSION: "193"
9
- - RUBY_VERSION: "200"
10
- - RUBY_VERSION: "200-x64"
11
- - RUBY_VERSION: "21"
12
- - RUBY_VERSION: "21-x64"
13
- - RUBY_VERSION: "22"
14
- - RUBY_VERSION: "22-x64"
15
- - RUBY_VERSION: "23"
16
- - RUBY_VERSION: "23-x64"
17
- - RUBY_VERSION: "24"
18
- - RUBY_VERSION: "24-x64"
19
-
20
- matrix:
21
- allow_failures:
22
- - RUBY_VERSION: "193"
23
-
24
- install:
25
- - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
26
- - bundle config --local path vendor/bundle
27
- - bundle install --retry=3 --without code_quality
28
-
29
- build: off
30
-
31
- before_test:
32
- - ruby -v
33
- - gem -v
34
- - bundle -v
35
-
36
- test_script:
37
- - bundle exec rake