Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
1b14a83
POC php process running
dantleech Nov 8, 2025
f3826cb
Show PHP process output
dantleech Nov 8, 2025
bd19344
Drain
dantleech Nov 8, 2025
bc431a9
Switch channels
dantleech Nov 8, 2025
90b90c1
Failing test for lines
dantleech Nov 9, 2025
c1d6963
Lines
dantleech Nov 9, 2025
6ae6881
Fix line ending
dantleech Nov 9, 2025
4f391ca
Show stdout and stderr
dantleech Nov 9, 2025
74a2468
Extract crappy code to own module
dantleech Nov 9, 2025
ee64240
OK
dantleech Nov 9, 2025
6ac8b2c
Clippy
dantleech Nov 9, 2025
94f50da
Refactor
dantleech Nov 9, 2025
b9ed6c8
Support restarting
dantleech Nov 9, 2025
2a2ae99
Show error when process terminates abnormally
dantleech Nov 9, 2025
042d591
Clippy
dantleech Nov 9, 2025
8e9a455
Fix channel names
dantleech Nov 12, 2025
517eaf8
Refactor event loop to use tokio
dantleech Nov 15, 2025
71ce20c
Do NOT inherit stdin in sub-process
dantleech Nov 15, 2025
50351c8
Add event stream deps
dantleech Nov 15, 2025
75c197f
Scroll lines
dantleech Nov 15, 2025
d134093
"Safely" render ANSI output
dantleech Nov 15, 2025
5eb45ee
Kill io_task
dantleech Nov 16, 2025
d4ce787
Fix clippys
dantleech Nov 16, 2025
c9586f2
Do not use Vec
dantleech Nov 22, 2025
b25f271
Snapshot rewind
dantleech Nov 22, 2025
570a5ef
Update
dantleech Nov 22, 2025
f8c866d
Show process out on listen screen
dantleech Nov 22, 2025
e9e9179
Clipyp
dantleech Nov 22, 2025
405ce88
Clippy
dantleech Nov 22, 2025
6232cf2
Handle error
dantleech Nov 23, 2025
806aea5
Refactor error handling in process manager
dantleech Nov 23, 2025
b7b711a
Refactorings and bug fixes
dantleech Nov 23, 2025
8bebd5a
Update test
dantleech Nov 23, 2025
4ff576a
FIx clippy
dantleech Nov 23, 2025
33bb3e1
Blinken lights channels
dantleech Jan 23, 2026
f823769
Allow filtering the context with a global shortcut
dantleech Jan 23, 2026
017f56e
Encapsulate notfication handling
dantleech Jan 24, 2026
62ad115
show all notifications
dantleech Jan 24, 2026
f41697e
Fix order of inline variables
dantleech Jan 24, 2026
9084213
Do not issue Xdebug commands when xdebug is locked
dantleech Jan 24, 2026
3965bad
Improve notifications
dantleech Jan 24, 2026
8a718ed
Avoid out-of-bounds error when ntifications scroll of end of screen
dantleech Jan 24, 2026
ab0575b
Do not allow process to be restarted when waiting for xdebug
dantleech Jan 24, 2026
bbe256a
Avoid deadlock
dantleech Jan 24, 2026
9306e24
Avoid deadlock with running execution continuation
dantleech Jan 24, 2026
63ee5dc
Bind keys in listen mode
dantleech Jan 25, 2026
7a4a7e0
Clippy fixes
dantleech Jan 25, 2026
5059967
Update README
dantleech Jan 25, 2026
1453559
Fix div
dantleech Jan 25, 2026
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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@ CHANGELOG
main
----

### Features

- Process control - launch, restart and monitor a process.

### Improvements

- Show window "titles" at bottom of window
- Ability to disconnect from the server (via. "d")
- Channel pane replaces eval pane.
- Show multiple notifications.

### Bug fixes

- Fix order of inline variables.
- Fixed deadlocks.

0.2.0
-----
Expand Down
169 changes: 169 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ edition = "2021"
[build-dependencies]
cc="*"
[dependencies]
ansi-to-tui = "7.0.0"
anyhow = "1.0.97"
base64 = "0.22.1"
better-panic = "0.3.0"
clap = { version = "4.5.35", features = ["derive"] }
crossterm = "0.28.1"
crossterm = { version = "0.28.1", features = ["event-stream"] }
futures = "0.3.31"
log = "0.4.27"
ordered_hash_map = "0.5.0"
pretty_assertions = "1.4.1"
ratatui = "0.29.0"
serde = { version = "1.0.219", features = ["derive"] }
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Interactive [Xdebug](https://xdebug.org) step-debugging client for your terminal
- **Jump the stack**: jump up and down the stack.
- **Vim-like motions**: Typing `100n` will repeat "step into" 100 times.
- **Inline values**: Show variable values inline with the source code.
- **Process control**: Launch, monitor and restart the process being debugged.

## Installation

Expand All @@ -22,11 +23,26 @@ Interactive [Xdebug](https://xdebug.org) step-debugging client for your terminal
- `--log`: Debug log to file.
- `--listen`: Listen on an alternative address (defaults to `0.0.0.0:9003`).

## Usage

To listen for an incoming Xdebug connection on the default port:

```bash
$ debug-tui
```

Launch and manage the process to be debugged:

```bash
$ debug-tui -- php path/to/script.php
```

## Key bindings

Prefix with number to repeat:

- `r` run
- `R` restart process if one was provided
- `n` next / step into
- `N` step over
- `p` previous (switches to history mode if in current mode)
Expand Down
29 changes: 29 additions & 0 deletions debug.loh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[00:00:00.000] (7ffa3507f440) INFO Handling event Startup
[00:00:00.000] (7ffa2edf66c0) TRACE registering event source with poller: token=Token(140711450119680), interests=READABLE | WRITABLE
[00:00:00.648] (7ffa34dff6c0) TRACE registering event source with poller: token=Token(140712523862528), interests=READABLE | WRITABLE
[00:00:00.648] (7ffa3507f440) INFO Handling event ClientConnected(PollEvented { io: Some(TcpStream { addr: 127.0.0.1:9003, peer: 127.0.0.1:47680, fd: 14 }) })
[00:00:00.648] (7ffa3507f440) DEBUG [dbgp] << <?xml version="1.0" encoding="iso-8859-1"?>
<init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file:///home/daniel/www/dantleech/debug-tui/php/test.php" language="PHP" xdebug:language_version="8.4.3" protocol_version="1.0" appid="2532590" xdebug:ctrl_socket="xdebug-ctrl.2532590"><engine version="3.4.1"><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2025 by Derick Rethans]]></copyright></init>
[00:00:00.648] (7ffa3507f440) INFO setting feature max_depth to "4"
[00:00:00.648] (7ffa3507f440) DEBUG [dbgp] >> feature_set -i 0 -n max_depth -v 4
[00:00:00.648] (7ffa3507f440) DEBUG [dbgp] << <?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="0" feature="max_depth" success="1"></response>
[00:00:00.648] (7ffa3507f440) INFO setting feature extended_properties to "1"
[00:00:00.648] (7ffa3507f440) DEBUG [dbgp] >> feature_set -i 1 -n extended_properties -v 1
[00:00:00.648] (7ffa3507f440) DEBUG [dbgp] << <?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="1" feature="extended_properties" success="1"></response>
[00:00:00.649] (7ffa3507f440) DEBUG [dbgp] >> source -i 2 -f file:///home/daniel/www/dantleech/debug-tui/php/test.php
[00:00:00.652] (7ffa3507f440) DEBUG [dbgp] << <?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="source" transaction_id="2" encoding="base64"><![CDATA[PD9waHAKCiRhcnJheSA9IFsKICAgICdpbnQnID0+IDEyMywKICAgICdmbG9hdCcgPT4gMTIzLjQsCiAgICAnc3RyaW5nJyA9PiAic3RyaW5nIiwKICAgICdib29sJyA9PiB0cnVlLAogICAgJ21vcmUnID0+IFsKICAgICAgICAnaW50JyA9PiAxMjMsCiAgICAgICAgJ2Zsb2F0JyA9PiAxMjMuNCwKICAgICAgICAnc3RyaW5nJyA9PiAic3RyaW5nIiwKICAgICAgICAnYm9vbCcgPT4gdHJ1ZSwKICAgIF0sCl07CiRhID0gMjsKJGZvbyA9ICRhOwokZm9vID0gJGFycmF5OwoKJGJhciA9ICRmb287CgoKKG5ldyBGb28odHJ1ZSwgImZvbyIpKS0+bWV0aG9kMygpOwpjYWxsX2Z1bmN0aW9uKCJoZWxsbyIpOwoKCgpmdW5jdGlvbiBjYWxsX2Z1bmN0aW9uKHN0cmluZyAkaGVsbG8pIHsKICAgICR2YXIgPSAxMjM7CiAgICAkb2JqID0gbmV3IEZvbyhmYWxzZSwgJ2dvb2QgZGF5Jyk7CiAgICBhbm90aGVyX2Z1bmN0aW9uKCRoZWxsbyk7CiAgICBhbm90aGVyX2Z1bmN0aW9uKCRoZWxsbyk7CiAgICBhbm90aGVyX2Z1bmN0aW9uKCRoZWxsbyk7Cn0KCmZ1bmN0aW9uIGFub3RoZXJfZnVuY3Rpb24oc3RyaW5nICRnb29kYnllKSB7CiAgICBlY2hvICRnb29kYnllOwoKCiAgICBmb3JlYWNoIChbJ29uZScsICd0d28nLCAndGhyZWUnLCAnZm91ciddIGFzICRudW1iZXIpIHsKICAgICAgICBpZiAoJG51bWJlciA9PT0gJ29uZScpIHsKICAgICAgICAgICAgZWNobyAibnVtYmVyIjsKICAgICAgICB9CiAgICAgICAgZWNobyAkbnVtYmVyOwogICAgfQp9CgpjbGFzcyBGb28gewogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KHB1YmxpYyBib29sICR0cnVlLCBwdWJsaWMgc3RyaW5nICRiYXIpIHt9CiAgICBwdWJsaWMgZnVuY3Rpb24gbWV0aG9kMSgpIHsKICAgIH0KICAgIHB1YmxpYyBmdW5jdGlvbiBtZXRob2QyKCkgewogICAgfQogICAgcHVibGljIGZ1bmN0aW9uIG1ldGhvZDMoKSB7CiAgICB9Cn0KCg==]]></response>
[00:00:06.466] (7ffa3507f440) INFO Handling event Input(KeyEvent { code: Char('r'), modifiers: KeyModifiers(0x0), kind: Press, state: KeyEventState(0x0) })
[00:00:06.478] (7ffa3507f440) INFO Handling event Run
[00:00:06.478] (7ffa34dff6c0) INFO Running iteration 0/1
[00:00:06.478] (7ffa34dff6c0) DEBUG [dbgp] >> run -i 3
[00:00:06.478] (7ffa2eff76c0) DEBUG [dbgp] << <?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="run" transaction_id="3" status="stopping" reason="ok"></response>
[00:00:06.481] (7ffa3507f440) INFO Handling event UpdateStatus(Stopping)
[00:00:06.484] (7ffa3507f440) INFO Handling event Disconnect
[00:00:06.484] (7ffa3507f440) TRACE deregistering event source from poller
[00:00:06.487] (7ffa3507f440) INFO Handling event ChangeSessionViewMode(History)
[00:00:09.778] (7ffa3507f440) INFO Handling event Quit
[00:00:09.779] (7ffa347fc6c0) TRACE deregistering event source from poller
Loading