1+ #!/usr/bin/env ruby
2+ # frozen_string_literal: true
3+
4+ require "bundler/setup"
5+ require "thor/interactive"
6+
7+ class SignalDemo < Thor
8+ include Thor ::Interactive ::Command
9+
10+ configure_interactive (
11+ prompt : "signal> " ,
12+ ctrl_c_behavior : :clear_prompt , # Default
13+ double_ctrl_c_timeout : 0.5 # 500ms window for double Ctrl-C
14+ )
15+
16+ desc "slow" , "Simulate a slow command"
17+ def slow
18+ puts "Starting slow operation..."
19+ 5 . times do |i |
20+ puts "Step #{ i + 1 } /5"
21+ sleep ( 1 )
22+ end
23+ puts "Done!"
24+ rescue Interrupt
25+ puts "\n Operation cancelled!"
26+ end
27+
28+ desc "loop" , "Run an infinite loop (test Ctrl-C)"
29+ def loop
30+ puts "Starting infinite loop (press Ctrl-C to stop)..."
31+ counter = 0
32+ while true
33+ print "\r Counter: #{ counter } "
34+ counter += 1
35+ sleep ( 0.1 )
36+ end
37+ rescue Interrupt
38+ puts "\n Loop stopped at #{ counter } "
39+ end
40+
41+ desc "input" , "Test input with special text"
42+ def input
43+ puts "Type something with Ctrl chars:"
44+ puts " - Ctrl-C to clear and start over"
45+ puts " - Ctrl-D to cancel"
46+ puts " - Enter to submit"
47+
48+ print "input> "
49+ begin
50+ text = $stdin. gets
51+ if text
52+ puts "You entered: #{ text . inspect } "
53+ else
54+ puts "Cancelled with Ctrl-D"
55+ end
56+ rescue Interrupt
57+ puts "\n Interrupted - input cancelled"
58+ end
59+ end
60+
61+ desc "behaviors" , "Demo different Ctrl-C behaviors"
62+ def behaviors
63+ puts "\n === Ctrl-C Behavior Options ==="
64+ puts
65+ puts "1. :clear_prompt (default)"
66+ puts " - Shows ^C and hint message"
67+ puts " - Clear and friendly"
68+
69+ puts "\n 2. :show_help"
70+ puts " - Shows help reminder"
71+ puts " - Good for new users"
72+
73+ puts "\n 3. :silent"
74+ puts " - Just clears the line"
75+ puts " - Minimal interruption"
76+
77+ puts "\n You can configure with:"
78+ puts " configure_interactive(ctrl_c_behavior: :show_help)"
79+ end
80+
81+ desc "test_clear" , "Test with clear_prompt behavior"
82+ def test_clear
83+ puts "Starting new shell with :clear_prompt behavior"
84+ puts "Try pressing Ctrl-C..."
85+ puts
86+
87+ SignalDemo . new . interactive
88+ end
89+
90+ desc "test_help" , "Test with show_help behavior"
91+ def test_help
92+ puts "Starting new shell with :show_help behavior"
93+ puts "Try pressing Ctrl-C..."
94+ puts
95+
96+ test_app = Class . new ( Thor ) do
97+ include Thor ::Interactive ::Command
98+ configure_interactive (
99+ prompt : "help> " ,
100+ ctrl_c_behavior : :show_help
101+ )
102+
103+ desc "test" , "Test command"
104+ def test
105+ puts "Test executed"
106+ end
107+ end
108+
109+ test_app . new . interactive
110+ end
111+
112+ desc "test_silent" , "Test with silent behavior"
113+ def test_silent
114+ puts "Starting new shell with :silent behavior"
115+ puts "Try pressing Ctrl-C..."
116+ puts
117+
118+ test_app = Class . new ( Thor ) do
119+ include Thor ::Interactive ::Command
120+ configure_interactive (
121+ prompt : "silent> " ,
122+ ctrl_c_behavior : :silent
123+ )
124+
125+ desc "test" , "Test command"
126+ def test
127+ puts "Test executed"
128+ end
129+ end
130+
131+ test_app . new . interactive
132+ end
133+
134+ desc "help_signals" , "Explain signal handling"
135+ def help_signals
136+ puts <<~HELP
137+
138+ === Signal Handling in thor-interactive ===
139+
140+ CTRL-C (SIGINT):
141+ Single Press:
142+ - Clears current input line
143+ - Shows hint about double Ctrl-C
144+ - Returns to fresh prompt
145+
146+ Double Press (within 500ms):
147+ - Exits the interactive shell
148+ - Same as typing 'exit'
149+
150+ CTRL-D (EOF):
151+ - Exits immediately
152+ - Standard Unix EOF behavior
153+ - Same as typing 'exit'
154+
155+ EXIT COMMANDS:
156+ - exit
157+ - quit
158+ - q
159+ - /exit, /quit, /q (with slash)
160+
161+ CONFIGURATION:
162+ configure_interactive(
163+ ctrl_c_behavior: :clear_prompt, # or :show_help, :silent
164+ double_ctrl_c_timeout: 0.5 # seconds
165+ )
166+
167+ BEHAVIOR OPTIONS:
168+ :clear_prompt (default)
169+ Shows "^C" and hint message
170+
171+ :show_help
172+ Shows help reminder on Ctrl-C
173+
174+ :silent
175+ Just clears the line, no message
176+
177+ WHY THIS DESIGN?
178+ - Matches behavior of Python, Node.js REPLs
179+ - Prevents accidental exit
180+ - Clear feedback to user
181+ - Configurable for different preferences
182+
183+ HELP
184+ end
185+
186+ default_task :help_signals
187+ end
188+
189+ if __FILE__ == $0
190+ puts "Signal Handling Demo"
191+ puts "==================="
192+ puts
193+ puts "Try these:"
194+ puts " 1. Press Ctrl-C once (clears prompt)"
195+ puts " 2. Press Ctrl-C twice quickly (exits)"
196+ puts " 3. Press Ctrl-D (exits immediately)"
197+ puts " 4. Type 'exit', 'quit', or 'q' (exits)"
198+ puts
199+ puts "Starting interactive shell..."
200+ puts
201+
202+ SignalDemo . new . interactive
203+ end
0 commit comments