diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3ad295b..82b8781 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -35,8 +35,6 @@ jobs: arch: ${{ matrix.arch }} - uses: julia-actions/cache@v3 - uses: julia-actions/julia-buildpkg@v1 - - name: Use TerminalRegressionTests Julia 1.12 support branch - run: julia --project=. --color=yes -e 'using Pkg; Pkg.add(Pkg.PackageSpec(url="https://github.com/JuliaDebug/TerminalRegressionTests.jl", rev="kc/terminal-1.12-support"))' - uses: julia-actions/julia-runtest@v1 - uses: julia-actions/julia-processcoverage@v1 - uses: codecov/codecov-action@v7 diff --git a/Project.toml b/Project.toml index 1875225..77c8c86 100644 --- a/Project.toml +++ b/Project.toml @@ -12,12 +12,9 @@ PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" tree_sitter_julia_jll = "52be201e-a5e9-5cfe-8bf2-2dc4b062171c" -[sources] -TerminalRegressionTests = {url = "https://github.com/JuliaDebug/TerminalRegressionTests.jl", rev = "kc/terminal-1.12-support"} - [compat] CodeTracking = "2, 3" -Highlights = "0.6" +Highlights = "0.6.2" JuliaInterpreter = "0.10, 0.11" PrecompileTools = "1" TerminalRegressionTests = "0.3" diff --git a/src/precompile.jl b/src/precompile.jl index 08c62ce..2da95a6 100644 --- a/src/precompile.jl +++ b/src/precompile.jl @@ -42,10 +42,7 @@ end # active REPL), which the scripted session above does not exercise precompile(RunDebugger, (Frame,)) - # Clean up global state the workload mutated. The highlight cache in - # particular holds tree-sitter pointers that must not be serialized into - # the package image. - _highlight_cache[] = nothing + # Clean up global state the workload mutated. empty!(WATCH_LIST) JuliaInterpreter.remove() _ALT_SCREEN[] = false diff --git a/src/printing.jl b/src/printing.jl index c22abcf..aa75560 100644 --- a/src/printing.jl +++ b/src/printing.jl @@ -402,29 +402,10 @@ function compute_source_offsets(code::AbstractString, current_offsetline::Intege startoffset, stopoffset end -# `Highlights.highlight` creates a tree-sitter parser and compiles the -# highlight query on every call (~30 ms) — far too slow for a status print -# that highlights every variable line. Cache them for the session. -mutable struct HighlightCache - parser::Any - query::Any - theme::Any - theme_name::String -end -const _highlight_cache = Ref{Union{HighlightCache, Nothing}}(nothing) - -function highlight_cache() - cache = _highlight_cache[] - if cache === nothing || cache.theme_name != _current_theme[] - lang = Highlights.resolve_language(:julia) - parser = Highlights.TreeSitter.Parser(lang) - query = Highlights.TreeSitter.Query(lang, ["highlights"]) - theme = Highlights.load_theme(_current_theme[]) - cache = HighlightCache(parser, query, theme, _current_theme[]) - _highlight_cache[] = cache - end - return cache -end +# Pass the grammar module rather than the `:julia` symbol: symbol lookup goes +# through `Base.identify_package`, which only sees the active project's direct +# deps and so fails when Debugger is an indirect dependency. +import tree_sitter_julia_jll function highlight_code(code; context=nothing) if context !== nothing && !get(context, :color, false) @@ -432,20 +413,12 @@ function highlight_code(code; context=nothing) end _syntax_highlighting[] || return code try - cache = highlight_cache() - tokens = Highlights.highlight_tokens(cache.parser, cache.query, code) return sprint(context=context) do io - Highlights.format(io, MIME("text/ansi"), tokens, code, cache.theme, :julia) - end - catch - # The fast path uses Highlights internals; fall back to the public API - # if they change - try - return sprint(highlight, MIME("text/ansi"), code, :julia, _current_theme[]; context=context) - catch e - printstyled(stderr, "failed to highlight code, $e\n"; color=Base.warn_color()) - return code + Highlights.highlight(io, MIME("text/ansi"), code, tree_sitter_julia_jll, _current_theme[]) end + catch e + printstyled(stderr, "failed to highlight code, $e\n"; color=Base.warn_color()) + return code end end diff --git a/test/misc.jl b/test/misc.jl index c19212f..2c758c2 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -478,3 +478,26 @@ end # the session survived: `fr` after the error still prints the locals @test occursin(r"y.*= .*2", out) end + +# Highlighting must work when the grammar jll is not a direct dep of the active +# project (i.e. Debugger installed as an indirect dependency). An empty active +# project reproduces that; `:julia` symbol lookup would fail there. +@testset "highlighting when grammar jll is not a direct project dep" begin + prev_highlight = Debugger.config().highlight + Debugger.set_highlight(true) + old_project = Base.active_project() + try + mktempdir() do tmp + touch(joinpath(tmp, "Project.toml")) + Base.set_active_project(joinpath(tmp, "Project.toml")) + io = IOContext(IOBuffer(), :color => true) + out = Debugger.highlight_code("x = 1"; context=io) + # ANSI escapes mean it highlighted; the bug silently fell back to + # the un-highlighted source. + @test occursin("\e[", out) + end + finally + Base.set_active_project(old_project) + Debugger.set_highlight(prev_highlight) + end +end