Vimspector is a powerful, extensible debugger for Vim, designed to feel like a native Vim experience.

Let’s see Vimspector in action with a simple Python script.

Consider this main.py:

def greet(name):
    message = f"Hello, {name}!"
    return message

if __name__ == "__main__":
    user_name = "Vimspector User"
    greeting = greet(user_name)
    print(greeting)

First, we need to tell Vimspector how to build and run our Python code. This is done via a .vimspector.json file in your project’s root directory.

{
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal"
        }
    ]
}

This configuration tells Vimspector:

  • "name": A human-readable name for this debug configuration.
  • "type": The debugger backend to use (in this case, Python).
  • "request": Whether we’re launching a new process ("launch") or attaching to an existing one ("attach").
  • "program": The script to run. ${file} is a Vimspector variable that expands to the currently open file.
  • "console": Where to show the program’s output. "integratedTerminal" uses Vim’s built-in terminal.

With this setup, open main.py in Vim. Now, use Vimspector’s command to launch the debugger. Typically, this is mapped to a key, but you can invoke it directly: :VimspectorLaunch Python: Current File.

Vimspector will now start the Python interpreter to run main.py. Since we haven’t set any breakpoints yet, it will run to completion, and you’ll see "Hello, Vimspector User!" printed in your Vim terminal.

To actually debug, we need breakpoints. Navigate to line 2 in main.py (the def greet(name): line) and press <leader>b (assuming <leader> is your Vim leader key, often \ or ,). You’ll see a small marker appear next to the line number. Repeat this for line 4 (message = f"Hello, {name}!").

Now, run :VimspectorLaunch Python: Current File again. This time, execution will pause at the first breakpoint on line 2. Vimspector’s UI will appear, showing variables, call stacks, and the code itself.

You can now step through the code.

  • n (or <leader>dn): Step Over. Executes the current line and moves to the next.
  • s (or <leader>ds): Step Into. If the current line is a function call, steps into that function.
  • o (or <leader>do): Step Out. Continues execution until the current function returns.
  • c (or <leader>dc): Continue. Resumes execution until the next breakpoint or the program ends.

As you step, watch the "Variables" pane. When you’re on line 4, you’ll see name have the value "Vimspector User". After stepping over line 4, message will appear with the value "Hello, Vimspector User!".

The real power of Vimspector comes from its integration with Vim’s editing capabilities. You can open files directly from the call stack, modify code on the fly (though this might not always reflect in the currently running process without restarting), and use Vim’s search and navigation within the debug UI.

The Vimspector UI itself is composed of several buffers:

  • Variables: Shows local and global variables.
  • Watch: Allows you to add expressions to monitor.
  • Call Stack: Displays the sequence of function calls leading to the current point.
  • Breakpoints: Lists all active breakpoints.
  • Debug Console: An interactive REPL for the debugged program.

This integrated approach means you’re not context-switching to a separate debugger window. You’re debugging within Vim, using the editor you already know.

When you encounter a breakpoint, Vimspector highlights the current line. If you want to inspect a variable that’s not immediately visible, you can open the "Watch" pane and add an expression like greeting or even greeting.upper().

A common misunderstanding is that Vimspector requires a separate server process. While it can attach to existing processes, its primary mode is "launch", where it manages the entire debugging session from start to finish, using the specified debugger backend (like python, gdb, lldb, etc.) and its corresponding protocol (like DAP).

The next step in mastering Vimspector is understanding how to configure conditional breakpoints and how to use Vimspector’s "expressions" feature to evaluate arbitrary code in the context of the running program.

Want structured learning?

Take the full Vim course →