@@ -2823,22 +2823,27 @@ keymap_data(ms::MIState, m::ModalInterface) = keymap_data(state(ms), mode(ms))
2823
2823
2824
2824
function prompt! (term:: TextTerminal , prompt:: ModalInterface , s:: MIState = init_state (term, prompt))
2825
2825
Base. reseteof (term)
2826
+ l = Base. ReentrantLock ()
2827
+ t1 = Threads. @spawn :interactive while true
2828
+ wait (s. async_channel)
2829
+ status = @lock l begin
2830
+ fcn = take! (s. async_channel)
2831
+ fcn (s)
2832
+ end
2833
+ status ∈ (:ok , :ignore ) || break
2834
+ end
2826
2835
raw! (term, true )
2827
2836
enable_bracketed_paste (term)
2828
2837
try
2829
2838
activate (prompt, s, term, term)
2830
2839
old_state = mode (s)
2831
- l = Base. ReentrantLock ()
2832
- t = @async while true
2833
- fcn = take! (s. async_channel)
2834
- status = @lock l fcn (s)
2835
- status ∈ (:ok , :ignore ) || break
2836
- end
2837
- Base. errormonitor (t)
2838
- while true
2839
- kmap = keymap (s, prompt)
2840
- fcn = match_input (kmap, s)
2840
+ # spawn this because the main repl task is sticky (due to use of @async and _wait2)
2841
+ # and we want to not block typing when the repl task thread is busy
2842
+ t2 = Threads. @spawn :interactive while true
2843
+ eof (term) || peek (term, Char) # wait before locking but don't consume
2841
2844
@lock l begin
2845
+ kmap = keymap (s, prompt)
2846
+ fcn = match_input (kmap, s)
2842
2847
kdata = keymap_data (s, prompt)
2843
2848
s. current_action = :unknown # if the to-be-run action doesn't update this field,
2844
2849
# :unknown will be recorded in the last_action field
@@ -2869,7 +2874,10 @@ function prompt!(term::TextTerminal, prompt::ModalInterface, s::MIState = init_s
2869
2874
end
2870
2875
end
2871
2876
end
2877
+ return fetch (t2)
2872
2878
finally
2879
+ put! (s. async_channel, Returns (:done ))
2880
+ wait (t1)
2873
2881
raw! (term, false ) && disable_bracketed_paste (term)
2874
2882
end
2875
2883
# unreachable
0 commit comments