Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ Settings][debugpy_wiki]
A test runner building upon vim-test with nvim-dap support.
Aims to work for all python runners.

## Development

- Generate docs using [vimcats][vimcats]:

```bash
vimcats -f -t lua/dap-python.lua > doc/dap-python.txt
```


[1]: https://github.com/mfussenegger/nvim-dap
[3]: https://github.com/microsoft/debugpy
Expand All @@ -192,3 +200,4 @@ Aims to work for all python runners.
[6]: https://github.com/junegunn/vim-plug
[7]: https://github.com/wbthomason/packer.nvim
[debugpy_wiki]: https://github.com/microsoft/debugpy/wiki/Debug-configuration-settings
[vimcats]: https://github.com/mrcjkb/vimcats
100 changes: 49 additions & 51 deletions doc/dap-python.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
================================================================================
==============================================================================
Python extension for nvim-dap *dap-python*

M.test_runner *dap-python.test_runner*
Test runner to use by default.
The default value is dynamic and depends on `pytest.ini`, `manage.py` or `pyproject.toml` markers.
If none are found "unittest" is used. See |dap-python.test_runners|
The default value is dynamic and depends on `pytest.ini` or `manage.py` markers.
If neither is found "unittest" is used. See |dap-python.test_runners|
Override this to set a different runner:
```
require('dap-python').test_runner = "pytest"
```

Type: ~
((string|fun():string)) name of the test runner
(string|fun():string) name of the test runner


M.resolve_python *dap-python.resolve_python*
Expand All @@ -30,101 +30,99 @@ M.test_runners *dap-python.test_runners*
module name to run and its arguments. See |dap-python.TestRunner|

Type: ~
(table<string,TestRunner>)
(table<string,dap-python.TestRunner>)


M.setup({adapter_python_path}, {opts}) *dap-python.setup*
M.setup({python_path}, {opts?}) *dap-python.setup*
Register the python debug adapter

Parameters: ~
{adapter_python_path} (string|nil) Path to the python interpreter. Path must be absolute or in $PATH and needs to have the debugpy package installed. Default is `python3`
{opts} (SetupOpts|nil) See |dap-python.SetupOpts|
{python_path} (string|nil) Path to the python interpreter. Path must be absolute or in $PATH and needs to have the debugpy package installed. Default is `python3`
{opts?} (dap-python.setup.opts) See |dap-python.setup.opts|


M.test_class({opts}) *dap-python.test_class*
M.test_class({opts?}) *dap-python.test_class*
Run test class above cursor

Parameters: ~
{opts} (DebugOpts) See |dap-python.DebugOpts|
{opts?} (dap-python.debug_opts) See |dap-python.debug_opts|


M.test_method({opts}) *dap-python.test_method*
M.test_method({opts?}) *dap-python.test_method*
Run the test method above cursor

Parameters: ~
{opts} (DebugOpts) See |dap-python.DebugOpts|
{opts?} (dap-python.debug_opts) See |dap-python.debug_opts|


M.debug_selection({opts}) *dap-python.debug_selection*
M.debug_selection({opts?}) *dap-python.debug_selection*
Debug the selected code

Parameters: ~
{opts} (DebugOpts)
{opts?} (dap-python.debug_opts)


PathMapping *dap-python.PathMapping*
dap-python.PathMapping *dap-python.PathMapping*

Fields: ~
{localRoot} (string)
{remoteRoot} (string)


DebugpyConfig *dap-python.DebugpyConfig*
dap-python.Config *dap-python.Config*

Fields: ~
{django} (boolean|nil) Enable django templates. Default is `false`
{gevent} (boolean|nil) Enable debugging of gevent monkey-patched code. Default is `false`
{jinja} (boolean|nil) Enable jinja2 template debugging. Default is `false`
{justMyCode} (boolean|nil) Debug only user-written code. Default is `true`
{pathMappings} (PathMapping[]|nil) Map of local and remote paths.
{pyramid} (boolean|nil) Enable debugging of pyramid applications
{redirectOutput} (boolean|nil) Redirect output to debug console. Default is `false`
{showReturnValue} (boolean|nil) Shows return value of function when stepping
{sudo} (boolean|nil) Run program under elevated permissions. Default is `false`
{django} (boolean|nil) Enable django templates. Default is `false`
{gevent} (boolean|nil) Enable debugging of gevent monkey-patched code. Default is `false`
{jinja} (boolean|nil) Enable jinja2 template debugging. Default is `false`
{justMyCode} (boolean|nil) Debug only user-written code. Default is `true`
{pathMappings} (dap-python.PathMapping[]|nil) Map of local and remote paths.
{pyramid} (boolean|nil) Enable debugging of pyramid applications
{redirectOutput} (boolean|nil) Redirect output to debug console. Default is `false`
{showReturnValue} (boolean|nil) Shows return value of function when stepping
{sudo} (boolean|nil) Run program under elevated permissions. Default is `false`


DebugpyLaunchConfig *dap-python.DebugpyLaunchConfig*
: DebugpyConfig
*dap-python.LaunchConfig*
dap-python.LaunchConfig : dap-python.Config

Fields: ~
{module} (string|nil) Name of the module to debug
{program} (string|nil) Absolute path to the program
{code} (string|nil) Code to execute in string form
{python} (string[]|nil) Path to python executable and interpreter arguments
{args} (string[]|nil) Command line arguments passed to the program
{console} (DebugpyConsole) See |dap-python.DebugpyConsole|
{cwd} (string|nil) Absolute path to the working directory of the program being debugged.
{env} (table|nil) Environment variables defined as key value pair
{stopOnEntry} (boolean|nil) Stop at first line of user code.
{module} (string|nil) Name of the module to debug
{program} (string|nil) Absolute path to the program
{code} (string|nil) Code to execute in string form
{python} (string[]|nil) Path to python executable and interpreter arguments
{args} (string[]|nil) Command line arguments passed to the program
{console} (dap-python.console) See |dap-python.console|
{cwd} (string|nil) Absolute path to the working directory of the program being debugged.
{env} (table|nil) Environment variables defined as key value pair
{stopOnEntry} (boolean|nil) Stop at first line of user code.


DebugOpts *dap-python.DebugOpts*

dap-python.debug_opts *dap-python.debug_opts*

Fields: ~
{console} (DebugpyConsole) See |dap-python.DebugpyConsole|
{test_runner} ("unittest"|"pytest"|"django"|string) name of the test runner. Default is |dap-python.test_runner|
{config} (DebugpyConfig) Overrides for the configuration

{console?} (dap-python.console)
{test_runner?} ()

SetupOpts *dap-python.SetupOpts*

dap-python.setup.opts *dap-python.setup.opts*

Fields: ~
{include_configs} (boolean) Add default configurations
{console} (DebugpyConsole) See |dap-python.DebugpyConsole|
{pythonPath} (string|nil) Path to python interpreter. Uses interpreter from `VIRTUAL_ENV` environment variable or `adapter_python_path` by default
{include_configs?} (boolean) Add default configurations
{console?} (dap-python.console)
{pythonPath?} (string)
Path to python interpreter. Uses interpreter from `VIRTUAL_ENV` environment
variable or `python_path` by default


TestRunner *TestRunner*
string, methodname: string): string module, string[] args
dap-python.TestRunner *dap-python.TestRunner*
A function receiving classname and methodname; must return module to run and its arguments

Type: ~
fun(classname:

fun

DebugpyConsole *DebugpyConsole*

dap-python.console *dap-python.console*

Type: ~
"internalConsole"|"integratedTerminal"|"externalTerminal"|nil
Expand Down
4 changes: 0 additions & 4 deletions lemmy.sh

This file was deleted.

65 changes: 39 additions & 26 deletions lua/dap-python.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ local uv = vim.uv or vim.loop
--- ```
--- require('dap-python').test_runner = "pytest"
--- ```
---@type (string|fun():string) name of the test runner
---@type string|fun():string name of the test runner
M.test_runner = nil


Expand All @@ -26,7 +26,7 @@ M.resolve_python = nil
--- Built-in are test runners for unittest, pytest and django.
--- The key is the test runner name, the value a function to generate the
--- module name to run and its arguments. See |dap-python.TestRunner|
---@type table<string, TestRunner>
---@type table<string, dap-python.TestRunner>
M.test_runners = {}


Expand Down Expand Up @@ -90,6 +90,7 @@ local function default_runner()
end


---@return string|nil
local get_python_path = function()
local venv_path = os.getenv('VIRTUAL_ENV')
if venv_path then
Expand Down Expand Up @@ -123,8 +124,11 @@ local get_python_path = function()
end


---@param config dap-python.Config|dap-python.LaunchConfig
---@param on_config fun(config: dap-python.Config)
local enrich_config = function(config, on_config)
if not config.pythonPath and not config.python then
---@diagnostic disable-next-line: inject-field
config.pythonPath = get_python_path()
end
on_config(config)
Expand Down Expand Up @@ -164,6 +168,7 @@ local function flatten(...)
if vim.iter then
return vim.iter(values):flatten(2):totable()
end
---@diagnostic disable-next-line: deprecated
return vim.tbl_flatten(values)
end

Expand Down Expand Up @@ -202,11 +207,11 @@ end


--- Register the python debug adapter
---@param adapter_python_path string|nil Path to the python interpreter. Path must be absolute or in $PATH and needs to have the debugpy package installed. Default is `python3`
---@param opts SetupOpts|nil See |dap-python.SetupOpts|
function M.setup(adapter_python_path, opts)
---@param python_path string|nil Path to the python interpreter. Path must be absolute or in $PATH and needs to have the debugpy package installed. Default is `python3`
---@param opts? dap-python.setup.opts See |dap-python.setup.opts|
function M.setup(python_path, opts)
local dap = load_dap()
adapter_python_path = adapter_python_path and vim.fn.expand(vim.fn.trim(adapter_python_path), true) or 'python3'
python_path = python_path and vim.fn.expand(vim.fn.trim(python_path), true) or 'python3'
opts = vim.tbl_extend('keep', opts or {}, default_setup_opts)
dap.adapters.python = function(cb, config)
if config.request == 'attach' then
Expand All @@ -226,7 +231,7 @@ function M.setup(adapter_python_path, opts)
else
cb({
type = 'executable';
command = adapter_python_path;
command = python_path;
args = { '-m', 'debugpy.adapter' };
enrich_config = enrich_config;
options = {
Expand Down Expand Up @@ -317,6 +322,7 @@ local function reverse(list)
end


---@private
---@param source string|integer
---@param subject "function"|"class"
---@param end_row integer? defaults to cursor
Expand Down Expand Up @@ -392,7 +398,7 @@ end

---@param classnames string[]
---@param methodname string?
---@param opts DebugOpts
---@param opts dap-python.debug_opts
local function trigger_test(classnames, methodname, opts)
local test_runner = opts.test_runner or (M.test_runner or default_runner)
if type(test_runner) == "function" then
Expand Down Expand Up @@ -420,7 +426,7 @@ end


--- Run test class above cursor
---@param opts? DebugOpts See |dap-python.DebugOpts|
---@param opts? dap-python.debug_opts See |dap-python.debug_opts|
function M.test_class(opts)
opts = vim.tbl_extend('keep', opts or {}, default_test_opts)
local candidates = M._get_nodes(0, "class")
Expand Down Expand Up @@ -452,7 +458,7 @@ end


--- Run the test method above cursor
---@param opts? DebugOpts See |dap-python.DebugOpts|
---@param opts? dap-python.debug_opts See |dap-python.debug_opts|
function M.test_method(opts)
opts = vim.tbl_extend('keep', opts or {}, default_test_opts)
local functions = M._get_nodes(0, "function")
Expand All @@ -471,6 +477,8 @@ end
--
-- >>> remove_indent({' print(10)', ' if True:', ' print(20)'})
-- {'print(10)', 'if True:', ' print(20)'}
---@param lines string[]
---@return string[]
local function remove_indent(lines)
local offset = nil
for _, line in ipairs(lines) do
Expand All @@ -489,7 +497,7 @@ end


--- Debug the selected code
---@param opts? DebugOpts
---@param opts? dap-python.debug_opts
function M.debug_selection(opts)
opts = vim.tbl_extend('keep', opts or {}, default_test_opts)
local start_row, _ = unpack(api.nvim_buf_get_mark(0, '<'))
Expand All @@ -507,47 +515,52 @@ end



---@class PathMapping
---@class dap-python.PathMapping
---@field localRoot string
---@field remoteRoot string


---@class DebugpyConfig
---@class dap-python.Config
---@field django boolean|nil Enable django templates. Default is `false`
---@field gevent boolean|nil Enable debugging of gevent monkey-patched code. Default is `false`
---@field jinja boolean|nil Enable jinja2 template debugging. Default is `false`
---@field justMyCode boolean|nil Debug only user-written code. Default is `true`
---@field pathMappings PathMapping[]|nil Map of local and remote paths.
---@field pathMappings dap-python.PathMapping[]|nil Map of local and remote paths.
---@field pyramid boolean|nil Enable debugging of pyramid applications
---@field redirectOutput boolean|nil Redirect output to debug console. Default is `false`
---@field showReturnValue boolean|nil Shows return value of function when stepping
---@field sudo boolean|nil Run program under elevated permissions. Default is `false`

---@class DebugpyLaunchConfig : DebugpyConfig

---@class dap-python.LaunchConfig : dap-python.Config
---@field module string|nil Name of the module to debug
---@field program string|nil Absolute path to the program
---@field code string|nil Code to execute in string form
---@field python string[]|nil Path to python executable and interpreter arguments
---@field args string[]|nil Command line arguments passed to the program
---@field console DebugpyConsole See |dap-python.DebugpyConsole|
---@field console dap-python.console See |dap-python.console|
---@field cwd string|nil Absolute path to the working directory of the program being debugged.
---@field env table|nil Environment variables defined as key value pair
---@field stopOnEntry boolean|nil Stop at first line of user code.


---@class DebugOpts
---@field console DebugpyConsole See |dap-python.DebugpyConsole|
---@field test_runner "unittest"|"pytest"|"django"|string name of the test runner. Default is |dap-python.test_runner|
---@field config DebugpyConfig Overrides for the configuration
---@class dap-python.debug_opts
---@field console? dap-python.console
---@field test_runner? "unittest"|"pytest"|"django"|string name of the test runner
---@field config? dap-python.Config Overrides for the configuration

---@class SetupOpts
---@field include_configs boolean Add default configurations
---@field console DebugpyConsole See |dap-python.DebugpyConsole|
---@field pythonPath string|nil Path to python interpreter. Uses interpreter from `VIRTUAL_ENV` environment variable or `adapter_python_path` by default
---@class dap-python.setup.opts
---@field include_configs? boolean Add default configurations
---@field console? dap-python.console
---
--- Path to python interpreter. Uses interpreter from `VIRTUAL_ENV` environment
--- variable or `python_path` by default
---@field pythonPath? string


---@alias TestRunner fun(classname: string|string[], methodname: string?):string, string[]
--- A function receiving classname and methodname; must return module to run and its arguments
---@alias dap-python.TestRunner fun(classname: string|string[], methodname: string?):string, string[]

---@alias DebugpyConsole "internalConsole"|"integratedTerminal"|"externalTerminal"|nil
---@alias dap-python.console 'internalConsole'|'integratedTerminal'|'externalTerminal'|nil

return M
Loading