1
1
# frozen_string_literal: true
2
2
3
+ begin
4
+ require 'pty'
5
+ rescue LoadError
6
+ # Ignore, fallback not to use interceptor
7
+ end
8
+
3
9
module RubyJard
4
10
# Pry depends heavily on GNU Readline, or any Readline-like input libraries. Those libraries
5
11
# serve limited use cases, and specific interface to support those. Unfortunately, to serve
@@ -44,8 +50,8 @@ class ReplInterceptor
44
50
RubyJard ::Keys ::CTRL_C => ( KEY_BINDING_INTERRUPT = :interrupt )
45
51
} . freeze
46
52
47
- KEY_READ_TIMEOUT = 0.2 # 200ms
48
- PTY_OUTPUT_TIMEOUT = 1 . to_f / 60 # 60hz
53
+ KEY_READ_TIMEOUT = 0.2 # 200ms
54
+ OUTPUT_TICK = 1 . to_f / 60 # 60hz
49
55
50
56
def initialize ( state , console , key_bindings )
51
57
@state = state
@@ -68,14 +74,16 @@ def start
68
74
def stop
69
75
@key_listen_thread &.exit if @key_listen_thread &.alive?
70
76
if interceptable?
71
- sleep PTY_OUTPUT_TIMEOUT until @state . exited?
77
+ sleep OUTPUT_TICK until @state . exited?
72
78
else
73
79
@state . exited!
74
80
end
75
81
end
76
82
77
83
def dispatch_command ( command )
78
- @input_writer . write ( "#{ RubyJard ::ReplManager ::COMMAND_ESCAPE_SEQUENCE } #{ command } \n " )
84
+ @input_writer . write (
85
+ "#{ RubyJard ::ReplSequence . encode ( command ) } \n "
86
+ )
79
87
end
80
88
81
89
def feed_output ( content )
@@ -105,6 +113,7 @@ def redirected_output
105
113
end
106
114
107
115
def interceptable?
116
+ return false unless defined? ( PTY )
108
117
return false if defined? ( Reline ) && Readline == Reline
109
118
return false if RubyJard ::Reflection . instance . call_method ( ::Readline , :input= ) . source_location != nil
110
119
return false if RubyJard ::Reflection . instance . call_method ( ::Readline , :output= ) . source_location != nil
@@ -160,7 +169,7 @@ def output_bridge
160
169
@state . exited!
161
170
end
162
171
elsif @state . exited?
163
- sleep PTY_OUTPUT_TIMEOUT
172
+ sleep OUTPUT_TICK
164
173
else
165
174
content = @output_reader . read_nonblock ( 2048 )
166
175
unless content . nil?
@@ -169,7 +178,7 @@ def output_bridge
169
178
end
170
179
rescue IO ::WaitReadable , IO ::WaitWritable
171
180
# Retry
172
- sleep PTY_OUTPUT_TIMEOUT
181
+ sleep OUTPUT_TICK
173
182
end
174
183
rescue StandardError
175
184
# This thread shoud never die, or the user may be freezed, and cannot type anything
@@ -184,7 +193,7 @@ def listen_key_press
184
193
185
194
if @state . processing? && @state . pager?
186
195
# Discard all keys unfortunately
187
- sleep PTY_OUTPUT_TIMEOUT
196
+ sleep OUTPUT_TICK
188
197
else
189
198
key = @key_bindings . match { @console . getch ( KEY_READ_TIMEOUT ) }
190
199
if key . is_a? ( RubyJard ::KeyBinding )
@@ -217,7 +226,7 @@ def handle_interrupt_command
217
226
end
218
227
loop do
219
228
begin
220
- sleep PTY_OUTPUT_TIMEOUT
229
+ sleep OUTPUT_TICK
221
230
rescue Interrupt
222
231
# Interrupt spam. Ignore.
223
232
end
@@ -226,7 +235,7 @@ def handle_interrupt_command
226
235
end
227
236
228
237
def write_output ( content )
229
- return if content . include? ( RubyJard ::ReplManager :: COMMAND_ESCAPE_SEQUENCE )
238
+ return if RubyJard ::ReplSequence . detect ( content )
230
239
231
240
@console . write content . force_encoding ( 'UTF-8' )
232
241
end
0 commit comments