Class: Thor::Interactive::Shell
- Inherits:
-
Object
- Object
- Thor::Interactive::Shell
- Includes:
- CommandDispatch
- Defined in:
- lib/thor/interactive/shell.rb
Constant Summary collapse
- DEFAULT_PROMPT =
"> "- DEFAULT_HISTORY_FILE =
"~/.thor_interactive_history"
Constants included from CommandDispatch
CommandDispatch::EXIT_COMMANDS
Instance Attribute Summary collapse
-
#prompt ⇒ Object
readonly
Returns the value of attribute prompt.
-
#thor_class ⇒ Object
readonly
Returns the value of attribute thor_class.
-
#thor_instance ⇒ Object
readonly
Returns the value of attribute thor_instance.
Instance Method Summary collapse
-
#initialize(thor_class, options = {}) ⇒ Shell
constructor
A new instance of Shell.
- #start ⇒ Object
Methods included from CommandDispatch
#after_path_option?, #complete_command_options, #complete_commands, #complete_input, #complete_option_names, #complete_path, #complete_subcommand_args, #complete_subcommands, #format_path_completions, #handle_command, #handle_slash_command, #handle_unparseable_command, #invoke_thor_command, #is_help_request?, #parse_input, #parse_thor_options, #path_like?, #process_input, #safe_parse_input, #should_exit?, #show_help, #single_text_command?, #thor_command?
Constructor Details
#initialize(thor_class, options = {}) ⇒ Shell
Returns a new instance of Shell.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/thor/interactive/shell.rb', line 16 def initialize(thor_class, = {}) @thor_class = thor_class @thor_instance = thor_class.new # Merge class-level interactive options if available = {} if thor_class.respond_to?(:interactive_options) .merge!(thor_class.) end .merge!() @merged_options = @default_handler = [:default_handler] @prompt = [:prompt] || DEFAULT_PROMPT @history_file = File.([:history_file] || DEFAULT_HISTORY_FILE) # Ctrl-C handling configuration @ctrl_c_behavior = [:ctrl_c_behavior] || :clear_prompt @double_ctrl_c_timeout = .key?(:double_ctrl_c_timeout) ? [:double_ctrl_c_timeout] : 0.5 @last_interrupt_time = nil setup_completion load_history end |
Instance Attribute Details
#prompt ⇒ Object (readonly)
Returns the value of attribute prompt.
12 13 14 |
# File 'lib/thor/interactive/shell.rb', line 12 def prompt @prompt end |
#thor_class ⇒ Object (readonly)
Returns the value of attribute thor_class.
12 13 14 |
# File 'lib/thor/interactive/shell.rb', line 12 def thor_class @thor_class end |
#thor_instance ⇒ Object (readonly)
Returns the value of attribute thor_instance.
12 13 14 |
# File 'lib/thor/interactive/shell.rb', line 12 def thor_instance @thor_instance end |
Instance Method Details
#start ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/thor/interactive/shell.rb', line 42 def start # Track that we're in an interactive session was_in_session = ENV["THOR_INTERACTIVE_SESSION"] nesting_level = ENV["THOR_INTERACTIVE_LEVEL"].to_i ENV["THOR_INTERACTIVE_SESSION"] = "true" ENV["THOR_INTERACTIVE_LEVEL"] = (nesting_level + 1).to_s puts "(Debug: Interactive session started, level #{nesting_level + 1})" if ENV["DEBUG"] # Adjust prompt for nested sessions if configured display_prompt = @prompt if nesting_level > 0 && @merged_options[:nested_prompt_format] display_prompt = @merged_options[:nested_prompt_format] % [nesting_level + 1, @prompt] elsif nesting_level > 0 display_prompt = "(#{nesting_level + 1}) #{@prompt}" end show_welcome(nesting_level) puts "(Debug: Entering main loop)" if ENV["DEBUG"] loop do begin line = Reline.readline(display_prompt, true) puts "(Debug: Got input: #{line.inspect})" if ENV["DEBUG"] # Reset interrupt tracking on successful input @last_interrupt_time = nil if line if should_exit?(line) puts "(Debug: Exit condition met)" if ENV["DEBUG"] break end next if line.nil? || line.strip.empty? puts "(Debug: Processing input: #{line.strip})" if ENV["DEBUG"] process_input(line.strip) puts "(Debug: Input processed successfully)" if ENV["DEBUG"] rescue Interrupt # Handle Ctrl-C if handle_interrupt break # Exit on double Ctrl-C end next # Continue on single Ctrl-C rescue SystemExit => e puts "A command tried to exit with code #{e.status}. Staying in interactive mode." puts "(Debug: SystemExit caught in main loop)" if ENV["DEBUG"] rescue => e puts "Error: #{e.}" puts e.backtrace.first(5) if ENV["DEBUG"] puts "(Debug: Error handled, continuing loop)" if ENV["DEBUG"] # Continue the loop - don't let errors break the session end end puts "(Debug: Exited main loop)" if ENV["DEBUG"] save_history puts nesting_level > 0 ? "Exiting nested session..." : "Goodbye!" ensure # Restore previous session state if was_in_session ENV["THOR_INTERACTIVE_SESSION"] = "true" ENV["THOR_INTERACTIVE_LEVEL"] = nesting_level.to_s else ENV.delete("THOR_INTERACTIVE_SESSION") ENV.delete("THOR_INTERACTIVE_LEVEL") end end |