Class: Thor::Interactive::TUI::RatatuiShell

Inherits:
Object
  • Object
show all
Includes:
CommandDispatch
Defined in:
lib/thor/interactive/tui/ratatui_shell.rb

Constant Summary collapse

DEFAULT_PROMPT =
"> "
DEFAULT_HISTORY_FILE =
"~/.thor_interactive_history"
INPUT_VIEWPORT_HEIGHT =

Viewport: status bar (1) + input box with room for multi-line (7)

8

Constants included from CommandDispatch

CommandDispatch::EXIT_COMMANDS

Instance Attribute Summary collapse

Instance Method Summary collapse

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 = {}) ⇒ RatatuiShell

Returns a new instance of RatatuiShell.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/thor/interactive/tui/ratatui_shell.rb', line 27

def initialize(thor_class, options = {})
  @thor_class = thor_class
  @thor_instance = thor_class.new

  merged_options = {}
  if thor_class.respond_to?(:interactive_options)
    merged_options.merge!(thor_class.interactive_options)
  end
  merged_options.merge!(options)

  @merged_options = merged_options
  @default_handler = merged_options[:default_handler]
  @prompt = merged_options[:prompt] || DEFAULT_PROMPT
  @history_file = File.expand_path(merged_options[:history_file] || DEFAULT_HISTORY_FILE)

  @text_input = TextInput.new
  @status_bar = StatusBar.new(thor_class, @thor_instance, merged_options)
  @spinner = Spinner.new(messages: merged_options[:spinner_messages])
  @theme = Theme.new(merged_options[:theme] || :default)
  @running = false
  @executing_command = false
  @completions = []
  @completion_index = -1

  # Multi-line input mode
  @kitty_protocol_active = false
  @multiline_mode = false # fallback toggle when Kitty protocol unavailable

  # Ctrl-C handling
  @last_interrupt_time = nil
  @double_ctrl_c_timeout = merged_options.key?(:double_ctrl_c_timeout) ?
                          merged_options[:double_ctrl_c_timeout] : 0.5

  load_history
end

Instance Attribute Details

#promptObject (readonly)

Returns the value of attribute prompt.



23
24
25
# File 'lib/thor/interactive/tui/ratatui_shell.rb', line 23

def prompt
  @prompt
end

#thor_classObject (readonly)

Returns the value of attribute thor_class.



23
24
25
# File 'lib/thor/interactive/tui/ratatui_shell.rb', line 23

def thor_class
  @thor_class
end

#thor_instanceObject (readonly)

Returns the value of attribute thor_instance.



23
24
25
# File 'lib/thor/interactive/tui/ratatui_shell.rb', line 23

def thor_instance
  @thor_instance
end

Instance Method Details

#startObject



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
# File 'lib/thor/interactive/tui/ratatui_shell.rb', line 63

def start
  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

  @running = true

  RatatuiRuby.run(viewport: :inline, height: INPUT_VIEWPORT_HEIGHT, bracketed_paste: true) do |tui|
    @tui = tui
    disable_mouse_capture
    enable_kitty_keyboard

    # Welcome message above viewport (scrollback)
    emit_above(tui, "#{@thor_class.name} Interactive Shell (TUI mode)", style: :system)
    if @kitty_protocol_active
      emit_above(tui, "Enter to submit, Shift+Enter for newline, Ctrl+D to exit", style: :system)
    else
      emit_above(tui, "Enter to submit, Ctrl+N for multi-line mode, Ctrl+D to exit", style: :system)
    end

    run_event_loop(tui)
  end

  save_history
  puts "Goodbye!"
ensure
  disable_kitty_keyboard
  @running = false
  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