diff --git a/src/diagnostics.jl b/src/diagnostics.jl index c84fa0ac..9a5ea961 100644 --- a/src/diagnostics.jl +++ b/src/diagnostics.jl @@ -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) @@ -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" diff --git a/test/diagnostics.jl b/test/diagnostics.jl index 423bb882..d9aee625 100644 --- a/test/diagnostics.jl +++ b/test/diagnostics.jl @@ -214,4 +214,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