From d5b2ba8f2ae56b692d185bf3ac80a83c67dd4813 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Thu, 11 Dec 2025 15:24:37 -0600 Subject: [PATCH] plugins/dap: allow lua for adapters Support `mkRaw` for adapter definitions to support more flexible configuration. --- plugins/by-name/dap/dapHelpers.nix | 10 ++- plugins/by-name/dap/default.nix | 76 +++++++++++++++++-- .../plugins/by-name/dap/default.nix | 38 +++++++++- 3 files changed, 112 insertions(+), 12 deletions(-) diff --git a/plugins/by-name/dap/dapHelpers.nix b/plugins/by-name/dap/dapHelpers.nix index 05095008..1f3d7ad6 100644 --- a/plugins/by-name/dap/dapHelpers.nix +++ b/plugins/by-name/dap/dapHelpers.nix @@ -98,7 +98,11 @@ rec { mkAdapterOption = name: type: - mkNullOrOption (with types; attrsOf (either str type)) '' + let + # TODO: Added 2025-12-11 (26.05) + strToRawLua = lib.nixvim.deprecation.transitionType types.str lib.nixvim.mkRaw types.rawLua; + in + mkNullOrOption (with types; attrsOf (either strToRawLua type)) '' Debug adapters of `${name}` type. The adapters can also be set to a function which takes three arguments: @@ -150,8 +154,8 @@ rec { type: adapters: lib.mapAttrs ( _: adapter: - if builtins.isString adapter then - lib.nixvim.mkRaw adapter + if lib.types.isRawType adapter then + adapter else lib.filterAttrs (n: _: n != "enrichConfig") ( adapter diff --git a/plugins/by-name/dap/default.nix b/plugins/by-name/dap/default.nix index dfd51b5a..d8bcbfa0 100644 --- a/plugins/by-name/dap/default.nix +++ b/plugins/by-name/dap/default.nix @@ -22,10 +22,64 @@ lib.nixvim.plugins.mkNeovimPlugin { deprecateExtraOptions = true; extraOptions = { - adapters = lib.nixvim.mkCompositeOption "Dap adapters." { - executables = dapHelpers.mkAdapterOption "executable" dapHelpers.executableAdapterOption; - servers = dapHelpers.mkAdapterOption "server" dapHelpers.serverAdapterOption; - pipes = dapHelpers.mkAdapterOption "pipe" dapHelpers.pipeAdapterOption; + adapters = lib.nixvim.mkNullOrOption' { + type = types.submodule { + freeformType = types.attrsOf types.rawLua; + options = { + executables = dapHelpers.mkAdapterOption "executable" dapHelpers.executableAdapterOption; + servers = dapHelpers.mkAdapterOption "server" dapHelpers.serverAdapterOption; + pipes = dapHelpers.mkAdapterOption "pipe" dapHelpers.pipeAdapterOption; + }; + }; + description = '' + Debug Adapter Protocol adapters. + + Adapters can be defined as dynamic functions or categorized structured configs. + See `Example` for usage patterns. + ''; + example = lib.literalExpression '' + { + # Dynamic adapter using raw lua function + # Useful when adapter type is determined at runtime + python.__raw = ''' + 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 godot `attach` configuration'), + host = host, + options = { + source_filetype = 'gdscript', + }, + }) + else + cb({ + type = 'executable', + command = 'godot', + args = { '--path', config.project_path or vim.fn.getcwd(), '--remote-debug', '127.0.0.1:6006' }, + options = { + source_filetype = 'gdscript', + }, + }) + end + end + '''; + + # Categorized structured config for executable adapter + executables.python = { + command = "python"; + args = [ "-m" "debugpy" ]; + }; + + # Categorized structured config for server adapter + servers.netcoredbg = { + port = 4711; + executable.command = "netcoredbg"; + }; + } + ''; }; configurations = @@ -64,16 +118,22 @@ lib.nixvim.plugins.mkNeovimPlugin { options = { inherit (cfg) configurations; - adapters = + adapters = lib.mkMerge [ + (lib.removeAttrs (cfg.adapters or { }) [ + "executables" + "servers" + "pipes" + ]) (lib.optionalAttrs (cfg.adapters.executables != null) ( dapHelpers.processAdapters "executable" cfg.adapters.executables )) - // (lib.optionalAttrs (cfg.adapters.servers != null) ( + (lib.optionalAttrs (cfg.adapters.servers != null) ( dapHelpers.processAdapters "server" cfg.adapters.servers )) - // (lib.optionalAttrs (cfg.adapters.pipes != null) ( + (lib.optionalAttrs (cfg.adapters.pipes != null) ( dapHelpers.processAdapters "pipe" cfg.adapters.pipes - )); + )) + ]; signs = with cfg.signs; { DapBreakpoint = dapBreakpoint; diff --git a/tests/test-sources/plugins/by-name/dap/default.nix b/tests/test-sources/plugins/by-name/dap/default.nix index 3794facb..fb2cedcd 100644 --- a/tests/test-sources/plugins/by-name/dap/default.nix +++ b/tests/test-sources/plugins/by-name/dap/default.nix @@ -8,14 +8,50 @@ enable = true; adapters = { + python.__raw = '' + 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 = 'path/to/virtualenvs/debugpy/bin/python', + args = { '-m', 'debugpy.adapter' }, + options = { + source_filetype = 'python', + }, + }) + end + end + ''; + executables = { - python = { + pythonStructured = { command = ".virtualenvs/tools/bin/python"; args = [ "-m" "debugpy.adapter" ]; }; + lldb.__raw = '' + function(on_config, config) + local command = config.lldbCommand or "lldb-vscode" + on_config({ + type = "executable", + command = command, + name = "lldb", + }) + end + ''; }; servers = { java = ''