Skip to content

Commit

Permalink
Fix diagnostics printing when pwd() doesn't exist (#373)
Browse files Browse the repository at this point in the history
Computing the file URL for pretty printing using `abspath` can fail when
the current working directory doesn't exist. This is a quick fix for
this issue (which is incredibly confusing/disruptive if the user does
manage to enter a nonexistant working directory!)

A more complete fix would avoid ever looking at the working directory
when printing diagnostics, instead requiring the caller to pass in a
richer definition of the "location of source code" than the mere file
name as a string. However getting something sensible working there is
(a) breaking and (b) unclear on may details. So just patching this up
quickly seems good for now.
  • Loading branch information
c42f committed Oct 29, 2023
1 parent 1b048aa commit 4d990b6
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
32 changes: 24 additions & 8 deletions src/diagnostics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,26 @@ Base.range(d::Diagnostic) = first_byte(d):last_byte(d)

# Make relative path into a file URL
function _file_url(filename)
@static if Sys.iswindows()
# TODO: Test this with windows terminal
path = replace(abspath(filename), '\\'=>'/')
else
path = abspath(filename)
try
@static if Sys.iswindows()
# TODO: Test this with windows terminal
path = replace(abspath(filename), '\\'=>'/')
else
path = abspath(filename)
end
return "file://$(path)"
catch exc
# abspath may fail if working directory doesn't exist
# TODO: It seems rather non-ideal to have the behavior here depend on
# the state of the local filesystem. And yet links in diagnostics seem
# useful.
#
# Ideally it'd be up to the caller to provide some notion of the
# "absolute location" of the source code resource when SourceFile is
# constructed. This is often not related to the local filesystem - it
# could be in memory, a fragment embedded in another file, etc etc.
return nothing
end
"file://$(path)"
end

function show_diagnostic(io::IO, diagnostic::Diagnostic, source::SourceFile)
Expand All @@ -64,8 +77,11 @@ function show_diagnostic(io::IO, diagnostic::Diagnostic, source::SourceFile)
file_href = nothing
if !isnothing(filename)
locstr = "$filename:$linecol"
if !startswith(filename, "REPL[")
file_href = _file_url(filename)*"#$linecol"
if !startswith(filename, "REPL[") && get(io, :color, false)
url = _file_url(filename)
if !isnothing(url)
file_href = url*"#$linecol"
end
end
else
locstr = "line $linecol"
Expand Down
21 changes: 21 additions & 0 deletions test/diagnostics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,25 @@ end
# Error @ line 1:8
a -- b -- c
# └┘ ── invalid operator"""

stream = JuliaSyntax.ParseStream("a -- b")
JuliaSyntax.parse!(stream)
fname = "test.jl"
sf = SourceFile(stream, filename=fname)
url = JuliaSyntax._file_url(fname)
@test sprint(JuliaSyntax.show_diagnostics, stream.diagnostics, sf,
context=:color=>true) == """
\e[90m# Error @ \e[0;0m\e]8;;$url#1:3\e\\\e[90mtest.jl:1:3\e[0;0m\e]8;;\e\\
a \e[48;2;120;70;70m--\e[0;0m b
\e[90m# └┘ ── \e[0;0m\e[91minvalid operator\e[0;0m"""

if Sys.isunix()
mktempdir() do tempdirname
cd(tempdirname) do
rm(tempdirname)
# Test _file_url doesn't fail with nonexistant directories
@test isnothing(JuliaSyntax._file_url(joinpath("__nonexistant__", "test.jl")))
end
end
end
end

0 comments on commit 4d990b6

Please sign in to comment.