This commit is contained in:
Ching Pei Yang 2026-06-13 02:20:46 +02:00 committed by GitHub
commit 96eccb8636
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 365 additions and 68 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,12 @@ 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.
'')
]
];
}

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,22 @@ in {
nvim-dap = entryAnywhere ''
local dap = require("dap")
vim.fn.sign_define("DapBreakpoint", { text = "🛑", texthl = "ErrorMsg", linehl = "", numhl = "" })
${
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,236 @@
...
}: 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
'';
};
};
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.
'';
};
};
};
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)
'';
};
};
};
};
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
'';
};
};
};
};
configurationType = submodule {
freeformType = attrsOf anything;
options = {
type = mkOption {
type = str;
description = "Which debug adapter to use";
};
request = mkOption {
type = str;
description = ''
Either `attach` or `launch`. Indicates whether the debug adapter
should launch a debugee 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 +246,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 +259,27 @@ in {
type = attrsOf str;
};
adapters = mkOption {
type = attrsOf (oneOf [
execAdapterType
serverAdapterType
pipeAdapterType
luaInline
]);
default = {};
description = "Adapter configurations. See `:help dap-adapter`";
};
configurations = mkOption {
type = attrsOf (listOf configurationType);
default = {};
description = ''
Mapping of filetype to list of possible `Configuration`.
See `:help dap-configuration`.
'';
};
mappings = {
continue = mkMappingOption "Continue" "<leader>dc";
restart = mkMappingOption "Restart" "<leader>dR";

View file

@ -0,0 +1,5 @@
{
imports = [
./lldb.nix
];
}

View file

@ -0,0 +1,22 @@
{
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 "LLDB debugger using lldb-dap";
};
config.vim.debugger.nvim-dap.adapters = mkIf cfg.enable {
lldb = {
type = "executable";
command = "${pkgs.lldb}/bin/lldb-dap";
};
};
}

View file

@ -6,7 +6,7 @@
}: 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;
@ -14,38 +14,32 @@
inherit (lib.generators) mkLuaInline;
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";
defaultDebugger = ["lldb"];
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
'';
lldb = let
configuration = {
name = "Launch";
type = "lldb";
request = "launch";
program = mkLuaInline ''
function()
return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/", "file")
end
'';
cwd = "\${workspaceFolder}";
stopOnEntry = false;
args = {};
};
in {
c = [configuration];
cpp = [configuration];
};
};
@ -147,14 +141,13 @@ in {
};
debugger = mkOption {
description = "clang debugger to use";
type = enum (attrNames debuggers);
type =
deprecatedSingleOrListOf "vim.langauges.clang.dap.debugger"
(enumWithRename "vim.langauges.clang.dap.debugger" (attrNames debuggers) {
lldb-vscode = "lldb";
});
default = defaultDebugger;
};
package = mkOption {
description = "clang debugger package.";
type = package;
default = debuggers.${cfg.dap.debugger}.package;
};
};
format = {
@ -208,8 +201,11 @@ 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 = {
enable = true;
presets.lldb.enable = true;
configurations = mkMerge (map (name: debuggers.${name}) cfg.dap.debugger);
};
})
(mkIf cfg.format.enable {

View file

@ -7,42 +7,34 @@
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption literalExpression;
inherit (lib.modules) mkIf mkMerge mkDefault;
inherit (lib.generators) mkLuaInline;
inherit (lib) genAttrs;
inherit (lib.types) bool package enum listOf;
inherit (lib.nvim.types) mkGrammarOption;
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";
defaultDebugger = ["lldb"];
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()
lldb = {
zig = [
{
name = "Launch";
type = "lldb";
request = "launch";
program = mkLuaInline ''
function()
return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
end,
cwd = "''${workspaceFolder}",
stopOnEntry = false,
args = {},
},
end
'';
cwd = "\${workspaceFolder}";
stopOnEntry = false;
args = {};
}
'';
];
};
};
in {
@ -83,7 +75,11 @@ in {
};
debugger = mkOption {
type = enum (attrNames debuggers);
type =
deprecatedSingleOrListOf "vim.langauges.zig.dap.debugger"
(enumWithRename "vim.langauges.zig.dap.debugger" (attrNames debuggers) {
lldb-vscode = "lldb";
});
default = defaultDebugger;
description = "Zig debugger to use";
};
@ -119,9 +115,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.lldb.enable = true;
configurations = mkMerge (map (name: debuggers.${name}) cfg.dap.debugger);
};
})
]);