diff --git a/docs/src/terminals.md b/docs/src/terminals.md index 875cd50..d7893e2 100644 --- a/docs/src/terminals.md +++ b/docs/src/terminals.md @@ -28,7 +28,31 @@ Press the `h` key on the window to display an help message with all available ke ## Plot in a terminal application (`dumb`, `sixel` and `sixelgd`) Gnuplot supports plotting in a terminal application, with no need for X11 or other GUI support, via the `dumb`, `sixel` and `sixelgd` terminals. These are extremely useful when you run Julia on a remote shell through `ssh`, with no X11 forwarding. -The `dumb` terminal uses ASCII characters to draw a plot, while `sixel` and `sixelgd` actually use bitmaps (but require Sixel support to be enabled in the terminal, e.g. `xterm -ti vt340`). A sixel plot on `xterm` looks as follows: +The `dumb` terminal uses ASCII characters to draw a plot, while `sixel` and `sixelgd` actually use bitmaps (but require Sixel support to be enabled in the terminal, e.g. `xterm -ti vt340`). Dumb terminal can be used as follows: + +```jldoctest; setup = :(using Gnuplot; origterm = Gnuplot.options.term) +julia> Gnuplot.options.term = "dumb size 60,15"; + +julia> @gp "plot sin(x)" + + 1 +-------------------------------------------------+ + 0.8 |-+ *+ * + ** ** + * * +-| + 0.6 |-+ * ** * * sin(x) *******-| + 0.4 |*+ * * * * * *+-| + 0.2 |*+ * * * * * *-| + 0 |*+ * * * * * *-| + | * * * * * * *| + -0.2 |-* * * * * * +*| + -0.4 |-+* * * * * * +*| + -0.6 |-+* * * * ** * +-| + -0.8 |-+ * * + ** ** + * * +-| + -1 +-------------------------------------------------+ + -10 -5 0 5 10 + +julia> Gnuplot.options.term = origterm; + +``` +A sixel plot on `xterm` looks as follows: ![](assets/sixelgd.png) The above terminals are available if gnuplot has been compiled with the `--with-bitmap-terminals` option enabled and Libgd (only for `sixelgd`). diff --git a/src/Gnuplot.jl b/src/Gnuplot.jl index c6ba948..ad14df4 100644 --- a/src/Gnuplot.jl +++ b/src/Gnuplot.jl @@ -520,6 +520,18 @@ function readTask(gp::GPSession) delete!(sessions, gp.sid) end +# Read data from `from` and forward them to `stdout`. +# +# This is similar to `Base.write(to::IO, from::IO)` when called as +# write(stdout, from), but the difference is in situation when +# `stdout` changes. This function writes data to the changed `stdout`, +# whereas the call to `Base.write` writes to the original `stdout` +# forever. +function writeToStdout(from::IO) + while !eof(from) + write(stdout, readavailable(from)) + end +end function GPSession(sid::Symbol) session = DrySession(sid) @@ -535,13 +547,16 @@ function GPSession(sid::Symbol) end pin = Base.Pipe() + pout = Base.Pipe() perr = Base.Pipe() - proc = run(pipeline(`$(options.cmd)`, stdin=pin, stdout=stdout, stderr=perr), wait=false) + proc = run(pipeline(`$(options.cmd)`, stdin=pin, stdout=pout, stderr=perr), wait=false) chan = Channel{String}(32) # Close unused sides of the pipes + Base.close(pout.in) Base.close(perr.in) Base.close(pin.out) + Base.start_reading(pout.out) Base.start_reading(perr.out) out = GPSession(getfield.(Ref(session), fieldnames(DrySession))..., @@ -550,6 +565,7 @@ function GPSession(sid::Symbol) # Start reading tasks @async readTask(out) + @async writeToStdout(pout) # Read gnuplot default terminal if options.term == ""