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