Skip to content

Neovim: Commands

Every command the plugin defines.

Starting a session

:DebugStart [profile]

Starts a debug session for the current project. With no argument the default profile from .bugsaur/config.toml is used; with an argument, that profile. Names complete with Tab, read from the project config.

If there is no config, the debugger detects the language, generates one, reports that it did, and continues.

Saved breakpoints from .bugsaur/breakpoints.json are used. With none set, the current line becomes the initial breakpoint.

:DebugTest

Debugs the test under the cursor. The cursor must be inside a test function — in Rust the #[test] line counts too. On a test group line, such as mod tests or a PHP class containing recognised test methods, the whole group runs. Ordinary PHP classes are rejected.

Requires a saved buffer: the backend reads the file from disk. Unlike :DebugStart, saved breakpoints are not picked up — only breakpoints from this request are used.

Controlling execution

Command What it does
:DebugContinue run until the next breakpoint
:DebugStepOver run the current line, stop on the next
:DebugStepInto enter the call on the current line
:DebugStepOut run until the current function returns
:DebugPause interrupt a running program
:DebugStop terminate the session

These map onto the same operations as the window's own keys; see Using Bugsaur → Stepping.

Breakpoints

:ToggleBreakpoint [condition]

Adds or removes a breakpoint on the current line. With an argument the breakpoint becomes conditional:

:ToggleBreakpoint count > 10
:ToggleBreakpoint user.id == 42

The expression is in the debuggee's language. :ToggleBreakpoint is the one entry point that checks whether the line can actually hold a breakpoint, because it works from the cursor and the buffer is loaded.

The window

:DebugFocus

Brings the debugger window forward. Useful when the stop was triggered from outside the editor — a browser request to a PHP application, for instance — and the window is behind something else.

With gui_focus_on_stop = true in setup(), this happens automatically on every stop.

The Lua API for extensions

Beyond the commands, the module exposes functions for scripting:

local bugsaur = require("bugsaur")

bugsaur.list(opts)              -- entries; opts.root or opts.path narrow the selection
bugsaur.set(path, line, cond)   -- set or replace a condition; true if the set changed
bugsaur.remove(path, line)      -- remove one; true if there was one to remove
bugsaur.remove_file(path)       -- remove all in a file; returns how many
bugsaur.clear(opts)             -- remove everything, or everything under opts.root

An entry from list(), sorted by path then line:

{
  path = "/abs/src/main.rs",
  relative = "src/main.rs",   -- nil if the file is outside any root
  root = "/abs",              -- nil likewise
  line = 42,
  condition = nil,
  state = "verified",         -- "verified" | "rejected" | "pending"
}

list() with no arguments returns everything currently in memory. opts.root first reads that root's set from disk, so the list can show a project whose files you have not opened in this Neovim.

Any change to the set — through these functions, through :ToggleBreakpoint, or by reading a file from disk — fires an autocommand:

vim.api.nvim_create_autocmd("User", {
  pattern = "BugsaurBreakpointsChanged",
  callback = function(event)
    -- event.data.paths — the affected files
  end,
})

Two caveats

bugsaur.set does not check whether the line holds an executable statement — the buffer may not even be loaded. Only :ToggleBreakpoint checks, because it works from the cursor.

bugsaur.state is the plugin's internal state, not a contract. Do not rely on it.