Skip to content

Commit 44bfd28

Browse files
committed
WiP: Switch to using display() to show the plots
This should ensure better compatibility with the Julia package ecosystem. Now, if Gnuplot.jl is used in an environment capable of showing multimedia content (IJulia, VS Code, Pluto), this will take precedence over using gnuplot's built-in viewer. In the REPL, gnuplot viewer is used by default. In VS Code, for example, when the "Use Plot Pane" settings is enabled, the plots show in that pane, but when it is disabled, gnuplot viewer is automatically used. For people who prefer to always use the gnuplot viewer, they can achieve that by running: popdisplay(Gnuplot.GnuplotDisplay()) pushdisplay(Gnuplot.GnuplotDisplay()) This ensures that the gnuplot display has the highest priority. However, note that VSCode ensures that its VSCodeDisplay is always the last and IJulia also ignores this. On the other hand, to disable the gnuplot viewer, one can run: Gnuplot.option.gpviewer = false What was tested: - [x] Plotting from REPL - [x] VS Code - [x] With Plot Pane enabled - [x] With Plot Pane disabled - [x] IJulia - [x] Gnuplot.jl test suite - [ ] DrySessions - [x] Pluto - [ ] Juno - [ ] Weave.jl
1 parent 04484ad commit 44bfd28

File tree

2 files changed

+48
-17
lines changed

2 files changed

+48
-17
lines changed

src/Gnuplot.jl

+30-17
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ Base.@kwdef mutable struct Options
222222
MIME"image/svg+xml" => "svg enhanced mouse standalone dynamic background rgb 'white'",
223223
MIME"text/html" => "svg enhanced mouse standalone dynamic", # canvas mousing
224224
MIME"text/plain" => "dumb enhanced ansi")
225-
gpviewer::Bool = false
225+
gpviewer::Bool = true
226226
init::Vector{String} = Vector{String}()
227227
verbose::Bool = false
228228
preferred_format::Symbol = :auto
@@ -236,14 +236,15 @@ const sessions = OrderedDict{Symbol, Session}()
236236
const options = Options()
237237

238238
function __init__()
239-
# Check whether we are running in an IJulia, Juno, VSCode or Pluto session.
240-
# (copied from Gaston.jl).
241-
options.gpviewer = !(
242-
((isdefined(Main, :IJulia) && Main.IJulia.inited) ||
243-
(isdefined(Main, :Juno) && Main.Juno.isactive()) ||
244-
(isdefined(Main, :VSCodeServer)) ||
245-
(isdefined(Main, :PlutoRunner)) )
246-
)
239+
# Copied from Plots - insert GnuplotDisplay before text displays, but after graphic displays such as IJulia, VSCodeDisplay, etc.
240+
insert!(Base.Multimedia.displays, findlast(x -> x isa Base.TextDisplay || x isa REPL.REPLDisplay, Base.Multimedia.displays) + 1, GnuplotDisplay())
241+
atreplinit(i -> begin
242+
while GnuplotDisplay() in Base.Multimedia.displays
243+
popdisplay(GnuplotDisplay())
244+
end
245+
insert!(Base.Multimedia.displays, findlast(x -> x isa REPL.REPLDisplay, Base.Multimedia.displays) + 1, GnuplotDisplay())
246+
end)
247+
247248
if isdefined(Main, :VSCodeServer)
248249
# VS Code shows "dynamic" plots with fixed and small size :-(
249250
options.mime[MIME"image/svg+xml"] = replace(options.mime[MIME"image/svg+xml"], "dynamic" => "")
@@ -583,8 +584,8 @@ function gp_write_table(args...; kw...)
583584
sid = Symbol("j", Base.Libc.getpid())
584585
gp = getsession(sid)
585586
reset(gp)
586-
gpexec(sid, "set term unknown")
587587
driver(sid, "set table '$tmpfile'", args...; kw...)
588+
execall(gp, term="unknown")
588589
gpexec(sid, "unset table")
589590
quit(sid)
590591
out = readlines(tmpfile)
@@ -767,7 +768,9 @@ function reset(gp::Session)
767768
gpexec(gp, "reset session")
768769

769770
if options.gpviewer
770-
# Use gnuplot viewer
771+
# Use gnuplot viewer. It would be more appropriate to do this in display(), but
772+
# doing so leads to hang of the gnuplot process (it receives the END marker, but
773+
# does not print it back).
771774
(options.term != "") && gpexec(gp, "set term " * options.term)
772775

773776
# Set window title (if not already set)
@@ -784,7 +787,7 @@ function reset(gp::Session)
784787
end
785788

786789
# Note: the reason to keep Options.term and .init separate are:
787-
# - .term can be overriden by "unknown" (if options.gpviewer is false);
790+
# - .term can be overriden by "unknown" (if options.gpviewer is false); TODO: Is this still true?
788791
# - .init is dumped in scripts, while .term is not;
789792
add_cmd.(Ref(gp), options.init)
790793
return nothing
@@ -1332,9 +1335,6 @@ function driver(_args...; is3d=false)
13321335
end
13331336
end
13341337

1335-
if options.gpviewer && doDump
1336-
execall(gp)
1337-
end
13381338
return SessionID(gp.sid, doDump)
13391339
end
13401340

@@ -1547,10 +1547,23 @@ end
15471547

15481548

15491549
# ╭───────────────────────────────────────────────────────────────────╮
1550-
# Interfacing Julia's show
1550+
# │ Interfacing Julia's Multimedia I/O
15511551
# ╰───────────────────────────────────────────────────────────────────╯
15521552
# --------------------------------------------------------------------
15531553

1554+
struct GnuplotDisplay <: AbstractDisplay end
1555+
1556+
function Base.display(d::GnuplotDisplay, obj::SessionID)
1557+
# Use this display only when options.gpviewer is set
1558+
if options.gpviewer && obj.dump
1559+
# TODO: Shall we ignore DrySession here?
1560+
gp = getsession(obj.sid)
1561+
execall(gp)
1562+
else
1563+
throw(MethodError(display, (d, obj)))
1564+
end
1565+
end
1566+
15541567
function show(obj::SessionID)
15551568
gp = getsession(obj.sid)
15561569
@info "Gnuplot session" sid=gp.sid datasets=length(gp.datas) plots=length(gp.plots)
@@ -1560,7 +1573,7 @@ show(io::IO, gp::SessionID) = nothing
15601573

15611574

15621575
function showable(mime::Type{T}, gp::SessionID) where T <: MIME
1563-
if gp.dump && !options.gpviewer
1576+
if gp.dump
15641577
if mime in keys(options.mime)
15651578
term = strip(options.mime[mime])
15661579
if term != ""

test/runtests.jl

+18
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,24 @@ dummy = terminals()
110110
# Force unknown on Travis CI
111111
Gnuplot.options.term = "unknown"
112112

113+
# Wrap @gp macrocalls in display() to ensure that the whole plot is
114+
# sent to the gnuplot process during testing.
115+
macro gp(args...)
116+
gpcall = :(Gnuplot.@gp)
117+
push!(gpcall.args, args...)
118+
out = :(display($gpcall))
119+
return esc(out)
120+
end
121+
122+
# Wrap @gsp macrocalls in display() to ensure that the whole plot is
123+
# sent to the gnuplot process during testing.
124+
macro gsp(args...)
125+
gpcall = :(Gnuplot.@gsp)
126+
push!(gpcall.args, args...)
127+
out = :(display($gpcall))
128+
return esc(out)
129+
end
130+
113131
@gp 1:9
114132
@info "using terminal: " terminal()
115133
#test_terminal("unknown")

0 commit comments

Comments
 (0)