Skip to content
This repository was archived by the owner on Mar 12, 2023. It is now read-only.

Commit 25e5c39

Browse files
committed
Check the possibility to intercept Readline's input and output
1 parent 4589f39 commit 25e5c39

File tree

3 files changed

+47
-23
lines changed

3 files changed

+47
-23
lines changed

lib/ruby_jard/pry_proxy.rb

+4
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ def pager
8181
RubyJard::Pager.new(self)
8282
end
8383

84+
def line_buffer
85+
Readline.line_buffer
86+
end
87+
8488
private
8589

8690
def pry_jard_prompt

lib/ruby_jard/repl_interceptor.rb

+14-6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ def start
2929

3030
def stop
3131
@key_listen_thread&.exit if @key_listen_thread&.alive?
32+
if interceptable?
33+
sleep PTY_OUTPUT_TIMEOUT until @state.exited?
34+
else
35+
@state.exited!
36+
end
3237
end
3338

3439
def dispatch_command(command)
@@ -61,14 +66,18 @@ def redirected_output
6166
@output_writer
6267
end
6368

64-
def redirectable?
69+
def interceptable?
70+
return false if defined?(Reline) && Readline == Reline
71+
return false if RubyJard::Reflection.instance.call_method(::Readline, :input=).source_location != nil
72+
return false if RubyJard::Reflection.instance.call_method(::Readline, :output=).source_location != nil
73+
6574
true
6675
end
6776

6877
private
6978

7079
def reopen_streams
71-
unless redirectable?
80+
unless interceptable?
7281
@input_reader = @console.input
7382
@input_writer = @console.input
7483
@output_reader = @console.output
@@ -86,7 +95,7 @@ def reopen_streams
8695
end
8796

8897
def start_output_bridge
89-
return unless redirectable?
98+
return unless interceptable?
9099

91100
@output_bridge_thread = Thread.new { output_bridge }
92101
@output_bridge_thread.abort_on_exception = true
@@ -95,7 +104,7 @@ def start_output_bridge
95104
end
96105

97106
def start_key_listen_thread
98-
return unless redirectable?
107+
return unless interceptable?
99108

100109
@main_thread = Thread.current
101110
@key_listen_thread = Thread.new { listen_key_press }
@@ -147,10 +156,9 @@ def listen_key_press
147156
end
148157
end
149158
end
150-
rescue StandardError => e
159+
rescue StandardError
151160
# This thread shoud never die, or the user may be freezed, and cannot type anything
152161
sleep 0.5
153-
RubyJard.debug(e.inspect)
154162
retry
155163
end
156164

lib/ruby_jard/repl_manager.rb

+29-17
Original file line numberDiff line numberDiff line change
@@ -64,51 +64,49 @@ def repl(current_binding)
6464

6565
@state.ready!
6666
@state.clear_pager!
67-
@console.disable_echo!
68-
@console.raw!
6967
@interceptor.start
7068

71-
pry_repl(current_binding)
69+
set_console_raw!
70+
unless @interceptor.interceptable?
71+
@console.output.puts '*Warning*: Key bindings are disabled! '\
72+
'There maybe a gem or a module touching Readline whose Jard depends on.'
73+
end
74+
75+
pry_proxy.repl(current_binding)
7276
ensure
77+
set_console_cooked!
7378
@state.exiting!
74-
sleep PTY_OUTPUT_TIMEOUT until @state.exited?
75-
@console.enable_echo!
76-
@console.cooked!
7779
@interceptor.stop
7880
end
7981

8082
private
8183

82-
def pry_repl(current_binding)
83-
pry_instance.repl(current_binding)
84-
end
85-
86-
def pry_instance
87-
PryProxy.new(
84+
def pry_proxy
85+
@pry_proxy = PryProxy.new(
8886
original_input: @interceptor.original_input,
8987
original_output: @interceptor.original_output,
9088
redirected_input: @interceptor.redirected_input,
9189
redirected_output: @interceptor.redirected_output,
9290
state_hooks: {
9391
after_read: proc {
94-
@console.cooked!
92+
set_console_cooked!
9593
@state.processing!
9694
# Sleep 2 ticks, wait for pry to print out all existing output in the queue
9795
sleep PTY_OUTPUT_TIMEOUT * 2
9896
},
9997
after_handle_line: proc {
100-
@console.raw!
98+
set_console_raw!
10199
@state.ready!
102100
},
103101
before_pager: proc {
104102
@state.processing!
105103
@state.set_pager!
106-
@console.cooked!
104+
set_console_cooked!
107105
},
108106
after_pager: proc {
109107
@state.ready!
110108
@state.clear_pager!
111-
@console.raw!
109+
set_console_raw!
112110
}
113111
}
114112
)
@@ -119,7 +117,7 @@ def start_resizing
119117

120118
@resizing = true
121119
@resizing_output_mark = @console.stdout_storage.length
122-
@resizing_readline_buffer = Readline.line_buffer unless @state.processing?
120+
@resizing_readline_buffer = @pry_proxy&.line_buffer unless @state.processing?
123121
@interceptor.dispatch_command('list')
124122
end
125123

@@ -141,5 +139,19 @@ def finish_resizing
141139
@resizing_output_mark = nil
142140
@resizing = false
143141
end
142+
143+
def set_console_cooked!
144+
return unless @interceptor.interceptable?
145+
146+
@console.enable_echo!
147+
@console.cooked!
148+
end
149+
150+
def set_console_raw!
151+
return unless @interceptor.interceptable?
152+
153+
@console.disable_echo!
154+
@console.raw!
155+
end
144156
end
145157
end

0 commit comments

Comments
 (0)