From d025d14f4ee325bfb51e61960f68984c8041a4d4 Mon Sep 17 00:00:00 2001 From: Wolbyte <79154039+Wolbyte@users.noreply.github.com> Date: Mon, 3 Jul 2023 22:34:46 +0330 Subject: [PATCH] plugins/dap: init + extensions + tests (#455) --- plugins/dap/dap-go.nix | 56 +++++ plugins/dap/dap-python.nix | 83 +++++++ plugins/dap/dap-ui.nix | 228 ++++++++++++++++++ plugins/dap/dap-virtual-text.nix | 91 +++++++ plugins/dap/dapHelpers.nix | 136 +++++++++++ plugins/dap/default.nix | 91 +++++++ plugins/default.nix | 2 + tests/test-sources/plugins/dap/dap-go.nix | 27 +++ tests/test-sources/plugins/dap/dap-python.nix | 45 ++++ tests/test-sources/plugins/dap/dap-ui.nix | 91 +++++++ .../plugins/dap/dap-virtual-text.nix | 32 +++ tests/test-sources/plugins/dap/nvim-dap.nix | 85 +++++++ 12 files changed, 967 insertions(+) create mode 100644 plugins/dap/dap-go.nix create mode 100644 plugins/dap/dap-python.nix create mode 100644 plugins/dap/dap-ui.nix create mode 100644 plugins/dap/dap-virtual-text.nix create mode 100644 plugins/dap/dapHelpers.nix create mode 100644 plugins/dap/default.nix create mode 100644 tests/test-sources/plugins/dap/dap-go.nix create mode 100644 tests/test-sources/plugins/dap/dap-python.nix create mode 100644 tests/test-sources/plugins/dap/dap-ui.nix create mode 100644 tests/test-sources/plugins/dap/dap-virtual-text.nix create mode 100644 tests/test-sources/plugins/dap/nvim-dap.nix diff --git a/plugins/dap/dap-go.nix b/plugins/dap/dap-go.nix new file mode 100644 index 00000000..3e6fb7d6 --- /dev/null +++ b/plugins/dap/dap-go.nix @@ -0,0 +1,56 @@ +{ + pkgs, + config, + lib, + ... +}: +with lib; let + cfg = config.plugins.dap.extensions.dap-go; + helpers = import ../helpers.nix {inherit lib;}; + dapHelpers = import ./dapHelpers.nix {inherit lib;}; +in { + options.plugins.dap.extensions.dap-go = { + enable = mkEnableOption "dap-go"; + + package = helpers.mkPackageOption "dap-go" pkgs.vimPlugins.nvim-dap-go; + + dapConfigurations = helpers.mkNullOrOption (types.listOf dapHelpers.configurationOption) '' + Additional dap configurations. + See `:h dap-configuration` for more detail. + ''; + + delve = { + path = helpers.defaultNullOpts.mkStr "dlv" "The path to the executable dlv which will be used for debugging."; + + initializeTimeoutSec = helpers.defaultNullOpts.mkInt 20 "Time to wait for delve to initialize the debug session."; + + port = helpers.defaultNullOpts.mkStr "$\{port}" '' + A string that defines the port to start delve debugger. + Defaults to string "$\{port}" which instructs dap + to start the process in a random available port. + ''; + + args = helpers.mkNullOrOption (types.listOf types.str) "Additional args to pass to dlv."; + }; + }; + + config = let + options = with cfg; { + dap_configurations = dapConfigurations; + + delve = with delve; { + inherit path port args; + initialize_timeout_sec = initializeTimeoutSec; + }; + }; + in + mkIf cfg.enable { + extraPlugins = [cfg.package]; + + plugins.dap.enable = true; + + extraConfigLua = '' + require("dap-go").setup(${helpers.toLuaObject options}) + ''; + }; +} diff --git a/plugins/dap/dap-python.nix b/plugins/dap/dap-python.nix new file mode 100644 index 00000000..b05da95c --- /dev/null +++ b/plugins/dap/dap-python.nix @@ -0,0 +1,83 @@ +{ + pkgs, + config, + lib, + ... +}: +with lib; let + cfg = config.plugins.dap.extensions.dap-python; + helpers = import ../helpers.nix {inherit lib;}; + dapHelpers = import ./dapHelpers.nix {inherit lib;}; +in { + options.plugins.dap.extensions.dap-python = { + enable = mkEnableOption "dap-python"; + + package = helpers.mkPackageOption "dap-python" pkgs.vimPlugins.nvim-dap-python; + + adapterPythonPath = mkOption { + default = "${pkgs.python3}/bin/python3"; + description = "Path to the python interpreter. Path must be absolute or in $PATH and needs to have the debugpy package installed."; + type = types.str; + }; + + console = helpers.defaultNullOpts.mkEnumFirstDefault ["integratedTerminal" "internalConsole" "externalTerminal"] "Debugpy console."; + + customConfigurations = helpers.mkNullOrOption (types.listOf dapHelpers.configurationOption) "Custom python configurations for dap."; + + includeConfigs = helpers.defaultNullOpts.mkBool true "Add default configurations."; + + resolvePython = helpers.mkNullOrOption types.str '' + Function to resolve path to python to use for program or test execution. + By default the `VIRTUAL_ENV` and `CONDA_PREFIX` environment variables are used if present. + ''; + + testRunner = helpers.mkNullOrOption (types.either types.str helpers.rawType) '' + The name of test runner to use by default. + The default value is dynamic and depends on `pytest.ini` or `manage.py` markers. + If neither is found "unittest" is used. + ''; + + testRunners = helpers.mkNullOrOption (types.attrsOf types.str) '' + Set to register test runners. + 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|. + ''; + }; + + config = let + options = with cfg; { + inherit console; + include_configs = includeConfigs; + }; + in + mkIf cfg.enable { + extraPlugins = [cfg.package]; + + plugins.dap.enable = true; + + extraConfigLua = with helpers; + '' + require("dap-python").setup("${cfg.adapterPythonPath}", ${toLuaObject options}) + '' + + (optionalString (cfg.testRunners != null) '' + table.insert(require("dap-python").test_runners, + ${ + toLuaObject + ( + builtins.mapAttrs (_: mkRaw) cfg.testRunners + ) + }) + '') + + (optionalString (cfg.customConfigurations != null) '' + table.insert(require("dap").configurations.python, ${toLuaObject cfg.customConfigurations}) + '') + + (optionalString (cfg.resolvePython != null) '' + require("dap-python").resolve_python = ${toLuaObject (mkRaw cfg.resolvePython)} + '') + + (optionalString (cfg.testRunner != null) '' + require("dap-python").test_runner = ${toLuaObject cfg.testRunner}; + ''); + }; +} diff --git a/plugins/dap/dap-ui.nix b/plugins/dap/dap-ui.nix new file mode 100644 index 00000000..8b6c65cb --- /dev/null +++ b/plugins/dap/dap-ui.nix @@ -0,0 +1,228 @@ +{ + pkgs, + config, + lib, + ... +}: +with lib; let + cfg = config.plugins.dap.extensions.dap-ui; + helpers = import ../helpers.nix {inherit lib;}; + + mkSizeOption = + helpers.mkNullOrOption + ( + with types; + either int (numbers.between 0.0 1.0) + ); + + mkKeymapOptions = name: + mapAttrs ( + key: default: + helpers.defaultNullOpts.mkNullable (with types; either str (listOf str)) "${default}" "Map `${key}` for ${name}" + ); + + elementOption = types.submodule { + options = { + id = helpers.mkNullOrOption types.str "Element ID."; + + size = mkSizeOption "Size of the element in lines/columns or as proportion of total editor size (0-1)."; + }; + }; + + layoutOption = types.submodule { + options = { + elements = mkOption { + default = []; + description = "Elements to display in this layout."; + type = with types; listOf (either str elementOption); + }; + + size = mkOption { + default = 10; + description = "Size of the layout in lines/columns."; + type = types.int; + }; + + position = mkOption { + default = "left"; + description = "Which side of editor to open layout on."; + type = types.enum ["left" "right" "top" "bottom"]; + }; + }; + }; +in { + options.plugins.dap.extensions.dap-ui = + helpers.extraOptionsOptions + // { + enable = mkEnableOption "dap-ui"; + + package = helpers.mkPackageOption "dap-ui" pkgs.vimPlugins.nvim-dap-ui; + + controls = helpers.mkCompositeOption "Options for dap-ui controls." { + enabled = helpers.defaultNullOpts.mkBool true "Enable controls"; + + element = + helpers.defaultNullOpts.mkEnumFirstDefault ["repl" "scopes" "stacks" "watches" "breakpoints" "console"] + "Element to show the controls on."; + + icons = { + disconnect = helpers.defaultNullOpts.mkStr "" ""; + pause = helpers.defaultNullOpts.mkStr "" ""; + play = helpers.defaultNullOpts.mkStr "" ""; + run_last = helpers.defaultNullOpts.mkStr "" ""; + step_into = helpers.defaultNullOpts.mkStr "" ""; + step_over = helpers.defaultNullOpts.mkStr "" ""; + step_out = helpers.defaultNullOpts.mkStr "" ""; + step_back = helpers.defaultNullOpts.mkStr "" ""; + terminate = helpers.defaultNullOpts.mkStr "" ""; + }; + }; + + elementMappings = helpers.mkNullOrOption ( + types.attrsOf ( + types.submodule { + options = mkKeymapOptions "element mapping overrides" { + edit = "e"; + expand = ''["" "<2-LeftMouse>"]''; + open = "o"; + remove = "d"; + repl = "r"; + toggle = "t"; + }; + } + ) + ) "Per-element overrides of global mappings."; + + expandLines = helpers.defaultNullOpts.mkBool true "Expand current line to hover window if larger than window size."; + + floating = { + maxHeight = mkSizeOption "Maximum height of the floating window."; + + maxWidth = mkSizeOption "Maximum width of the floating window."; + + border = helpers.defaultNullOpts.mkBorder "single" "dap-ui floating window" ""; + + mappings = + helpers.mkNullOrOption (types.submodule { + options = mkKeymapOptions "dap-ui floating" { + close = ''["" "q"]''; + }; + }) + "Keys to trigger actions in elements."; + }; + + forceBuffers = helpers.defaultNullOpts.mkBool true "Prevents other buffers being loaded into dap-ui windows."; + + icons = { + collapsed = helpers.defaultNullOpts.mkStr "" ""; + current_frame = helpers.defaultNullOpts.mkStr "" ""; + expanded = helpers.defaultNullOpts.mkStr "" ""; + }; + + layouts = + helpers.defaultNullOpts.mkNullable (types.listOf layoutOption) + '' + ``` + [ + { + elements = [ + { + id = "scopes"; + size = 0.25; + } + { + id = "breakpoints"; + size = 0.25; + } + { + id = "stacks"; + size = 0.25; + } + { + id = "watches"; + size = 0.25; + } + ]; + position = "left"; + size = 40; + } + { + elements = [ + { + id = "repl"; + size = 0.5; + } + { + id = "console"; + size = 0.5; + } + ]; + position = "bottom"; + size = 10; + } + ]; + ``` + '' + "List of layouts for dap-ui."; + + mappings = + helpers.mkNullOrOption (types.submodule { + options = mkKeymapOptions "dap-ui" { + edit = "e"; + expand = ''["" "<2-LeftMouse>"]''; + open = "o"; + remove = "d"; + repl = "r"; + toggle = "t"; + }; + }) + "Keys to trigger actions in elements."; + + render = helpers.mkCompositeOption "Rendering options which can be updated after initial setup." { + indent = helpers.defaultNullOpts.mkInt 1 "Default indentation size."; + + maxTypeLength = helpers.mkNullOrOption types.int "Maximum number of characters to allow a type name to fill before trimming."; + + maxValueLines = helpers.defaultNullOpts.mkInt 100 "Maximum number of lines to allow a value to fill before trimming."; + }; + + selectWindow = helpers.mkNullOrOption types.str '' + A function which returns a window to be used for opening buffers such as a stack frame location. + ''; + }; + + config = let + options = with cfg; + { + inherit controls icons layouts mappings; + + element_mappings = elementMappings; + + floating = with floating; { + inherit border mappings; + max_height = maxHeight; + max_width = maxWidth; + }; + + force_buffers = forceBuffers; + + render = helpers.ifNonNull' render (with render; { + inherit indent; + max_type_length = maxTypeLength; + max_value_lines = maxValueLines; + }); + + select_window = helpers.ifNonNull' selectWindow (helpers.mkRaw selectWindow); + } + // cfg.extraOptions; + in + mkIf cfg.enable { + extraPlugins = [cfg.package]; + + plugins.dap.enable = true; + + extraConfigLua = '' + require("dapui").setup(${helpers.toLuaObject options}); + ''; + }; +} diff --git a/plugins/dap/dap-virtual-text.nix b/plugins/dap/dap-virtual-text.nix new file mode 100644 index 00000000..6d91de08 --- /dev/null +++ b/plugins/dap/dap-virtual-text.nix @@ -0,0 +1,91 @@ +{ + pkgs, + config, + lib, + ... +}: +with lib; let + cfg = config.plugins.dap.extensions.dap-virtual-text; + helpers = import ../helpers.nix {inherit lib;}; +in { + options.plugins.dap.extensions.dap-virtual-text = { + enable = mkEnableOption "dap-virtual-text"; + + package = helpers.mkPackageOption "dap-virtual-text" pkgs.vimPlugins.nvim-dap-virtual-text; + + enabledCommands = helpers.defaultNullOpts.mkBool true '' + Create commands `DapVirtualTextEnable`, `DapVirtualTextDisable`, `DapVirtualTextToggle`. + (`DapVirtualTextForceRefresh` for refreshing when debug adapter did not notify its termination). + ''; + + highlightChangedVariables = helpers.defaultNullOpts.mkBool true '' + Highlight changed values with `NvimDapVirtualTextChanged`, else always `NvimDapVirtualText`. + ''; + + highlightNewAsChanged = helpers.defaultNullOpts.mkBool false '' + Highlight new variables in the same way as changed variables (if highlightChangedVariables). + ''; + + showStopReason = helpers.defaultNullOpts.mkBool true "Show stop reason when stopped for exceptions."; + + commented = helpers.defaultNullOpts.mkBool false "Prefix virtual text with comment string."; + + onlyFirstDefinition = helpers.defaultNullOpts.mkBool true "Only show virtual text at first definition (if there are multiple)."; + + allReferences = helpers.defaultNullOpts.mkBool false "Show virtual text on all all references of the variable (not only definitions)."; + + clearOnContinue = helpers.defaultNullOpts.mkBool false "Clear virtual text on `continue` (might cause flickering when stepping)."; + + displayCallback = helpers.defaultNullOpts.mkStr '' + function(variable, buf, stackframe, node, options) + if options.virt_text_pos == 'inline' then + return ' = ' .. variable.value + else + return variable.name .. ' = ' .. variable.value + end + end, + '' "A callback that determines how a variable is displayed or whether it should be omitted."; + + virtTextPos = helpers.defaultNullOpts.mkStr "vim.fn.has 'nvim-0.10' == 1 and 'inline' or 'eol'" '' + Position of virtual text, see `:h nvim_buf_set_extmark()`. + Default tries to inline the virtual text. Use 'eol' to set to end of line. + ''; + + allFrames = helpers.defaultNullOpts.mkBool false "Show virtual text for all stack frames not only current."; + + virtLines = helpers.defaultNullOpts.mkBool false "Show virtual lines instead of virtual text (will flicker!)."; + + virtTextWinCol = helpers.mkNullOrOption types.int '' + Position the virtual text at a fixed window column (starting from the first text column). + See `:h nvim_buf_set_extmark()`. + ''; + }; + + config = let + options = with cfg; { + inherit commented; + + enabled_commands = enabledCommands; + highlight_changed_variables = highlightChangedVariables; + highlight_new_as_changed = highlightNewAsChanged; + show_stop_reason = showStopReason; + only_first_definition = onlyFirstDefinition; + all_references = allReferences; + clear_on_continue = clearOnContinue; + display_callback = helpers.ifNonNull' displayCallback (helpers.mkRaw displayCallback); + virt_text_pos = virtTextPos; + all_frames = allFrames; + virt_lines = virtLines; + virt_text_win_col = virtTextWinCol; + }; + in + mkIf cfg.enable { + extraPlugins = [cfg.package]; + + plugins.dap.enable = true; + + extraConfigLua = '' + require("nvim-dap-virtual-text").setup(${helpers.toLuaObject options}); + ''; + }; +} diff --git a/plugins/dap/dapHelpers.nix b/plugins/dap/dapHelpers.nix new file mode 100644 index 00000000..64afb001 --- /dev/null +++ b/plugins/dap/dapHelpers.nix @@ -0,0 +1,136 @@ +{lib, ...}: +with lib; let + helpers = import ../helpers.nix {inherit lib;}; +in rec { + mkAdapterType = attrs: + types.submodule { + options = + { + id = helpers.mkNullOrOption types.str '' + Identifier of the adapter. This is used for the + `adapterId` property of the initialize request. + For most debug adapters setting this is not necessary. + ''; + + enrichConfig = helpers.mkNullOrOption types.str '' + A lua function (`func(config, on_config)`) which allows an adapter to enrich a + configuration with additional information. It receives a configuration as first + argument, and a callback that must be called with the final configuration as second argument. + ''; + + options = { + initializeTimeoutSec = helpers.defaultNullOpts.mkInt 4 '' + How many seconds the client waits for a response on a initialize request before emitting a warning. + ''; + + disconnectTimeoutSec = helpers.defaultNullOpts.mkInt 3 '' + How many seconds the client waits for a disconnect response from the debug + adapter before emitting a warning and closing the connection. + ''; + + sourceFiletype = helpers.mkNullOrOption types.str '' + The filetype to use for content retrieved via a source request. + ''; + }; + } + // attrs; + }; + + executableAdapterOption = mkAdapterType { + command = helpers.mkNullOrOption types.str "The command to invoke."; + + args = helpers.mkNullOrOption (types.listOf types.str) "Arguments for the command."; + + options = { + env = helpers.mkNullOrOption types.attrs "Set the environment variables for the command."; + + cwd = helpers.mkNullOrOption types.str "Set the working directory for the command."; + + detached = helpers.defaultNullOpts.mkBool true "Start the debug adapter in a detached state."; + }; + }; + + serverAdapterOption = mkAdapterType { + host = helpers.defaultNullOpts.mkStr "127.0.0.1" "Host to connect to."; + + port = helpers.mkNullOrOption (types.either types.int (types.enum ["$\{port}"])) '' + Port to connect to. + If "$\{port}" dap resolves a free port. + This is intended to be used with `executable.args`. + ''; + + executable = { + command = helpers.mkNullOrOption types.str "Command that spawns the adapter."; + + args = helpers.mkNullOrOption (types.listOf types.str) "Command arguments."; + + detached = helpers.defaultNullOpts.mkBool true "Spawn the debug adapter in detached state."; + + cwd = helpers.mkNullOrOption types.str "Working directory."; + }; + + options.maxRetries = helpers.defaultNullOpts.mkInt 14 '' + Amount of times the client should attempt to connect before erroring out. + There is a 250ms delay between each retry. + ''; + }; + + mkAdapterOption = name: type: + helpers.mkNullOrOption (with types; attrsOf (either str type)) '' + Debug adapters of `${name}` type. + The adapters can also be set to a function which takes three arguments: + + - A `on_config` callback. This must be called with the actual adapter table. + - The |dap-configuration| which the user wants to use. + - An optional parent session. This is only available if the debug-adapter + wants to start a child-session via a `startDebugging` request. + + This can be used to defer the resolving of the values to when a configuration + is used. A use-case for this is starting an adapter asynchronous. + ''; + + configurationOption = types.submodule { + freeformType = types.attrs; + + options = { + type = mkOption { + description = "Which debug adapter to use."; + type = types.str; + }; + + request = mkOption { + type = types.enum ["attach" "launch"]; + description = '' + Indicates whether the debug adapter should launch a debugee or attach to one that is already running. + ''; + }; + + name = mkOption { + type = types.str; + description = "A user readable name for the configuration."; + }; + }; + }; + + mkSignOption = default: desc: { + text = helpers.defaultNullOpts.mkStr default desc; + texthl = helpers.mkNullOrOption types.str "`texthl` for sign."; + linehl = helpers.mkNullOrOption types.str "`linehl` for sign."; + numhl = helpers.mkNullOrOption types.str "`numhl` for sign."; + }; + + processAdapters = type: adapters: + with builtins; + mapAttrs (_: adapter: + if typeOf adapter == "string" + then helpers.mkRaw adapter + else + filterAttrs (n: _: n != "enrichConfig") ( + adapter + // { + inherit type; + enrich_config = helpers.ifNonNull' adapter.enrichConfig (helpers.mkRaw adapter.enrichConfig); + } + )) + adapters; +} diff --git a/plugins/dap/default.nix b/plugins/dap/default.nix new file mode 100644 index 00000000..4fca5f00 --- /dev/null +++ b/plugins/dap/default.nix @@ -0,0 +1,91 @@ +{ + pkgs, + config, + lib, + ... +}: +with lib; let + cfg = config.plugins.dap; + helpers = import ../helpers.nix {inherit lib;}; + dapHelpers = import ./dapHelpers.nix {inherit lib;}; +in + with dapHelpers; { + imports = [ + ./dap-go.nix + ./dap-python.nix + ./dap-ui.nix + ./dap-virtual-text.nix + ]; + + options.plugins.dap = + helpers.extraOptionsOptions + // { + enable = mkEnableOption "dap"; + + package = helpers.mkPackageOption "dap" pkgs.vimPlugins.nvim-dap; + + adapters = helpers.mkCompositeOption "Dap adapters." { + executables = mkAdapterOption "executable" executableAdapterOption; + servers = mkAdapterOption "server" serverAdapterOption; + }; + + configurations = helpers.mkNullOrOption (with types; attrsOf (listOf dapHelpers.configurationOption)) '' + Debugee configurations, see `:h dap-configuration` for more info. + ''; + + signs = helpers.mkCompositeOption "Signs for dap." { + dapBreakpoint = mkSignOption "B" "Sign for breakpoints."; + + dapBreakpointCondition = mkSignOption "C" "Sign for conditional breakpoints."; + + dapLogPoint = mkSignOption "L" "Sign for log points."; + + dapStopped = mkSignOption "→" "Sign to indicate where the debugee is stopped."; + + dapBreakpointRejected = mkSignOption "R" "Sign to indicate breakpoints rejected by the debug adapter."; + }; + }; + + config = let + options = with cfg; + { + inherit configurations; + + adapters = + ( + lib.optionalAttrs (adapters.executables != null) + (processAdapters "executable" adapters.executables) + ) + // ( + lib.optionalAttrs (adapters.servers != null) + (processAdapters "server" adapters.servers) + ); + + signs = with signs; { + DapBreakpoint = dapBreakpoint; + DapBreakpointCondition = dapBreakpointCondition; + DapLogPoint = dapLogPoint; + DapStopped = dapStopped; + DapBreakpointRejected = dapBreakpointRejected; + }; + } + // cfg.extraOptions; + in + mkIf cfg.enable { + extraPlugins = [cfg.package]; + + extraConfigLua = + (optionalString (cfg.adapters != null) '' + require("dap").adapters = ${helpers.toLuaObject options.adapters} + '') + + (optionalString (options.configurations != null) '' + require("dap").configurations = ${helpers.toLuaObject options.configurations} + '') + + (optionalString (cfg.signs != null) '' + local __dap_signs = ${helpers.toLuaObject options.signs} + for sign_name, sign in pairs(__dap_signs) do + vim.fn.sign_define(sign_name, sign) + end + ''); + }; + } diff --git a/plugins/default.nix b/plugins/default.nix index 092518c3..a439ba6f 100644 --- a/plugins/default.nix +++ b/plugins/default.nix @@ -64,6 +64,8 @@ ./null-ls + ./dap + ./pluginmanagers/packer.nix ./snippets/luasnip diff --git a/tests/test-sources/plugins/dap/dap-go.nix b/tests/test-sources/plugins/dap/dap-go.nix new file mode 100644 index 00000000..c31ed063 --- /dev/null +++ b/tests/test-sources/plugins/dap/dap-go.nix @@ -0,0 +1,27 @@ +{ + empty = { + plugins.dap.extensions.dap-go.enable = true; + }; + + default = { + plugins.dap.extensions.dap-go = { + enable = true; + + dapConfigurations = [ + { + # Must be "go" or it will be ignored by the plugin + type = "go"; + name = "Attach remote"; + mode = "remote"; + request = "attach"; + } + ]; + delve = { + path = "dlv"; + initializeTimeoutSec = 20; + port = "$\{port}"; + args = []; + }; + }; + }; +} diff --git a/tests/test-sources/plugins/dap/dap-python.nix b/tests/test-sources/plugins/dap/dap-python.nix new file mode 100644 index 00000000..7ef06cb3 --- /dev/null +++ b/tests/test-sources/plugins/dap/dap-python.nix @@ -0,0 +1,45 @@ +{ + empty = { + plugins.dap.extensions.dap-python.enable = true; + }; + + example = { + plugins.dap.extensions.dap-python = { + enable = true; + + customConfigurations = [ + { + type = "python"; + request = "launch"; + name = "My custom launch configuration"; + program = "$\{file}"; + # ... more options; see https://github.com/microsoft/debugpy/wiki/Debug-configuration-settings + } + ]; + resolvePython = '' + function() + return "/absolute/path/to/python" + end + ''; + testRunner = "customTestRunner"; + testRunners = { + customTestRunner = '' + function(classname, methodname, opts) + local args = {classname, methodname} + return 'modulename', args + end + ''; + }; + }; + }; + + default = { + plugins.dap.extensions.dap-python = { + enable = true; + + console = "integratedTerminal"; + includeConfigs = true; + adapterPythonPath = "python3"; + }; + }; +} diff --git a/tests/test-sources/plugins/dap/dap-ui.nix b/tests/test-sources/plugins/dap/dap-ui.nix new file mode 100644 index 00000000..ddf5bc98 --- /dev/null +++ b/tests/test-sources/plugins/dap/dap-ui.nix @@ -0,0 +1,91 @@ +{ + empty = { + plugins.dap.extensions.dap-ui.enable = true; + }; + + default = { + plugins.dap.extensions.dap-ui = { + enable = true; + + controls = { + element = "repl"; + enabled = true; + icons = { + disconnect = ""; + pause = ""; + play = ""; + run_last = ""; + step_back = ""; + step_into = ""; + step_out = ""; + step_over = ""; + terminate = ""; + }; + }; + elementMappings = {}; + expandLines = true; + floating = { + border = "single"; + mappings = { + close = ["q" ""]; + }; + }; + forceBuffers = true; + icons = { + collapsed = ""; + current_frame = ""; + expanded = ""; + }; + layouts = [ + { + elements = [ + { + id = "scopes"; + size = 0.25; + } + { + id = "breakpoints"; + size = 0.25; + } + { + id = "stacks"; + size = 0.25; + } + { + id = "watches"; + size = 0.25; + } + ]; + position = "left"; + size = 40; + } + { + elements = [ + { + id = "repl"; + size = 0.5; + } + { + id = "console"; + size = 0.5; + } + ]; + position = "bottom"; + size = 10; + } + ]; + mappings = { + edit = "e"; + expand = ["" "<2-LeftMouse>"]; + open = "o"; + remove = "d"; + repl = "r"; + toggle = "t"; + }; + render = { + indent = 1; + maxValueLines = 100; + }; + }; + }; +} diff --git a/tests/test-sources/plugins/dap/dap-virtual-text.nix b/tests/test-sources/plugins/dap/dap-virtual-text.nix new file mode 100644 index 00000000..6312453e --- /dev/null +++ b/tests/test-sources/plugins/dap/dap-virtual-text.nix @@ -0,0 +1,32 @@ +{ + empty = { + plugins.dap.extensions.dap-virtual-text.enable = true; + }; + + default = { + plugins.dap.extensions.dap-virtual-text = { + enable = true; + + enabledCommands = true; + highlightChangedVariables = true; + highlightNewAsChanged = true; + showStopReason = true; + commented = false; + onlyFirstDefinition = true; + allReferences = false; + clearOnContinue = false; + displayCallback = '' + function(variable, buf, stackframe, node, options) + if options.virt_text_pos == 'inline' then + return ' = ' .. variable.value + else + return variable.name .. ' = ' .. variable.value + end + end + ''; + virtTextPos = "eol"; + allFrames = false; + virtLines = false; + }; + }; +} diff --git a/tests/test-sources/plugins/dap/nvim-dap.nix b/tests/test-sources/plugins/dap/nvim-dap.nix new file mode 100644 index 00000000..d53f3d6a --- /dev/null +++ b/tests/test-sources/plugins/dap/nvim-dap.nix @@ -0,0 +1,85 @@ +{ + empty = { + plugins.dap.enable = true; + }; + + example = { + plugins.dap = { + enable = true; + + adapters = { + executables = { + python = { + command = ".virtualenvs/tools/bin/python"; + args = ["-m" "debugpy.adapter"]; + }; + }; + servers = { + java = '' + function(callback, config) + M.execute_command({command = 'vscode.java.startDebugSession'}, function(err0, port) + assert(not err0, vim.inspect(err0)) + callback({ type = 'server'; host = '127.0.0.1'; port = port; }) + end) + end + ''; + javaEnriched = { + host = "127.0.0.1"; + port = 8080; + enrichConfig = '' + function(config, on_config) + local final_config = vim.deepcopy(config) + final_config.extra_property = 'This got injected by the adapter' + on_config(final_config) + end + ''; + }; + }; + }; + configurations = { + python = [ + { + type = "python"; + request = "launch"; + name = "Launch file"; + program = "$\{file}"; + } + ]; + }; + }; + }; + + default = { + plugins.dap = { + enable = true; + + adapters = { + executables = {}; + servers = {}; + }; + configurations = {}; + signs = { + dapStopped = { + text = "→"; + texthl = "DiagnosticWarn"; + }; + dapBreakpoint = { + text = "B"; + texthl = "DiagnosticInfo"; + }; + dapBreakpointRejected = { + text = "R"; + texthl = "DiagnosticError"; + }; + dapBreakpointCondition = { + text = "C"; + texthl = "DiagnosticInfo"; + }; + dapLogPoint = { + text = "L"; + texthl = "DiagnosticInfo"; + }; + }; + }; + }; +}