@@ -484,10 +484,70 @@ function repl_backend_loop(backend::REPLBackend, get_module::Function)
484484 return nothing
485485end
486486
487+ SHOW_MAXIMUM_BYTES:: Int = 20480
488+
489+ # Limit printing during REPL display
490+ mutable struct LimitIO{IO_t <: IO } <: IO
491+ io:: IO_t
492+ maxbytes:: Int
493+ n:: Int # max bytes to write
494+ end
495+ LimitIO (io:: IO , maxbytes) = LimitIO (io, maxbytes, 0 )
496+
497+ struct LimitIOException <: Exception
498+ maxbytes:: Int
499+ end
500+
501+ function Base. showerror (io:: IO , e:: LimitIOException )
502+ print (io, " $LimitIOException : aborted printing after attempting to print more than $(Base. format_bytes (e. maxbytes)) within a `LimitIO`." )
503+ end
504+
505+ function Base. write (io:: LimitIO , v:: UInt8 )
506+ io. n > io. maxbytes && throw (LimitIOException (io. maxbytes))
507+ n_bytes = write (io. io, v)
508+ io. n += n_bytes
509+ return n_bytes
510+ end
511+
512+ # Semantically, we only need to override `Base.write`, but we also
513+ # override `unsafe_write` for performance.
514+ function Base. unsafe_write (limiter:: LimitIO , p:: Ptr{UInt8} , nb:: UInt )
515+ # already exceeded? throw
516+ limiter. n > limiter. maxbytes && throw (LimitIOException (limiter. maxbytes))
517+ remaining = limiter. maxbytes - limiter. n # >= 0
518+
519+ # Not enough bytes left; we will print up to the limit, then throw
520+ if remaining < nb
521+ if remaining > 0
522+ Base. unsafe_write (limiter. io, p, remaining)
523+ end
524+ throw (LimitIOException (limiter. maxbytes))
525+ end
526+
527+ # We won't hit the limit so we'll write the full `nb` bytes
528+ bytes_written = Base. unsafe_write (limiter. io, p, nb)
529+ limiter. n += bytes_written
530+ return bytes_written
531+ end
532+
487533struct REPLDisplay{Repl<: AbstractREPL } <: AbstractDisplay
488534 repl:: Repl
489535end
490536
537+ function show_limited (io:: IO , mime:: MIME , x)
538+ try
539+ # We wrap in a LimitIO to limit the amount of printing.
540+ # We unpack `IOContext`s, since we will pass the properties on the outside.
541+ inner = io isa IOContext ? io. io : io
542+ wrapped_limiter = IOContext (LimitIO (inner, SHOW_MAXIMUM_BYTES), io)
543+ # `show_repl` to allow the hook with special syntax highlighting
544+ show_repl (wrapped_limiter, mime, x)
545+ catch e
546+ e isa LimitIOException || rethrow ()
547+ printstyled (io, """ …[printing stopped after displaying $(Base. format_bytes (e. maxbytes)) ; call `show(stdout, MIME"text/plain"(), ans)` to print without truncation]""" ; color= :light_yellow , bold= true )
548+ end
549+ end
550+
491551function display (d:: REPLDisplay , mime:: MIME"text/plain" , x)
492552 x = Ref {Any} (x)
493553 with_repl_linfo (d. repl) do io
@@ -504,7 +564,7 @@ function display(d::REPLDisplay, mime::MIME"text/plain", x)
504564 # this can override the :limit property set initially
505565 io = foldl (IOContext, d. repl. options. iocontext, init= io)
506566 end
507- show_repl (io, mime, x[])
567+ show_limited (io, mime, x[])
508568 println (io)
509569 end
510570 return nothing
0 commit comments