Merge pull request #1642 from horriblename/dap-rework
Some checks failed
Set up binary cache / cachix (default) (push) Has been cancelled
Set up binary cache / cachix (maximal) (push) Has been cancelled
Set up binary cache / cachix (nix) (push) Has been cancelled
Treewide Checks / Validate flake (push) Has been cancelled
Treewide Checks / Check formatting (push) Has been cancelled
Treewide Checks / Check source tree for typos (push) Has been cancelled
Treewide Checks / Validate documentation builds (push) Has been cancelled
Treewide Checks / Validate documentation builds-1 (push) Has been cancelled
Treewide Checks / Validate documentation builds-2 (push) Has been cancelled
Treewide Checks / Validate documentation builds-3 (push) Has been cancelled
Treewide Checks / Validate hyperlinks in documentation sources (push) Has been cancelled
Treewide Checks / Validate Editorconfig conformance (push) Has been cancelled
Build and deploy documentation / Check latest commit (push) Has been cancelled
Build and deploy documentation / publish (push) Has been cancelled

DAP rework
This commit is contained in:
Snoweuph 2026-06-24 00:22:59 +02:00 committed by GitHub
commit b1b92ec251
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 726 additions and 300 deletions

View file

@ -46,7 +46,7 @@ in {
# Example:
#
# vim.languages.typescript.lsp.servers = mkOption {
# type = renamedEnum
# type = enumWithRename
# "vim.languages.typescript.lsp.servers"
# ["typescript-language-server" "some-other-server"]
# { ts_ls = "typescript-language-server"; };

View file

@ -396,5 +396,33 @@ in {
Linters can still be customized via `vim.diagnostics.nvim-lint.<name>.args`
'')
]
# 2026-06-13
[
(mkRemovedOptionModule ["vim" "languages" "clang" "dap" "package"] ''
Please use `vim.debugger.nvim-dap.adapters.<debugger>.command` instead.
'')
(mkRemovedOptionModule ["vim" "languages" "zig" "dap" "package"] ''
Please use `vim.debugger.nvim-dap.adapters.<debugger>.command` instead.
'')
(mkRemovedOptionModule ["vim" "languages" "python" "dap" "package"] ''
Please use `vim.debugger.nvim-dap.adapters.<debugger>.command` instead.
Also see `vim.debugger.nvim-dap.configurations.python` if you want
to use a custom python/additional libraries as your debuggee
'')
(mkRemovedOptionModule ["vim" "languages" "odin" "dap" "package"] ''
Please use `vim.debugger.nvim-dap.adapters.<debugger>.command` instead.
'')
(mkRemovedOptionModule ["vim" "languages" "java" "dap" "package"] ''
Please use `vim.debugger.nvim-dap.adapters.<debugger>.command` instead.
'')
(mkRenamedOptionModule
["vim" "languages" "php" "dap" "xdebug" "adapter"]
["vim" "debugger" "nvim-dap" "adapters" "xdebug"])
(mkRemovedOptionModule ["vim" "languages" "php" "dap" "xdebug" "port"] ''
Please use a custom `vim.debugger.nvim-dap.configurations.php`
instead.
'')
]
];
}

View file

@ -4,11 +4,13 @@
lib,
...
}: let
inherit (builtins) concatStringsSep;
inherit (lib.strings) optionalString;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.attrsets) mapAttrs;
inherit (lib.attrsets) mapAttrs mapAttrsToList;
inherit (lib.nvim.binds) mkKeymap;
inherit (lib.nvim.dag) entryAnywhere entryAfter;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.debugger.nvim-dap;
opt = {
@ -28,6 +30,30 @@ in {
nvim-dap = entryAnywhere ''
local dap = require("dap")
vim.fn.sign_define("DapBreakpoint", { text = "🛑", texthl = "ErrorMsg", linehl = "", numhl = "" })
local nvf_dap_input_cache= {}
local function nvf_dap_cached_input(cache_key, prompt, default, completion)
default = nvf_dap_input_cache[cache_key] or default
nvf_dap_input_cache[cache_key] =
vim.fn.input(prompt, default, completion)
return nvf_dap_input_cache[cache_key]
end
${
concatStringsSep "\n"
(mapAttrsToList (name: opts: ''
dap.adapters[${toLuaObject name}] = ${toLuaObject opts}
'')
cfg.adapters)
}
${
concatStringsSep "\n"
(mapAttrsToList (ft: opts: ''
dap.configurations[${toLuaObject ft}] = ${toLuaObject opts}
'')
cfg.configurations)
}
'';
}
// mapAttrs (_: v: (entryAfter ["nvim-dap"] v)) cfg.sources;

View file

@ -1,5 +1,6 @@
{
imports = [
./presets
./config.nix
./nvim-dap.nix
];

View file

@ -4,9 +4,254 @@
...
}: let
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) bool attrsOf str;
inherit (lib.nvim.types) mkPluginSetupOption;
inherit (lib.types) bool attrsOf str submodule anything either enum oneOf listOf nullOr int;
inherit (lib.nvim.types) mkPluginSetupOption luaInline;
inherit (config.vim.lib) mkMappingOption;
commonOptions = {
initialize_timeout_sec = mkOption {
type = nullOr int;
default = null;
defaultText = "4"; # plugin default
description = ''
How many seconds to wait for a response on an initialize request before
emitting a warning
'';
};
disconnect_timeout_sec = mkOption {
type = nullOr int;
default = null;
defaultText = "3"; # plugin default
description = ''
How many seconds to wait for a disconnect response before
emitting a warning and closing the connection
'';
};
source_filetype = mkOption {
type = nullOr str;
default = null;
description = ''
The filetype to use for content retrieved via a source request
'';
};
};
# enrich_config accepted by all adapter types
enrich_config = mkOption {
type = nullOr luaInline;
default = null;
description = ''
Used to enrich a configurations with additional information.
See `:help dap-adapter`.
'';
};
execAdapterType = submodule {
options = {
type = mkOption {
type = enum ["executable"];
};
command = mkOption {
type = str;
description = "Command to invoke";
};
args = mkOption {
type = listOf str;
};
options =
commonOptions
// {
env = mkOption {
type = nullOr (attrsOf str);
default = null;
description = "Environment variables passed to the command";
};
cwd = mkOption {
type = nullOr str;
default = null;
description = "Set the working directory for the command";
};
detached = mkOption {
type = nullOr bool;
default = null;
defaultText = "true"; # plugin default
description = ''
Whether to spawn the debug adapter process in a detached state
'';
};
};
id = mkOption {
type = nullOr str;
default = null;
description = ''
Identifier of the adapter. This is used for the `adapterId` property
of the initialize request.
'';
};
inherit enrich_config;
};
};
serverPipeExecutable = submodule {
options = {
command = mkOption {
type = nullOr str;
description = "Command that spawns the debug adapter";
};
args = mkOption {
type = nullOr (listOf str);
default = null;
};
detached = mkOption {
type = nullOr bool;
default = null;
defaultText = "true"; # plugin default
description = ''
Whether to spawn the debug adapter process in a detached state
'';
};
cwd = mkOption {
type = nullOr str;
default = null;
description = "Working directory";
};
};
};
serverAdapterType = submodule {
options = {
type = mkOption {
type = enum ["server"];
};
host = mkOption {
type = nullOr str;
default = null;
defaultText = "127.0.0.1"; # plugin default
description = "Host to connect to";
};
port = mkOption {
type = either int (enum ["\${port}"]);
description = ''
Port to connect to. Use "''${port}" for a dynamically resolved free
port. This is intended to be used with executable.args.
'';
};
id = mkOption {
type = nullOr str;
default = null;
description = ''
Identifier of the adapter. This is used for the `adapterId` property
of the initialize request.
'';
};
executable = mkOption {
type = nullOr serverPipeExecutable;
default = null;
description = ''
Optional executable configuration to launch the debug adapter before
connecting via TCP
'';
};
options =
commonOptions
// {
max_retries = mkOption {
type = nullOr int;
default = null;
defaultText = "14"; # plugin default
description = ''
Amount of times the client should attempt to connect before
erroring out (250ms delay between retries)
'';
};
};
inherit enrich_config;
};
};
pipeAdapterType = submodule {
options = {
type = mkOption {
type = enum ["pipe"];
};
pipe = mkOption {
type = str;
description = ''
Absolute path to the pipe file. Use \"''${pipe}\" for a dynamically
generated temporary filename
'';
};
executable = mkOption {
type = nullOr serverPipeExecutable;
default = null;
description = ''
Optional executable configuration to launch the debug adapter before
connecting via pipe
'';
};
options =
commonOptions
// {
timeout = mkOption {
type = nullOr int;
default = null;
defaultText = "5000"; # plugin default
description = ''
Max amount of time in ms to wait between spawning the
executable and connecting to the pipe
'';
};
};
inherit enrich_config;
};
};
configurationType = submodule {
freeformType = attrsOf anything;
# These 3 options are required, everything else is passed to the debug
# adapter
options = {
type = mkOption {
type = str;
description = "Which debug adapter to use";
};
request = mkOption {
type = enum ["attach" "launch"];
description = ''
Indicates whether the debug adapter should launch a debuggee or attach
to one that is already running.
'';
};
name = mkOption {
type = str;
description = "A user-readable name for the configuration";
};
};
};
in {
options.vim.debugger.nvim-dap = {
enable = mkEnableOption "debugging via nvim-dap";
@ -19,7 +264,10 @@ in {
autoStart = mkOption {
type = bool;
default = true;
description = "Automatically Opens and Closes DAP-UI upon starting/closing a debugging session";
description = ''
Automatically Opens and Closes DAP-UI upon starting/closing a
debugging session
'';
};
};
@ -29,6 +277,27 @@ in {
type = attrsOf str;
};
adapters = mkOption {
type = attrsOf (oneOf [
luaInline
execAdapterType
serverAdapterType
pipeAdapterType
]);
default = {};
description = "Adapter configurations. See `:help dap-adapter`";
};
configurations = mkOption {
type = attrsOf (listOf configurationType);
default = {};
description = ''
Mapping of filetype to list of debuggee configurations.
See `:help dap-configuration`.
'';
};
mappings = {
continue = mkMappingOption "Continue" "<leader>dc";
restart = mkMappingOption "Restart" "<leader>dR";

View file

@ -0,0 +1,54 @@
{
lib,
pkgs,
config,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.options) mkEnableOption;
inherit (lib.generators) mkLuaInline;
inherit (lib.meta) getExe;
cfg = config.vim.debugger.nvim-dap.presets.debugpy;
package = pkgs.python3.withPackages (ps: with ps; [debugpy]);
in {
options.vim.debugger.nvim-dap.presets.debugpy = {
enable = mkEnableOption ''
adapter configuration for debugpy.
Use {option}`vim.debugger.nvim-dap.adapters.debugpy` for customization.
A configuration is also needed for your filetype in
{option}`vim.debugger.nvim-dap.configurations`
See https://github.com/microsoft/debugpy/wiki/Debug-configuration-settings
for supported options.
'';
};
config.vim.debugger.nvim-dap.adapters = mkIf cfg.enable {
debugpy = mkLuaInline ''
function(cb, config)
if config.request == "attach" then
local port = (config.connect or config).port
local host = (config.connect or config).host or "127.0.0.1"
cb({
type = "server",
port = assert(port, "`connect.port` is required for a python `attach` configuration"),
host = host,
options = {
source_filetype = "python",
},
})
else
cb({
type = "executable",
command = "${getExe package}",
args = { "-m", "debugpy.adapter" },
options = {
source_filetype = "python",
},
})
end
end
'';
};
}

View file

@ -0,0 +1,8 @@
{
imports = [
./debugpy.nix
./jls.nix
./lldb.nix
./xdebug.nix
];
}

View file

@ -0,0 +1,31 @@
{
lib,
pkgs,
config,
inputs,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.options) mkEnableOption;
inherit (lib.meta) getExe';
cfg = config.vim.debugger.nvim-dap.presets.jls;
pkg = inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.jls;
in {
options.vim.debugger.nvim-dap.presets.jls = {
enable = mkEnableOption ''
adapter configuration for JLS.
Use {option}`vim.debugger.nvim-dap.adapters.jls` for customization.
A configuration is also needed for your filetype in
{option}`vim.debugger.nvim-dap.configurations`
'';
};
config.vim.debugger.nvim-dap.adapters = mkIf cfg.enable {
jls = {
type = "executable";
command = getExe' pkg "jls-dap";
};
};
}

View file

@ -0,0 +1,28 @@
{
lib,
pkgs,
config,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.options) mkEnableOption;
cfg = config.vim.debugger.nvim-dap.presets.lldb;
in {
options.vim.debugger.nvim-dap.presets.lldb = {
enable = mkEnableOption ''
adapter configuration for LLDB using `lldb-dap`.
Use {option}`vim.debugger.nvim-dap.adapters.lldb` for customization.
A configuration is also needed for your filetype in
{option}`vim.debugger.nvim-dap.configurations`
'';
};
config.vim.debugger.nvim-dap.adapters = mkIf cfg.enable {
lldb = {
type = "executable";
command = "${pkgs.lldb}/bin/lldb-dap";
};
};
}

View file

@ -0,0 +1,32 @@
{
lib,
pkgs,
config,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.options) mkEnableOption;
inherit (lib.meta) getExe;
cfg = config.vim.debugger.nvim-dap.presets.xdebug;
in {
options.vim.debugger.nvim-dap.presets.xdebug = {
enable = mkEnableOption ''
adapter configuration for Xdebug.
Use {option}`vim.debugger.nvim-dap.adapters.xdebug` for customization.
A configuration is also needed for your filetype in
{option}`vim.debugger.nvim-dap.configurations`
'';
};
config.vim.debugger.nvim-dap.adapters = mkIf cfg.enable {
xdebug = {
type = "executable";
command = getExe pkgs.nodejs;
args = [
"${pkgs.vscode-extensions.xdebug.php-debug}/share/vscode/extensions/xdebug.php-debug/out/phpDebug.js"
];
};
};
}

View file

@ -6,47 +6,42 @@
}: let
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption literalExpression;
inherit (lib.types) bool enum package listOf;
inherit (lib.types) bool enum listOf;
inherit (lib) genAttrs;
inherit (lib.meta) getExe getExe';
inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.dag) entryAfter;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) deprecatedSingleOrListOf enumWithRename;
cfg = config.vim.languages.clang;
defaultServers = ["clangd"];
servers = ["ccls" "clangd"];
defaultDebugger = "lldb-vscode";
debuggers = {
lldb-vscode = {
package = pkgs.lldb;
dapConfig = ''
dap.adapters.lldb = {
type = 'executable',
command = '${cfg.dap.package}/bin/lldb-dap',
name = 'lldb'
}
dap.configurations.cpp = {
{
name = 'Launch',
type = 'lldb',
request = 'launch',
program = function()
return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
end,
cwd = "''${workspaceFolder}",
stopOnEntry = false,
args = {},
},
}
dap.configurations.c = dap.configurations.cpp
'';
};
defaultDebugger = ["lldb"];
dapConfigurations = {
lldb = [
{
name = "Launch";
type = "lldb";
request = "launch";
program = mkLuaInline ''
function()
return nvf_dap_cached_input(
'clang_lldb_launch_exe',
"Path to executable: ",
vim.fn.getcwd() .. "/",
"file")
end
'';
cwd = "\${workspaceFolder}";
stopOnEntry = false;
args = [];
}
];
};
defaultFormat = ["clang-format"];
@ -147,14 +142,13 @@ in {
};
debugger = mkOption {
description = "clang debugger to use";
type = enum (attrNames debuggers);
type =
deprecatedSingleOrListOf "vim.languages.clang.dap.debugger"
(enumWithRename "vim.languages.clang.dap.debugger" (attrNames dapConfigurations) {
lldb-vscode = "lldb";
});
default = defaultDebugger;
};
package = mkOption {
description = "clang debugger package.";
type = package;
default = debuggers.${cfg.dap.debugger}.package;
};
};
format = {
@ -208,8 +202,16 @@ in {
})
(mkIf cfg.dap.enable {
vim.debugger.nvim-dap.enable = true;
vim.debugger.nvim-dap.sources.clang-debugger = debuggers.${cfg.dap.debugger}.dapConfig;
vim.debugger.nvim-dap = let
conf = mkMerge (map (name: dapConfigurations.${name}) cfg.dap.debugger);
in {
enable = true;
presets = genAttrs cfg.dap.debugger (_: {enable = true;});
configurations = {
c = conf;
cpp = conf;
};
};
})
(mkIf cfg.format.enable {

View file

@ -2,78 +2,73 @@
config,
pkgs,
lib,
inputs,
...
}: let
inherit (lib.modules) mkIf mkMerge;
inherit (lib.options) literalExpression mkEnableOption mkOption;
inherit (lib.types) listOf str enum package;
inherit (lib.types) listOf str enum;
inherit (lib.attrsets) attrNames genAttrs;
inherit (lib.meta) getExe getExe';
inherit (lib.nvim.types) mkGrammarOption mkPluginSetupOption enumWithRename;
inherit (lib.lists) flatten;
inherit (lib.meta) getExe;
inherit (lib.generators) mkLuaInline toPretty;
inherit (lib.nvim.types) mkGrammarOption mkPluginSetupOption deprecatedSingleOrListOf enumWithRename;
cfg = config.vim.languages.java;
defaultServers = ["jdt-language-server"];
servers = ["jdt-language-server" "jls"];
defaultDebugger = "jls";
debuggers = {
jls = let
pkg = inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.jls;
in {
package = pkg;
config = ''
dap.adapters.jls= {
type = 'executable',
command = '${getExe' pkg "jls-dap"}',
}
dap.configurations.java = {
{
type = "jls",
request = "attach",
name = "Attach Auto",
hostName = "localhost",
port = 5005,
sourceRoots = function()
local matches = {}
defaultDebugger = ["jls"];
dapConfigurations = {
jls = [
{
type = "jls";
request = "attach";
name = "Attach Auto";
hostName = "localhost";
port = 5005;
sourceRoots = mkLuaInline ''
function()
local matches = {}
-- only look max 3 deep, due to performance reasons
for _, pattern in ipairs({
"src/main/java",
"*/src/main/java",
"*/*/src/main/java",
"*/*/*/src/main/java",
}) do
vim.list_extend(matches, vim.fn.glob(pattern, true, true))
end
-- only look max 3 deep, due to performance reasons
for _, pattern in ipairs({
"src/main/java",
"*/src/main/java",
"*/*/src/main/java",
"*/*/*/src/main/java",
}) do
vim.list_extend(matches, vim.fn.glob(pattern, true, true))
end
return matches
end,
},
{
type = "jls",
request = "attach",
name = "Attach Manual",
hostName = "localhost",
port = 5005,
sourceRoots = function()
local path = vim.fn.input(
"Path to src/main/java: ",
vim.fn.getcwd() .. "/",
"dir"
)
return matches
end
'';
}
{
type = "jls";
request = "attach";
name = "Attach Manual";
hostName = "localhost";
port = 5005;
sourceRoots = mkLuaInline ''
function()
local path = nvf_dap_cached_input(
"java_jls_attach_root",
"Path to src/main/java: ",
vim.fn.getcwd() .. "/",
"dir"
)
if path == "" then
return {}
end
if path == "" then
return {}
end
return { vim.fn.fnamemodify(path, ":p") }
end,
},
}
'';
};
return { vim.fn.fnamemodify(path, ":p") }
end
'';
}
];
};
in {
options.vim.languages.java = {
@ -117,22 +112,28 @@ in {
};
debugger = mkOption {
type = enum (attrNames debuggers);
type =
deprecatedSingleOrListOf "vim.languages.java.dap.debugger"
(enum (attrNames dapConfigurations));
default = defaultDebugger;
description = ''
Java debugger to use.
**JLS**
For `jls` to work, you need to run your application with debug symbols and networking.
For `jls` to work, you need to run your application with debug
symbols and networking.
The `jls` configuration is hardcoded to listen on port `5005`.
This matches the configuration described [upstream](https://github.com/idelice/jls#usage).
You can change this by modifying `vim.debugger.nvim-dap.sources.java-debugger`.
The `jls` configuration is hardcoded to listen on port `5005`. This
matches the configuration described
[upstream](https://github.com/idelice/jls#usage). You can change this
by modifying {option}`vim.debugger.nvim-dap.configurations.java`.
```nix
vim.debugger.nvim-dap.sources.java-debugger = /* lua */ '''
${debuggers.jls.config}
''';
# mkForce can be omitted if you want to retain our default
# configurations
vim.debugger.nvim-dap.configurations.java =
lib.mkForce
${toPretty {indent = " ";} dapConfigurations.jls};
```
*Examples:*
@ -147,18 +148,13 @@ in {
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 -jar your.jar
```
- Springboot Maven:
For Springboot you can just pass the JVM args directly into the `spring-boot:run`.
For Springboot you can just pass the JVM args directly into the
`spring-boot:run`.
```sh
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
```
'';
};
package = mkOption {
type = package;
default = debuggers.${cfg.dap.debugger}.package;
description = "Java debugger package.";
};
};
extensions = {
@ -218,7 +214,8 @@ in {
(mkIf cfg.dap.enable {
vim.debugger.nvim-dap = {
enable = true;
sources.java-debugger = debuggers.${cfg.dap.debugger}.config;
presets = genAttrs cfg.dap.debugger (_: {enable = true;});
configurations.java = flatten (map (name: dapConfigurations.${name}) cfg.dap.debugger);
};
})

View file

@ -7,27 +7,37 @@
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption literalExpression;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) enum package listOf;
inherit (lib.nvim.dag) entryAfter;
inherit (lib) genAttrs;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.types) enum listOf;
inherit (lib.attrsets) genAttrs;
inherit (lib.lists) flatten;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf enumWithRename;
cfg = config.vim.languages.odin;
defaultServers = ["ols"];
servers = ["ols"];
defaultDebugger = "codelldb";
debuggers = {
codelldb = {
package = pkgs.lldb;
dapConfig = ''
dap.adapters.codelldb = {
type = 'executable',
command = '${cfg.dap.package}/bin/lldb-dap',
name = 'codelldb'
}
'';
};
defaultDebugger = ["lldb"];
dapConfigurations = {
lldb = [
{
name = "Launch";
type = "lldb";
request = "launch";
program = mkLuaInline ''
function()
return nvf_dap_cached_input(
'odin_lldb_launch_exe',
"Path to executable: ",
vim.fn.getcwd() .. "/",
"file")
end
'';
cwd = "\${workspaceFolder}";
stopOnEntry = false;
args = [];
}
];
};
in {
options.vim.languages.odin = {
@ -68,14 +78,13 @@ in {
debugger = mkOption {
description = "Odin debugger to use";
type = enum (attrNames debuggers);
default = defaultDebugger;
};
type =
deprecatedSingleOrListOf "vim.languages.clang.dap.debugger"
(enumWithRename "vim.languages.clang.dap.debugger" (attrNames dapConfigurations) {
codelldb = "lldb";
});
package = mkOption {
description = "Odin debugger package.";
type = package;
default = debuggers.${cfg.dap.debugger}.package;
default = defaultDebugger;
};
};
};
@ -96,15 +105,10 @@ in {
})
(mkIf cfg.dap.enable {
vim = {
startPlugins = ["nvim-dap-odin"];
debugger.nvim-dap.sources.odin-debugger = debuggers.${cfg.dap.debugger}.dapConfig;
pluginRC.nvim-dap-odin = entryAfter ["nvim-dap"] ''
require('nvim-dap-odin').setup({
notifications = false -- contains no useful information
})
'';
debugger.nvim-dap.enable = true;
vim.debugger.nvim-dap = {
enable = true;
presets = genAttrs cfg.dap.debugger (_: {enable = true;});
configurations.odin = flatten (map (name: dapConfigurations.${name}) cfg.dap.debugger);
};
})
]);

View file

@ -7,10 +7,9 @@
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption literalExpression;
inherit (lib) genAttrs;
inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) enum int attrs listOf;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.types) enum listOf;
inherit (lib.lists) flatten;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.attrsets) mapListToAttrs;
@ -36,6 +35,20 @@
defaultDiagnosticsProvider = ["phpstan"];
diagnosticsProviders = ["phpstan"];
defaultDebugger = ["xdebug"];
dapConfigurations = {
xdebug = let
port = 9003;
in [
{
type = "xdebug";
request = "launch";
name = "Listen for XDebug at port ${toString port}";
inherit port;
}
];
};
in {
options.vim.languages.php = {
enable = mkEnableOption "PHP language support";
@ -87,23 +100,11 @@ in {
default = config.vim.languages.enableDAP;
defaultText = literalExpression "config.vim.languages.enableDAP";
};
xdebug = {
adapter = mkOption {
type = attrs;
default = {
type = "executable";
command = getExe pkgs.nodejs;
args = [
"${pkgs.vscode-extensions.xdebug.php-debug}/share/vscode/extensions/xdebug.php-debug/out/phpDebug.js"
];
};
description = "XDebug adapter to use for nvim-dap";
};
port = mkOption {
type = int;
default = 9003;
description = "Port to use for XDebug";
};
debugger = mkOption {
type = listOf (enum (attrNames dapConfigurations));
default = defaultDebugger;
description = "PHP debugger to use";
};
};
@ -154,21 +155,10 @@ in {
})
(mkIf cfg.dap.enable {
vim = {
debugger.nvim-dap = {
enable = true;
sources.php-debugger = ''
dap.adapters.xdebug = ${toLuaObject cfg.dap.xdebug.adapter}
dap.configurations.php = {
{
type = 'xdebug',
request = 'launch',
name = 'Listen for XDebug',
port = ${toString cfg.dap.xdebug.port},
},
}
'';
};
vim.debugger.nvim-dap = {
enable = true;
presets = genAttrs cfg.dap.debugger (_: {enable = true;});
configurations.php = flatten (map (name: dapConfigurations.${name}) cfg.dap.debugger);
};
})

View file

@ -11,6 +11,7 @@
inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) enum package bool listOf;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) deprecatedSingleOrListOf;
inherit (lib.trivial) warn;
@ -49,67 +50,34 @@
};
};
defaultDebugger = "debugpy";
debuggers = {
debugpy = {
# idk if this is the best way to install/run debugpy
package = pkgs.python3.withPackages (ps: with ps; [debugpy]);
dapConfig = ''
dap.adapters.debugpy = function(cb, config)
if config.request == 'attach' then
---@diagnostic disable-next-line: undefined-field
local port = (config.connect or config).port
---@diagnostic disable-next-line: undefined-field
local host = (config.connect or config).host or '127.0.0.1'
cb({
type = 'server',
port = assert(port, '`connect.port` is required for a python `attach` configuration'),
host = host,
options = {
source_filetype = 'python',
},
})
else
cb({
type = 'executable',
command = '${getExe cfg.dap.package}',
args = { '-m', 'debugpy.adapter' },
options = {
source_filetype = 'python',
},
})
defaultDebugger = ["debugpy"];
dapConfigurations = {
debugpy = [
{
type = "debugpy";
request = "launch";
name = "Launch file";
program = "\${file}";
pythonPath = mkLuaInline ''
function()
-- debugpy supports launching an application with a different interpreter then the one used to launch debugpy itself.
-- The code below looks for a `venv` or `.venv` folder in the current directly and uses the python within.
-- You could adapt this - to for example use the `VIRTUAL_ENV` environment variable.
local cwd = vim.fn.getcwd()
if vim.fn.executable(cwd .. "/venv/bin/python") == 1 then
return cwd .. "/venv/bin/python"
elseif vim.fn.executable(cwd .. "/.venv/bin/python") == 1 then
return cwd .. "/.venv/bin/python"
elseif vim.fn.executable("python") == 1 then
return vim.fn.exepath("python")
else -- this uses the same python package as the debugger
return nil
end
end
end
dap.configurations.python = {
{
-- The first three options are required by nvim-dap
type = 'debugpy'; -- the type here established the link to the adapter definition: `dap.adapters.debugpy`
request = 'launch';
name = "Launch file";
-- Options below are for debugpy, see https://github.com/microsoft/debugpy/wiki/Debug-configuration-settings for supported options
program = "''${file}"; -- This configuration will launch the current file if used.
pythonPath = function()
-- debugpy supports launching an application with a different interpreter then the one used to launch debugpy itself.
-- The code below looks for a `venv` or `.venv` folder in the current directly and uses the python within.
-- You could adapt this - to for example use the `VIRTUAL_ENV` environment variable.
local cwd = vim.fn.getcwd()
if vim.fn.executable(cwd .. '/venv/bin/python') == 1 then
return cwd .. '/venv/bin/python'
elseif vim.fn.executable(cwd .. '/.venv/bin/python') == 1 then
return cwd .. '/.venv/bin/python'
elseif vim.fn.executable("python") == 1 then
return vim.fn.exepath("python")
else -- WARNING cfg.dap.package probably has NO libraries other than builtins and debugpy
return '${getExe cfg.dap.package}'
end
end;
},
}
'';
};
'';
}
];
};
defaultDiagnosticsProvider = ["mypy"];
diagnosticsProviders = ["mypy"];
@ -171,20 +139,10 @@ in {
};
debugger = mkOption {
type = enum (attrNames debuggers);
type = deprecatedSingleOrListOf "vim.languages.python.dap.debugger" (enum (attrNames dapConfigurations));
default = defaultDebugger;
description = "Python debugger to use";
};
package = mkOption {
type = package;
default = debuggers.${cfg.dap.debugger}.package;
example = literalExpression "with pkgs; python39.withPackages (ps: with ps; [debugpy])";
description = ''
Python debugger package.
This is a python package with debugpy installed, see https://nixos.wiki/wiki/Python#Install_Python_Packages.
'';
};
};
extraDiagnostics = {
@ -250,8 +208,11 @@ in {
})
(mkIf cfg.dap.enable {
vim.debugger.nvim-dap.enable = true;
vim.debugger.nvim-dap.sources.python-debugger = debuggers.${cfg.dap.debugger}.dapConfig;
vim.debugger.nvim-dap = {
enable = true;
presets = genAttrs cfg.dap.debugger (_: {enable = true;});
configurations.python = flatten (map (name: dapConfigurations.${name}) cfg.dap.debugger);
};
})
(mkIf cfg.extraDiagnostics.enable {

View file

@ -7,43 +7,39 @@
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption literalExpression;
inherit (lib.modules) mkIf mkMerge mkDefault;
inherit (lib) genAttrs;
inherit (lib.types) bool package enum listOf;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.generators) mkLuaInline;
inherit (lib.attrsets) genAttrs;
inherit (lib.lists) flatten;
inherit (lib.types) bool enum listOf;
inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf enumWithRename;
cfg = config.vim.languages.zig;
defaultServers = ["zls"];
servers = ["zls"];
# TODO: dap.adapter.lldb is duplicated when enabling the
# vim.languages.clang.dap module. This does not cause
# breakage... but could be cleaner.
defaultDebugger = "lldb-vscode";
debuggers = {
lldb-vscode = {
package = pkgs.lldb;
dapConfig = ''
dap.adapters.lldb = {
type = 'executable',
command = '${cfg.dap.package}/bin/lldb-dap',
name = 'lldb'
}
dap.configurations.zig = {
{
name = 'Launch',
type = 'lldb',
request = 'launch',
program = function()
return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
end,
cwd = "''${workspaceFolder}",
stopOnEntry = false,
args = {},
},
}
'';
};
defaultDebugger = ["lldb"];
dapConfigurations = {
lldb = [
{
name = "Launch";
type = "lldb";
request = "launch";
program = mkLuaInline ''
function()
return nvf_dap_cached_input(
'zig_lldb_launch_exe',
'Path to executable: ',
vim.fn.getcwd() .. '/',
'file'
)
end
'';
cwd = "\${workspaceFolder}";
stopOnEntry = false;
args = [];
}
];
};
in {
options.vim.languages.zig = {
@ -83,16 +79,14 @@ in {
};
debugger = mkOption {
type = enum (attrNames debuggers);
type =
deprecatedSingleOrListOf "vim.languages.zig.dap.debugger"
(enumWithRename "vim.languages.zig.dap.debugger" (attrNames dapConfigurations) {
lldb-vscode = "lldb";
});
default = defaultDebugger;
description = "Zig debugger to use";
};
package = mkOption {
type = package;
default = debuggers.${cfg.dap.debugger}.package;
description = "Zig debugger package.";
};
};
};
@ -119,9 +113,10 @@ in {
})
(mkIf cfg.dap.enable {
vim = {
debugger.nvim-dap.enable = true;
debugger.nvim-dap.sources.zig-debugger = debuggers.${cfg.dap.debugger}.dapConfig;
vim.debugger.nvim-dap = {
enable = true;
presets = genAttrs cfg.dap.debugger (_: {enable = true;});
configurations.zig = flatten (map (name: dapConfigurations.${name}) cfg.dap.debugger);
};
})
]);