@@ -76,10 +76,10 @@ mutable struct MIState
76
76
key_repeats:: Int
77
77
last_action:: Symbol
78
78
current_action:: Symbol
79
- async_channel:: Channel
79
+ async_channel:: Channel{Function}
80
80
end
81
81
82
- MIState (i, mod, c, a, m) = MIState (i, mod, c, a, m, String[], 0 , Char[], 0 , :none , :none , Channel ())
82
+ MIState (i, mod, c, a, m) = MIState (i, mod, c, a, m, String[], 0 , Char[], 0 , :none , :none , Channel {Function} ())
83
83
84
84
const BufferLike = Union{MIState,ModeState,IOBuffer}
85
85
const State = Union{MIState,ModeState}
@@ -2829,40 +2829,45 @@ function prompt!(term::TextTerminal, prompt::ModalInterface, s::MIState = init_s
2829
2829
try
2830
2830
activate (prompt, s, term, term)
2831
2831
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)
2832
2839
while true
2833
2840
kmap = keymap (s, prompt)
2834
- waitany ((
2835
- @async ( eof (term) || peek (term, Char)),
2836
- @async ( wait (s . async_channel)),
2837
- ), throw = true )
2838
- fcn = isempty (s . async_channel) ? match_input (kmap, s) : take! (s . async_channel)
2839
- kdata = keymap_data (s, prompt)
2840
- s . current_action = :unknown # if the to-be-run action doesn 't update this field,
2841
- # :unknown will be recorded in the last_action field
2842
- local status
2843
- # errors in keymaps shouldn't cause the REPL to fail, so wrap in a
2844
- # try/ catch block
2845
- try
2846
- status = fcn (s, kdata)
2847
- catch e
2848
- @error " Error in the keymap " exception = e, catch_backtrace ( )
2849
- # try to cleanup and get `s` back to its original state before returning
2850
- transition (s, :reset )
2851
- transition (s, old_state )
2852
- status = :done
2853
- end
2854
- status != = :ignore && (s . last_action = s . current_action)
2855
- if status === :abort
2856
- s . aborted = true
2857
- return buffer (s), false , false
2858
- elseif status === :done
2859
- return buffer (s), true , false
2860
- elseif status === :suspend
2861
- if Sys . isunix ()
2862
- return buffer (s), true , true
2841
+ fcn = match_input (kmap, s)
2842
+ @lock l begin
2843
+ kdata = keymap_data (s, prompt)
2844
+ s . current_action = :unknown # if the to-be-run action doesn't update this field,
2845
+ # :unknown will be recorded in the last_action field
2846
+ local status
2847
+ # errors in keymaps shouldn 't cause the REPL to fail, so wrap in a
2848
+ # try/catch block
2849
+ try
2850
+ status = fcn (s, kdata)
2851
+ catch e
2852
+ @error " Error in the keymap " exception = e, catch_backtrace ()
2853
+ # try to cleanup and get `s` back to its original state before returning
2854
+ transition (s, :reset )
2855
+ transition (s, old_state )
2856
+ status = :done
2857
+ end
2858
+ status != = :ignore && (s . last_action = s . current_action )
2859
+ if status === :abort
2860
+ s . aborted = true
2861
+ return buffer (s), false , false
2862
+ elseif status === :done
2863
+ return buffer (s), true , false
2864
+ elseif status === :suspend
2865
+ if Sys . isunix ()
2866
+ return buffer (s), true , true
2867
+ end
2868
+ else
2869
+ @assert status ∈ ( :ok , :ignore )
2863
2870
end
2864
- else
2865
- @assert status ∈ (:ok , :ignore )
2866
2871
end
2867
2872
end
2868
2873
finally
0 commit comments