lib/cli/ui/prompt.rb in cli-ui-2.2.3 vs lib/cli/ui/prompt.rb in cli-ui-2.3.0
- old
+ new
@@ -1,25 +1,15 @@
# coding: utf-8
-
# typed: true
+# frozen_string_literal: true
require 'cli/ui'
-require 'readline'
-
-module Readline
- unless const_defined?(:FILENAME_COMPLETION_PROC)
- FILENAME_COMPLETION_PROC = proc do |input|
- directory = input[-1] == '/' ? input : File.dirname(input)
- filename = input[-1] == '/' ? '' : File.basename(input)
-
- (Dir.entries(directory).select do |fp|
- fp.start_with?(filename)
- end - (input[-1] == '.' ? [] : ['.', '..'])).map do |fp|
- File.join(directory, fp).gsub(/\A\.\//, '')
- end
- end
- end
+begin
+ require 'reline' # For 2.7+
+rescue LoadError
+ require 'readline' # For 2.6
+ Object.const_set(:Reline, Readline)
end
module CLI
module UI
module Prompt
@@ -135,14 +125,10 @@
filter_ui: true,
select_ui: true,
&options_proc
)
has_options = !!(options || block_given?)
- if has_options && default && !multiple
- raise(ArgumentError, 'conflicting arguments: default may not be provided with options when not multiple')
- end
-
if has_options && is_file
raise(ArgumentError, 'conflicting arguments: is_file is only useful when options are not provided')
end
if options && multiple && default && !(Array(default) - options).empty?
@@ -308,10 +294,12 @@
instructions = (multiple ? 'Toggle options. ' : '') + navigate_text
instructions += ", filter with 'f'" if filter_ui
instructions += ", enter option with 'e'" if select_ui && (options.size > 9)
+ resp = T.let([], T.any(String, T::Array[String]))
+
CLI::UI::StdoutRouter::Capture.in_alternate_screen do
puts_question("#{question} " + instructions_color.code + "(#{instructions})" + Color::RESET.code)
resp = interactive_prompt(options, multiple: multiple, default: default)
# Clear the line
@@ -332,16 +320,16 @@
end
else
resp
end
puts_question("#{question} (You chose: {{italic:#{resp_text}}})")
+ end
- if block_given?
- T.must(handler).call(resp)
- else
- resp
- end
+ if block_given?
+ T.must(handler).call(resp)
+ else
+ resp
end
end
# Useful for stubbing in tests
sig do
@@ -373,15 +361,24 @@
end
sig { params(is_file: T::Boolean).returns(String) }
def readline(is_file: false)
if is_file
- Readline.completion_proc = Readline::FILENAME_COMPLETION_PROC
- Readline.completion_append_character = ''
+ Reline.completion_proc = proc do |input|
+ directory = input[-1] == '/' ? input : File.dirname(input)
+ filename = input[-1] == '/' ? '' : File.basename(input)
+
+ (Dir.entries(directory).select do |fp|
+ fp.start_with?(filename)
+ end - (input[-1] == '.' ? [] : ['.', '..'])).map do |fp|
+ File.join(directory, fp).gsub(/\A\.\//, '')
+ end
+ end
+ Reline.completion_append_character = ''
else
- Readline.completion_proc = proc { |*| nil }
- Readline.completion_append_character = ' '
+ Reline.completion_proc = proc {}
+ Reline.completion_append_character = ' '
end
# because Readline is a C library, CLI::UI's hooks into $stdout don't
# work. We could work around this by having CLI::UI use a pipe and a
# thread to manage output, but the current strategy feels like a
@@ -391,10 +388,10 @@
# not change the colour here.
prompt = prefix + CLI::UI.fmt('{{blue:> }}')
prompt += CLI::UI::Color::YELLOW.code if CLI::UI::OS.current.use_color_prompt?
begin
- line = Readline.readline(prompt, true)
+ line = Reline.readline(prompt, true)
print(CLI::UI::Color::RESET.code)
line.to_s.chomp
rescue Interrupt
CLI::UI.raw { $stderr.puts('^C' + CLI::UI::Color::RESET.code) }
raise