@@ -102,6 +102,8 @@ mutable struct PromptState <: ModeState
102102 beeping:: Float64
103103 # this option is to detect when code is pasted in non-"bracketed paste mode" :
104104 last_newline:: Float64 # register when last newline was entered
105+ # this option is to speed up output
106+ refresh_wait:: Union{Timer,Nothing}
105107end
106108
107109options (s:: PromptState ) =
@@ -371,8 +373,17 @@ function complete_line(s::PromptState, repeats::Int)
371373 return true
372374end
373375
376+ function clear_input_area (terminal:: AbstractTerminal , s:: PromptState )
377+ if s. refresh_wait != = nothing
378+ close (s. refresh_wait)
379+ s. refresh_wait = nothing
380+ end
381+ _clear_input_area (terminal, s. ias)
382+ s. ias = InputAreaState (0 , 0 )
383+ end
374384clear_input_area (terminal:: AbstractTerminal , s:: ModeState ) = (_clear_input_area (terminal, s. ias); s. ias = InputAreaState (0 , 0 ))
375385clear_input_area (s:: ModeState ) = clear_input_area (s. terminal, s)
386+
376387function _clear_input_area (terminal:: AbstractTerminal , state:: InputAreaState )
377388 # Go to the last line
378389 if state. curs_row < state. num_rows
@@ -395,6 +406,13 @@ prompt_string(p::Prompt) = prompt_string(p.prompt)
395406prompt_string (s:: AbstractString ) = s
396407prompt_string (f:: Function ) = Base. invokelatest (f)
397408
409+ function refresh_multi_line (s:: PromptState ; kw... )
410+ if s. refresh_wait != = nothing
411+ close (s. refresh_wait)
412+ s. refresh_wait = nothing
413+ end
414+ refresh_multi_line (terminal (s), s; kw... )
415+ end
398416refresh_multi_line (s:: ModeState ; kw... ) = refresh_multi_line (terminal (s), s; kw... )
399417refresh_multi_line (termbuf:: TerminalBuffer , s:: ModeState ; kw... ) = refresh_multi_line (termbuf, terminal (s), s; kw... )
400418refresh_multi_line (termbuf:: TerminalBuffer , term, s:: ModeState ; kw... ) = (@assert term === terminal (s); refresh_multi_line (termbuf,s; kw... ))
@@ -738,7 +756,7 @@ function edit_insert(s::PromptState, c::StringLike)
738756 buf = s. input_buffer
739757
740758 if ! options (s). auto_indent_bracketed_paste
741- pos= position (buf)
759+ pos = position (buf)
742760 if pos > 0
743761 if buf. data[pos] != _space && string (c) != " "
744762 options (s). auto_indent_tmp_off = false
@@ -757,20 +775,46 @@ function edit_insert(s::PromptState, c::StringLike)
757775 end
758776 end
759777
778+ old_wait = s. refresh_wait != = nothing
779+ if old_wait
780+ close (s. refresh_wait)
781+ s. refresh_wait = nothing
782+ end
760783 str = string (c)
761784 edit_insert (buf, str)
762- offset = s. ias. curs_row == 1 || s. indent < 0 ?
763- sizeof (prompt_string (s. p. prompt):: String ) : s. indent
764- if ! (' \n ' in str) && eof (buf) &&
765- ((position (buf) - beginofline (buf) + # size of current line
766- offset + sizeof (str) - 1 ) < width (terminal (s)))
767- # Avoid full update when appending characters to the end
768- # and an update of curs_row isn't necessary (conservatively estimated)
769- write (terminal (s), str)
770- else
785+ if ' \n ' in str
771786 refresh_line (s)
787+ else
788+ after = options (s). auto_refresh_time_delay
789+ termbuf = terminal (s)
790+ w = width (termbuf)
791+ delayup = ! eof (buf) || old_wait
792+ offset = s. ias. curs_row == 1 || s. indent < 0 ?
793+ sizeof (prompt_string (s. p. prompt):: String ) : s. indent
794+ offset += position (buf) - beginofline (buf) # size of current line
795+ if offset + textwidth (str) <= w
796+ # Avoid full update when appending characters to the end
797+ # and an update of curs_row isn't necessary (conservatively estimated)
798+ write (termbuf, str)
799+ elseif after == 0
800+ refresh_line (s)
801+ delayup = false
802+ else
803+ delayup = true
804+ end
805+ if delayup
806+ write (termbuf, spin_seq[mod1 (position (buf) - w, length (spin_seq))])
807+ cmove_left (termbuf)
808+ s. refresh_wait = Timer (after) do t
809+ s. refresh_wait === t || return
810+ s. refresh_wait = nothing
811+ refresh_line (s)
812+ end
813+ end
772814 end
815+ nothing
773816end
817+ const spin_seq = (" ⋯" , " ⋱" , " ⋮" , " ⋰" )
774818
775819function edit_insert (buf:: IOBuffer , c:: StringLike )
776820 if eof (buf)
@@ -804,6 +848,7 @@ function edit_insert_newline(s::PromptState, align::Int = 0 - options(s).auto_in
804848 if ! options (s). auto_indent_bracketed_paste
805849 s. last_newline = time ()
806850 end
851+ nothing
807852end
808853
809854# align: delete up to 4 spaces to align to a multiple of 4 chars
@@ -2420,7 +2465,7 @@ run_interface(::Prompt) = nothing
24202465
24212466init_state (terminal, prompt:: Prompt ) =
24222467 PromptState (terminal, prompt, IOBuffer (), :off , IOBuffer[], 1 , InputAreaState (1 , 1 ),
2423- #= indent(spaces)=# - 1 , Threads. SpinLock (), 0.0 , - Inf )
2468+ #= indent(spaces)=# - 1 , Threads. SpinLock (), 0.0 , - Inf , nothing )
24242469
24252470function init_state (terminal, m:: ModalInterface )
24262471 s = MIState (m, m. modes[1 ], false , IdDict {Any,Any} ())
0 commit comments