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