Added repl_init; Added gpreadline to cope with pager output and repl

This commit is contained in:
Giorgio Calderone 2020-04-11 23:40:19 +02:00
parent 9bb35931b6
commit 3505403499
2 changed files with 93 additions and 23 deletions

View File

@ -7,16 +7,18 @@ ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
ReplMaker = "b873ce64-0db9-51f5-a568-4457d8e49576"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
StructC14N = "d2514e9c-36c4-5b8e-97e2-51e7675c221c" StructC14N = "d2514e9c-36c4-5b8e-97e2-51e7675c221c"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
[compat] [compat]
julia = "^1.2"
ColorSchemes = "^3.5" ColorSchemes = "^3.5"
ColorTypes = "^0.10" ColorTypes = "^0.10"
Colors = "^0.12" Colors = "^0.12"
DataStructures = "^0.17" DataStructures = "^0.17"
ReplMaker="^0.2"
StatsBase = "^0.33" StatsBase = "^0.33"
StructC14N = "^0.3" StructC14N = "^0.3"
julia = "^1.2"

View File

@ -1,6 +1,7 @@
module Gnuplot module Gnuplot
using StatsBase, ColorSchemes, ColorTypes, Colors, StructC14N, DataStructures using StatsBase, ColorSchemes, ColorTypes, Colors, StructC14N, DataStructures
using REPL, ReplMaker
import Base.reset import Base.reset
import Base.write import Base.write
@ -284,26 +285,47 @@ end
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
pagerTokens() = ["Press return for more:"]
function GPSession(sid::Symbol) function GPSession(sid::Symbol)
function readTask(sid, stream, channel) function readTask(sid, stream, channel)
saveOutput = false function gpreadline(stream)
line = ""
while isopen(stream) while true
line = readline(stream) c = read(stream, Char)
if (length(line) >= 1) && (line[1] == Char(0x1b)) # Escape (xterm -ti vt340) (c == '\r') && continue
buf = Vector{UInt8}() (c == '\n') && break
append!(buf, convert(Vector{UInt8}, [line...])) if c == Char(0x1b)
push!(buf, 0x0a) buf = Vector{UInt8}()
c = 0x00 push!(buf, UInt8(c))
while c != 0x1b while true
c = read(stream, 1)[1] c = read(stream, Char)
push!(buf, c) push!(buf, UInt8(c))
(c == Char(0x1b)) && break
end
c = read(stream, Char)
push!(buf, UInt8(c))
write(stdout, buf)
continue
end
line *= c
for token in pagerTokens()
if (length(line) == length(token)) && (line == token)
return line
end
end end
c = read(stream, 1)[1]
push!(buf, c)
write(stdout, buf)
continue
end end
if (line != "GNUPLOT_CAPTURE_BEGIN") &&
(line != "GNUPLOT_CAPTURE_END") &&
(Base.active_repl.mistate.current_mode.prompt == "gnuplot> ")
println(stdout, line)
end
return line
end
saveOutput = false
while isopen(stream)
line = gpreadline(stream)
if line == "GNUPLOT_CAPTURE_BEGIN" if line == "GNUPLOT_CAPTURE_BEGIN"
saveOutput = true saveOutput = true
elseif line == "GNUPLOT_CAPTURE_END" elseif line == "GNUPLOT_CAPTURE_END"
@ -454,8 +476,26 @@ function writeread(gp::GPSession, str::AbstractString)
out = Vector{String}() out = Vector{String}()
while true while true
l = take!(gp.channel) l = take!(gp.channel)
l == "GNUPLOT_CAPTURE_END" && break if l in pagerTokens()
push!(out, l) # Consume all data from the pager
while true
write(gp, "")
sleep(0.5)
if isready(gp.channel)
while isready(gp.channel)
push!(out, take!(gp.channel))
end
else
options.verbose = false
write(gp, "print 'GNUPLOT_CAPTURE_END'")
options.verbose = verbose
break
end
end
else
l == "GNUPLOT_CAPTURE_END" && break
push!(out, l)
end
end end
return out return out
end end
@ -744,10 +784,10 @@ function gpexec(gp::GPSession, command::String)
verbose = options.verbose verbose = options.verbose
options.verbose = false options.verbose = false
errno = writeread(gp, "print GPVAL_ERRNO")[1] errno = writeread(gp, "print GPVAL_ERRNO")
options.verbose = verbose options.verbose = verbose
@assert length(errno) == 1
if errno != "0" if errno[1] != "0"
@error "\n" * join(answer, "\n") @error "\n" * join(answer, "\n")
errmsg = writeread(gp, "print GPVAL_ERRMSG") errmsg = writeread(gp, "print GPVAL_ERRMSG")
write(gp.pin, "reset error\n") write(gp.pin, "reset error\n")
@ -1684,4 +1724,32 @@ function contourlines(args...; cntrparam="level auto 10")
return out return out
end end
"""
Gnuplot.init_repl(start_key='>')
Install a hook to replace the common Julia REPL with a gnuplot one. The key to start the REPL is the one provided in `start_key` (default: `>`).
Note: the gnuplot REPL operates only on the default session.
"""
function repl_init(start_key='>')
function repl_exec(s)
writeread(getsession(), s)
nothing
end
function repl_isvalid(s)
input = strip(String(take!(copy(REPL.LineEdit.buffer(s)))))
(length(input) == 0) || (input[end] != '\\')
end
initrepl(repl_exec,
prompt_text="gnuplot> ",
prompt_color = :blue,
start_key=start_key,
mode_name="Gnuplot",
completion_provider=nothing, # TODO: fix autocompletion
valid_input_checker=repl_isvalid, sticky_mode=false)
end
end #module end #module