Skip to content

Commit

Permalink
fix IO colorization for Julia 0.7, remove some type piracy hacks
Browse files Browse the repository at this point in the history
  • Loading branch information
stevengj committed Dec 18, 2017
1 parent 51a1e54 commit 8b7ee4c
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 23 deletions.
2 changes: 1 addition & 1 deletion REQUIRE
Expand Up @@ -2,5 +2,5 @@ julia 0.5
MbedTLS 0.4.3
JSON 0.5
ZMQ 0.3.3
Compat 0.33.0
Compat 0.40.0
Conda 0.1.5
3 changes: 3 additions & 0 deletions src/init.jl
Expand Up @@ -90,10 +90,13 @@ function init(args)
start_heartbeat(heartbeat[])
if capture_stdout
read_stdout[], = redirect_stdout()
eval(Base, :(STDOUT = $(IJuliaStdio(STDOUT,"stdout"))))
end
if capture_stderr
read_stderr[], = redirect_stderr()
eval(Base, :(STDERR = $(IJuliaStdio(STDERR,"stderr"))))
end
eval(Base, :(STDIN = $(IJuliaStdio(STDIN,"stdin"))))

send_status("starting")
global inited = true
Expand Down
4 changes: 2 additions & 2 deletions src/inline.jl
Expand Up @@ -21,14 +21,14 @@ function limitstringmime(mime::MIME, x)
if israwtext(mime, x)
return String(x)
else
show(IOContext(buf, :limit=>true), mime, x)
show(IOContext(buf, :limit=>true, :color=>true), mime, x)
end
else
b64 = Base64EncodePipe(buf)
if isa(x, Vector{UInt8})
write(b64, x) # x assumed to be raw binary data
else
show(IOContext(b64, :limit=>true), mime, x)
show(IOContext(b64, :limit=>true, :color=>true), mime, x)
end
close(b64)
end
Expand Down
52 changes: 32 additions & 20 deletions src/stdio.jl
@@ -1,6 +1,28 @@
# During handling of an execute_request (when execute_msg is !nothing),
# we redirect STDOUT and STDERR into "stream" messages sent to the IPython
# front-end.
# IJulia redirects STDOUT and STDERR into "stream" messages sent to the
# Jupyter front-end.

# create a wrapper type around redirected stdio streams,
# both for overloading things like `flush` and so that we
# can set properties like `color`.
immutable IJuliaStdio{IO_t <: IO} <: Base.AbstractPipe
io::IOContext{IO_t}
end
IJuliaStdio(io::IO, stream::AbstractString="unknown") =
IJuliaStdio{typeof(io)}(IOContext(io, :color=>Base.have_color,
:jupyter_stream=>stream,
:displaysize=>displaysize()))
Base.pipe_reader(io::IJuliaStdio) = io.io.io
Base.pipe_writer(io::IJuliaStdio) = io.io.io
Base.lock(io::IJuliaStdio) = lock(io.io.io)
Base.unlock(io::IJuliaStdio) = unlock(io.io.io)
Base.in(key_value::Pair, io::IJuliaStdio) = in(key_value, io.io)
Base.haskey(io::IJuliaStdio, key) = haskey(io.io, key)
Base.getindex(io::IJuliaStdio, key) = getindex(io.io, key)
Base.get(io::IJuliaStdio, key, default) = get(io.io, key, default)
Base.displaysize(io::IJuliaStdio) = displaysize(io.io)
if VERSION >= v"0.7.0-DEV.1472" # Julia PR #23271
Base.unwrapcontext(io::IJuliaStdio) = Base.unwrapcontext(io.io)
end

# logging in verbose mode goes to original stdio streams. Use macros
# so that we do not even evaluate the arguments in no-verbose modes
Expand Down Expand Up @@ -175,21 +197,16 @@ function readprompt(prompt::AbstractString; password::Bool=false)
end
end


# this is hacky: we overload some of the I/O functions on pipe endpoints
# in order to fix some interactions with stdio.
const StdioPipe = Base.PipeEndpoint

# IJulia issue #42: there doesn't seem to be a good way to make a task
# that blocks until there is a read request from STDIN ... this makes
# it very hard to properly redirect all reads from STDIN to pyin messages.
# In the meantime, however, we can just hack it so that readline works:
import Base.readline
function readline(io::StdioPipe)
if io == STDIN
function readline(io::IJuliaStdio)
if get(io,:jupyter_stream,"unknown") == "stdin"
return readprompt("STDIN> ")
else
invoke(readline, Tuple{supertype(StdioPipe)}, io)
readline(io.io)
end
end

Expand Down Expand Up @@ -224,13 +241,8 @@ function oslibuv_flush()
end

import Base.flush
function flush(io::StdioPipe)
invoke(flush, Tuple{supertype(StdioPipe)}, io)
if io == STDOUT
oslibuv_flush()
send_stream("stdout")
elseif io == STDERR
oslibuv_flush()
send_stream("stderr")
end
function flush(io::IJuliaStdio)
flush(io.io)
oslibuv_flush()
send_stream(get(io,:jupyter_stream,"unknown"))
end

0 comments on commit 8b7ee4c

Please sign in to comment.