Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,22 @@ jobs:
test:
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
runs-on: ${{ matrix.os }}
env:
DEBUGGER_RUN_UI_TESTS: ${{ matrix.version == '1' }}
strategy:
fail-fast: false
matrix:
version:
- '1.10'
- '1.11'
- '1'
- 'nightly'
os:
- ubuntu-latest
- macOS-latest
- windows-latest
arch:
- x64
- default
steps:
- uses: actions/checkout@v6
- uses: julia-actions/setup-julia@v3
Expand All @@ -31,6 +35,8 @@ jobs:
arch: ${{ matrix.arch }}
- uses: julia-actions/cache@v2
- 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@v5
Expand Down
10 changes: 7 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "Debugger"
uuid = "31a5f54b-26ea-5ae9-a837-f05ce5417438"
version = "0.7.16"
version = "0.8.0"

[deps]
CodeTracking = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
Expand All @@ -11,11 +11,15 @@ Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
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"
JuliaInterpreter = "0.10"
julia = "1.6"
JuliaInterpreter = "0.10, 0.11"
TerminalRegressionTests = "0.3"
julia = "1.10"
tree_sitter_julia_jll = "0.25.0"

[extras]
Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,21 +76,21 @@ Evaluation:
- `w`
- `w add expr`: add an expression to the watch list
- `w`: show all watch expressions evaluated in the current function's context
- `w rm [i::Int]`: remove all or the `i`:th watch expression
- `w rm [i::Int]`: remove all or the `i`-th watch expression

Breakpoints:
- `bp`
- `bp add`
- `bp add "file.jl":line [cond]`: add a breakpoint att file `file.jl` on line `line` with condition `cond`
- `bp add func [:line] [cond]`: add a breakpoint to function `func` at line `line` (defaulting to first line) with condition `cond`
- `bp add func(::Float64, Int)[:line] [cond]`: add a breakpoint to methods matching the signature at line `line` (defaulting to first line) with condition `cond`
- `bp add "file.jl":line [cond]`: add a breakpoint at file `file.jl` on line `line` with condition `cond`
- `bp add func [:line] [cond]`: add a breakpoint to function `func` at line `line` (defaulting to first line) with condition `cond`
- `bp add func(::Float64, Int)[:line] [cond]`: add a breakpoint to methods matching the signature at line `line` (defaulting to first line) with condition `cond`
- `bp add func(x, y)[:line] [cond]`: add a breakpoint to the method matching the types of the local variable `x`, `y` etc with condition `cond`
- `bp add line [cond]` add a breakpoint to `line` of the file of the current function with condition `cond`
- `bp add line [cond]`: add a breakpoint to `line` of the file of the current function with condition `cond`
- `bp` show all breakpoints
- `bp rm [i::Int]`: remove all or the `i`:th breakpoint
- `bp toggle [i::Int]`: toggle all or the `i`:th breakpoint
- `bp disable [i::Int]`: disable all or the `i`:th breakpoint
- `bp enable [i::Int]`: enable all or the `i`:th breakpoint
- `bp rm [i::Int]`: remove all or the `i`-th breakpoint
- `bp toggle [i::Int]`: toggle all or the `i`-th breakpoint
- `bp disable [i::Int]`: disable all or the `i`-th breakpoint
- `bp enable [i::Int]`: enable all or the `i`-th breakpoint
- `bp on/off`
- `bp on/off error` - turn on or off break on error
- `bp on/off throw` - turn on or off break on throw
Expand Down Expand Up @@ -239,7 +239,7 @@ union!(JuliaInterpreter.compiled_modules, SomePackage)

The source code preview is syntax highlighted and this highlighting has some options.
The theme can be set by calling `Debugger.set_theme(theme)` where `theme` is a [Highlights.jl theme](https://highlights.juliadocs.org/dev/themes/).
It can be completely turned off by calling `Debugger.set_highlight(false)`
It can be completely turned off by calling `Debugger.set_highlight(false)`.

[travis-img]: https://travis-ci.org/JuliaDebug/Debugger.jl.svg?branch=master
[travis-url]: https://travis-ci.org/JuliaDebug/Debugger.jl
Expand Down
6 changes: 6 additions & 0 deletions src/Debugger.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ Base.@kwdef mutable struct DebuggerState
overall_result = nothing
end

function output_stream(state::DebuggerState)
io = Base.pipe_writer(state.terminal)
have_color = state.repl isa REPL.LineEditREPL ? state.repl.hascolor : get(io, :color, false)
return IOContext(io, :color => have_color)
end

function toggle_mode(state)
state.interp = (state.interp === RecursiveInterpreter() ? (state.interp = NonRecursiveInterpreter()) : (state.interp = RecursiveInterpreter()))
end
Expand Down
28 changes: 14 additions & 14 deletions src/commands.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function execute_command(state::DebuggerState, v::Union{Val{:c},Val{:nc},Val{:n}
if pc isa BreakpointRef
if pc.stmtidx != 0 # This is the dummy breakpoint to stop just after entering a call
if state.terminal !== nothing # fix this, it happens when a test hits this and hasn't set a terminal
show_breakpoint(Base.pipe_writer(state.terminal), pc, state)
show_breakpoint(output_stream(state), pc, state)
end
end
if pc.err !== nothing
Expand All @@ -68,7 +68,7 @@ function execute_command(state::DebuggerState, v::Union{Val{:c},Val{:nc},Val{:n}
end

function execute_command(state::DebuggerState, ::Val{:bt}, cmd)
io = Base.pipe_writer(state.terminal)
io = output_stream(state)
iob = IOContext(IOBuffer(), io)
num = 0
frame = state.frame
Expand Down Expand Up @@ -117,7 +117,7 @@ function execute_command(state::DebuggerState, ::Union{Val{:f}, Val{:fr}}, cmd)
old_level = state.level
try
state.level = new_level
print_frame(Base.pipe_writer(state.terminal), new_level, active_frame(state))
print_frame(output_stream(state), new_level, active_frame(state))
finally
state.level = old_level
end
Expand Down Expand Up @@ -164,7 +164,7 @@ function execute_command(state::DebuggerState, ::Val{:w}, cmd::AbstractString)
end
end
if success_and_show
io = Base.pipe_writer(state.terminal)
io = output_stream(state)
outbuf = IOContext(IOBuffer(), io)
show_watch_list(outbuf, state)
print(io, String(take!(outbuf.io)))
Expand All @@ -179,7 +179,7 @@ function execute_command(state::DebuggerState, v::Union{Val{:bp}}, cmd::Abstract
cmds = split(cmd, r" +")
function repl_show_breakpoints()
if state.terminal !== nothing
io = Base.pipe_writer(state.terminal)
io = output_stream(state)
outbuf = IOContext(IOBuffer(), io)
show_breakpoints(outbuf, state)
print(io, String(take!(outbuf.io)))
Expand Down Expand Up @@ -275,21 +275,21 @@ function execute_command(state::DebuggerState, ::Union{Val{:help}, Val{:?}}, cmd
- `w`\\
- `w add expr`: add an expression to the watch list\\
- `w`: show all watch expressions evaluated in the current function's context\\
- `w rm [i::Int]`: remove all or the `i`:th watch expression\\
- `w rm [i::Int]`: remove all or the `i`-th watch expression\\


Breakpoints:\\
- `bp add`\\
- `bp add "file.jl":line [cond]`: add a breakpoint att file `file.jl` on line `line` with condition `cond`\\
- `bp add func [:line] [cond]`: add a breakpoint to function `func` at line `line` (defaulting to first line) with condition `cond`\\
- `bp add func(::Float64, Int)[:line] [cond]`: add a breakpoint to methods matching the signature at line `line` (defaulting to first line) with condition `cond`\\
- `bp add "file.jl":line [cond]`: add a breakpoint at file `file.jl` on line `line` with condition `cond`\\
- `bp add func [:line] [cond]`: add a breakpoint to function `func` at line `line` (defaulting to first line) with condition `cond`\\
- `bp add func(::Float64, Int)[:line] [cond]`: add a breakpoint to methods matching the signature at line `line` (defaulting to first line) with condition `cond`\\
- `bp add func(x, y)[:line] [cond]`: add a breakpoint to the method matching the types of the local variable `x`, `y` etc with condition `cond`\\
- `bp add line [cond]` add a breakpoint to `line` of the file of the current function with condition `cond`\\
- `bp add line [cond]`: add a breakpoint to `line` of the file of the current function with condition `cond`\\
- `bp` show all breakpoints\\
- `bp rm [i::Int]`: remove all or the `i`:th breakpoint\\
- `bp toggle [i::Int]`: toggle all or the `i`:th breakpoint\\
- `bp disable [i::Int]`: disable all or the `i`:th breakpoint\\
- `bp enable [i::Int]`: enable all or the `i`:th breakpoint\\
- `bp rm [i::Int]`: remove all or the `i`-th breakpoint\\
- `bp toggle [i::Int]`: toggle all or the `i`-th breakpoint\\
- `bp disable [i::Int]`: disable all or the `i`-th breakpoint\\
- `bp enable [i::Int]`: enable all or the `i`-th breakpoint\\
- `bp on/off`\\
- `bp on/off error` - turn on or off break on error\\
- `bp on/off throw` - turn on or off break on throw\\
Expand Down
61 changes: 43 additions & 18 deletions src/printing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,7 @@ function pattern_match_kw_call(expr)
return :($f($(args...); $(kws...)))
end

@static if VERSION < v"1.3.0-DEV.179"
const append_any = Base.append_any
else
append_any(@nospecialize x...) = append!([], Core.svec((x...)...))
end
append_any(@nospecialize x...) = append!([], Core.svec((x...)...))

function pattern_match_apply_call(expr, frame)
if !(isexpr(expr, :call) && expr.args[1] == Core._apply)
Expand All @@ -79,23 +75,58 @@ function pattern_match_apply_call(expr, frame)
return new_expr
end

# Replace functions with their symbol so that calls print like `f(x)` instead of `(f)(x)`.
# Replace functions with their symbol so that calls print like `f(x)` instead of `(f)(x)`,
# and function arguments do not gain a version-dependent `Main.` qualification.
function replace_function_with_symbol(expr)
if isexpr(expr, :call)
f = expr.args[1]
if f isa Function
s = Symbol(f)
for i in eachindex(expr.args)
arg = expr.args[i]
arg isa Function || continue
s = Symbol(arg)
if Base.isidentifier(s)
expr.args[1] = s
return expr
expr.args[i] = s
end
end
end
return expr
end

function print_next_expr(io::IO, frame::Frame)
function expression_for_display(frame::Frame)
expr = pc_expr(frame)
if expr isa GlobalRef && frame.pc < nstatements(frame.framecode)
# Julia 1.12 may pause on a global lookup followed by separate argument
# loads and then a call. Preview that call so the status still shows its
# arguments rather than just `Main.:+`.
for next_pc in (frame.pc + 1):nstatements(frame.framecode)
stmt = pc_expr(frame, next_pc)
call = isexpr(stmt, :(=)) ? stmt.args[2] : stmt
if isexpr(call, :call)
f = call.args[1]
if f isa JuliaInterpreter.SSAValue && f.id == frame.pc
call = copy(call)
for i in eachindex(call.args)
arg = call.args[i]
if arg isa JuliaInterpreter.SSAValue && frame.pc <= arg.id < next_pc
source = pc_expr(frame, arg.id)
if source isa Union{GlobalRef, JuliaInterpreter.SlotNumber, QuoteNode}
call.args[i] = source
else
return expr
end
end
end
return call
end
end

stmt isa Union{GlobalRef, JuliaInterpreter.SlotNumber, QuoteNode} || break
end
end
return expr
end

function print_next_expr(io::IO, frame::Frame)
expr = expression_for_display(frame)
@assert expr !== nothing
print(io, "About to run: ")
isa(expr, Expr) && (expr = copy(expr))
Expand Down Expand Up @@ -202,12 +233,6 @@ function compute_source_offsets(code::AbstractString, current_offsetline::Intege
startoffset, stopoffset
end

# TODO: Remove on next breaking change. These exist for back compat
const HIGHLIGHT_OFF = false
const HIGHLIGHT_SYSTEM_COLORS = true
const HIGHLIGHT_256_COLORS = true
const HIGHLIGHT_24_BIT = true

const _syntax_highlighting = Ref(true)
const _current_theme = Ref("Monokai Dark")
set_theme(theme::String) = _current_theme[] = theme
Expand Down
Loading
Loading