Overload show and keep default Juno rendering

Assume I have custom type

struct Foo
    x::Int
end

for which I want do define pretty printing. If I overload Base.show(io, x)

Base.show(io::IO, foo::Foo) = print(io, "Foo with value $(foo.x)")

everything works great, but I loose the default tree view rendering in Juno.
If I instead just define

Base.show(io::IO, ::MIME"text/plain", foo::Foo) = print(io, "Foo with value $(foo.x)")

then I still have the nice inline tree view in Juno, but now the printing doesn’t work anymore e.g. in tuple

julia> (Foo(2),)
(Foo(2),)

Now I obviously could use TreeViews.jl to define my custom logic but this is quite tedious. Is there a way to keep the default inline rendering in Juno while I overload Base.show(io, x)?

See the Juno docs:
http://docs.junolab.org/latest/man/info_developer.html#Custom-Inline-Display-1

Edit: Hm, didn’t read the end of your post :slight_smile:

So, it should be sufficient to define TreeViews.hastreeview(::Foo) = true.
I guess we could also special case show(io::IO, ::MIME"application/juno+inline", ...) as an alias for text/plain in Juno.

Okay, so I’ve gone ahead and added something like that here.

Basically, you can now define a show(io::IO, ::MIME"application/juno+inline", ::Foo) method, which has a lower priority than the TreeViews.jl stuff, but a higher priority than show(io::IO, MIME"text/plain", ::Foo). If you just print to io in that method then we’ll display that as we would text/plain, but if you return a object (which isn’t nothing) you’ll get the default Juno rendering for that object. This is a bit of an abuse of the display system, but w/e.

For your example you’d want

struct Foo
  x
end

Base.show(io::IO, ::Foo) = print(io, "Foo!")
Base.show(io::IO, ::MIME"application/juno+inline", x::Foo) = x

and get nice printing both in Juno and the REPL.

3 Likes