Skip to content

Repository files navigation

Bugsaur

A standalone graphical DAP debugger with Neovim integration.

CI Rust 1.92 DAP 1.71 macOS | Linux

📖 Documentation

About · Screenshots · Quickstart · Install · Build

English · Русский


About

Bugsaur is a graphical debugger that runs on its own. It is language-agnostic: it talks to debug adapters over the Debug Adapter Protocol, and Neovim acts as a source frontend rather than as the debugger.

The architectural invariant: Neovim does not own the debug session. Bugsaur is the only DAP client and the authoritative owner of state. It starts and works without Neovim, and Neovim is a replaceable frontend for showing source code.

Neovim — source frontend Bugsaur core Bugsaur GUI
Code editing DAP session Variables
Source navigation Execution control Threads
Breakpoint UX Runtime state Call stack
Watches, Evaluate

Breakpoints survive an editor restart: they live in <root>/.bugsaur/breakpoints.json and are visible both to the terminal debugger and to Neovim.

Languages today: PHP, Go, Rust, Python. A TOML catalog extends or overrides the built-in adapter catalog, so anything with a DAP adapter can be added.

PHP is the one language Bugsaur does not delegate. It ships its own native DBGp adapter, php-dbgp-adapter, built from this workspace. It replaces the usual DAP↔DBGp bridge and depends on no Node.js, npm, VS Code or vscode-php-debug — at runtime only bugsaur, php-dbgp-adapter and Xdebug are involved. See ADR-008.

Screenshots

Bugsaur is available in both light and dark themes. The two variants are shown side by side below.

Light theme Dark theme
Bugsaur graphical debugger in the light theme Bugsaur graphical debugger in the dark theme

Quickstart

# 1. Build the debugger
make build

# 2. Make sure the adapter for your language is on PATH
command -v codelldb        # Rust, C, C++
command -v dlv             # Go
python3 -m debugpy --version   # Python (usually in the project venv)

# 3. In your project: describe what to debug
target/debug/bugsaur init  # writes <project>/.bugsaur/config.toml

# 4. Debug it
target/debug/bugsaur gui --project /path/to/project --break src/main.rs:15
target/debug/bugsaur gui --project /path/to/project --test-at tests/test_app.py:12

bugsaur init detects the language by Cargo.toml, go.mod, composer.json or pyproject.toml and writes a config you then edit by hand:

version = 1
default = "app"

[profiles.app]
adapter = "codelldb"
program = "target/debug/app"

The config is read by the debugger, not by the editor, so bugsaur from a terminal and :DebugStart from Neovim see exactly the same setup. The project root is the nearest directory up the tree that contains .bugsaur/. Pick a profile with :DebugStart <name>, otherwise default is used.

Relative paths resolve from the project root, and so does the debuggee's working directory unless a profile sets cwd. Environment comes from env_file and env; arguments from args.

Full format, resolution rules and worked examples for every language: docs/CONFIG.md. See also docs/NEOVIM.md §3 and docs/SPEC.md §38.1.

How to Install

Prerequisites

Rust only for a source build: the toolchain pinned in rust-toolchain.toml (1.92), installed with rustup
Platform macOS or Linux
Adapter at least one: codelldb (Rust, C, C++), dlv (Go), debugpy (Python — a pip install debugpy away), or the bundled php-dbgp-adapter (PHP)
Neovim optional — only for the source frontend

Adapters are resolved through PATH, so they must be visible to the debugger. If yours came from Mason:

export PATH="$HOME/.local/share/nvim/mason/bin:$PATH"

Debugger

Download the archive for your platform from GitHub Releases, extract it, and put bugsaur and the bundled php-dbgp-adapter on your PATH. Archives are published for Linux x86-64, macOS Intel and macOS Apple Silicon, and also contain the optional Neovim frontend under lua/.

To build from source instead:

git clone https://github.com/real420og/bugsaur.git
cd bugsaur
make build

The binary lands in target/debug/bugsaur. Copy or symlink it into a directory on your PATH to call it as bugsaur.

Python and debugpy

The adapter is a Python module, so it is installed into the interpreter that runs your code:

python3 -m pip install debugpy      # or: .venv/bin/pip install debugpy

bugsaur init looks for .venv/bin/python and venv/bin/python in the project root. When it finds one, the generated profile points both the adapter and the debuggee at that interpreter:

[profiles.main]
adapter = "debugpy"
adapter_command = "${root}/.venv/bin/python"
program = "main.py"
cwd = "."

[profiles.main.launch_arguments]
python = "${root}/.venv/bin/python"

Without a virtualenv both fall back to python3 from PATH, which then needs debugpy installed. Entry points are found by name — main.py, app.py, manage.py, __main__.py in the root and src/<pkg>/__main__.py — one profile each; anything else you write by hand.

PHP and Xdebug

PHP needs no external adapter: release archives include php-dbgp-adapter, and the same make build produces it next to bugsaur. Put their directory on PATH so the catalog can find it:

export PATH="$PWD:$PATH"                # extracted release archive
export PATH="$PWD/target/debug:$PATH"   # source build

Point a profile at it and describe the Xdebug side:

[profiles.docker]
adapter = "php"
program = "."

[profiles.docker.launch_arguments]
port = 9003
sessionMode = "server"                    # "cli" for a one-shot script
pathMappings = { "/app" = "${root}" }     # path in the container -> host path

In the PHP environment itself:

xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003

server is for an already running PHP-FPM, built-in server or web container; cli is for a script that starts and exits. Session modes, running two PHP projects side by side and the Docker fixture: docs/NEOVIM.md §7.

Neovim plugin

The Lua source frontend lives in lua/bugsaur/init.lua and connects to the backend over a Unix socket. With lazy.nvim:

{
  dir = "/absolute/path/to/bugsaur",
  name = "bugsaur",
  config = function()
    require("bugsaur").setup({
      binary = "/absolute/path/to/bugsaur/target/debug/bugsaur",
      gui = true,
    })
  end,
}

setup() only carries editor and window options — adapters, programs and launch arguments live in the project config. Then add a breakpoint with :ToggleBreakpoint and run :DebugStart. Full command and keymap reference: docs/NEOVIM.md.

How to Build

Build through make, not through a bare cargo: the Makefile resolves the toolchain directory from rust-toolchain.toml and puts it first on PATH, so a stray older cargo cannot change the result.

Command What it does
make build build the workspace and bugsaur
make check type-check the workspace
make test run the offline test suite
make test-one run one target: PKG=<crate> [TEST=<file>] [NAME=<filter>]
make fmt check formatting
make clippy clippy with -D warnings
make gui build the Rust fixture and launch the GUI
make help list every target

Live adapter tests, acceptance scripts and the development process: docs/DEVELOPMENT.md.

Documentation

The full documentation lives at real420og.github.io/bugsaur — also available in Russian.

Getting Started install it, run it, hit your first breakpoint
Debugger UI every panel of the window, explained
Languages Rust, C/C++, Go, Python, PHP
Neovim commands, keymaps, breakpoint sync
Configuration profiles, environment, path mappings, UI
Guides cargo test, pytest, PHP in Docker, and more
Troubleshooting when it does not work
Reference CLI, config keys, keyboard shortcuts

Working on Bugsaur itself: Development · docs/SPEC.md · docs/ROADMAP.md · docs/MIGRATION.md · docs/adr/

About

Bugsaur is a standalone graphical DAP debugger with Neovim integration.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages