Skip to content

Neovim: Keymaps

There are two separate sets of bindings, and mixing them up is a common source of confusion:

  • Neovim mappings work in the editor.
  • Window hotkeys work inside the debugger window, which is a separate process with its own keyboard handling.

Neovim mappings

The defaults:

Mapping Command What it does
<leader>dS :DebugStart Start a session with the default profile
<leader>dT :DebugTest Debug the test under the cursor
<leader>dc :DebugContinue Run until the next stop
<leader>di :DebugStepInto Step into the call
<leader>do :DebugStepOver Step over the call
<leader>dO :DebugStepOut Step out, to the return from this function
<leader>dp :DebugPause Interrupt the running program
<leader>dt :DebugStop Terminate the session
<leader>du :DebugFocus Raise the debugger window
<leader>db :ToggleBreakpoint Set or clear a breakpoint on this line

Note the case: <leader>do is step over, <leader>dO is step out; <leader>dt is stop, <leader>dT is debug-test, <leader>dS is start.

A mapping cannot pass a profile: <leader>dS and <leader>dT do what :DebugStart and :DebugTest do with no argument. For another profile, type the command — it completes profile names from .bugsaur/config.toml.

Each mapping carries a description, so which-key and :nmap <leader>d show the action rather than the key spelled out again.

These are ordinary Neovim mappings, so rebind them the way you rebind anything else — map your own key to the corresponding :Debug* command.

Window hotkeys: gui_keymaps

Neovim mappings cannot reach the debugger window, so the window's bindings are configured separately, as a table of action → chord:

require("bugsaur").setup({
  gui = true,
  gui_keymaps = {
    continue = "Ctrl+R",
    step_over = "F6",
    step_into = "F7",
    step_out = "Shift+F8",
    pause = "F10",
    restart = "Ctrl+Shift+F5",
  },
})

Supported actions here: continue, step_into, step_over, step_out, pause, terminate, restart. The value vim.NIL disables a binding.

Modifiers are Cmd, Ctrl, Alt, Shift, and their order in a chord does not matter — Shift+Alt+F8 and Alt+Shift+F8 are the same chord.

gui_keymaps is read when the GUI process starts

Changing it and re-sourcing your config does not affect a window that is already open.

The project can override your window hotkeys

A [ui.keymaps] section in .bugsaur/config.toml takes precedence over gui_keymaps — but per action, not as a block:

[ui.keymaps]
continue = "Alt+R"
step_over = "F2"
pause = ""        # unbind

What the project names wins; what it does not name stays as you configured it in the editor. So a project with unusual key conventions is consistent for everyone who opens it, without wiping out your personal bindings for everything else.

The full stack, bottom to top:

  1. built-in defaults — F7, F8, Shift+F8, F9, Cmd+F2 / Ctrl+F2, H J K L, the arrow keys;
  2. <root>/.bugsaur-keys.json — a personal per-project file, chord → action, where null removes a binding;
  3. gui_keymaps from the plugin's setup();
  4. [ui.keymaps] from the project config.

Beyond execution, [ui.keymaps] can also bind panel focus and in-panel navigation, which gui_keymaps does not cover. Full action list: Configuration → UI.

When in doubt, ask the window

F1 or ? inside the debugger window shows the bindings actually in effect, after all four layers. That display is the authority — not this page, and not your init.lua.