Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic user input resolution during session launch (similar to VS Code) #816

Closed
dasupradyumna opened this issue Jan 10, 2023 · 3 comments
Closed

Comments

@dasupradyumna
Copy link

Problem Statement

Hey Mathias!

I have been using this plugin for a while now (primarily, for python and c++), and I love the simplicity and the flexibility that it provides so far. But there has been one feature that (I feel) is missing, which I believe is a frequent use case.
The ${input:<variable>} feature from VSCode, which allows the user to either type out their input as a string or select one from a list of pre-defined options when a debug session is being launched. I understand that this feature is already doable to an extent, using the coroutine technique that you have mentioned in #629, but limited to a single function per field in a configuration table, or requires more lua gymnastics to configure.

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug target script",
      "type": "python",
      "request": "launch",
      "cwd": "${workspaceFolder}",
      "program": "target_script.py",
      "args": [
        // arguments with substitution
        "../foo/${input:select_type}",
        "--sub-option=${input:string_type}/${input:select_type}/bar",
        // arguments without substitution
        "--non-flag-option=tester",
        "--flag-option",
      ],
      "console": "integratedTerminal",
      "justMyCode": false,
      "stopOnEntry": true,
    },
  ],
  "inputs": [
    {
      "id": "select_type",
      "type": "pickString",
      "description": "Select type option ...",
      "options": [
        "option1",
        "option2"
      ],
    },
    {
      "id": "string_type",
      "type": "promptString",
      "description": "String type option ...",
      "default": "default_option",
    },
  ],
}

Possible Solutions

I propose adding an inputs field to the nvim-dap module table, which specifies the variable names and their input types (pick or prompt), and is used for text substitution in every ${input:...} block. We can provide this functionality for the args field in most debug configurations, and extend it to program and other fields easily, if needed.
This inputs field can be structured similar to the configurations field and/or store different variable specifications per filetype.

Below is a proposed translation of the previous launch.json example to a lua configuration -

local dap = require 'dap'

-- existing functionality
dap.configurations.python = {
  {
    name = 'Debug target script',
    request = 'launch',
    cwd = vim.fn.getcwd(),
    pythonPath = '/usr/bin/python',
    program = 'target_script.py',
    args = {
      -- arguments with substitution
      '../foo/${input:select_type}',
      '--sub-option=${input:string_type}_${input:select_type}-bar',
      -- arguments without substitution
      '--non-flag-option=tester',
      '--flag-option',
    },
    console = 'integratedTerminal',
    justMyCode = true,
    stopOnEntry = true,
  },
}

-- proposed functionality
dap.inputs = {  -- OR `dap.inputs.python`
  select_type = {
    type = 'pick',
    desc = 'Select type option ...',
    items = { 'option1', 'option2' },
  },
  string_type = {
    type = 'prompt',
    desc = 'String type option ...',
    default = 'default_option',
  },
}

I would like to contribute and create a PR if this feature is worth adding to the plugin, since I already have a (possibly naive) working implementation of this in my NeoVim configuration.
Cheers ~

Considered Alternatives

No response

@mfussenegger
Copy link
Owner

Inputs are supported if you're using launch.json files:

nvim-dap/doc/dap.txt

Lines 338 to 370 in 700a3c7

load_launchjs supports `inputs`. Inputs can be used to define custom input prompts.
They are declared in an "inputs" array and each input must have the following properties:
- "id": the identifier of an input
- "type": Either `pickString` or `promptString`
- "description": Descriptive text shown to the user
- "default": Default value
`pickString` has an additional "options" property, which is an array of strings.
These are shown to the user as options.
Inputs can be referenced with `${input:<id>}` placeholders.
>json
{
"version": "0.2.0",
"configurations": [
{
"type": "python",
"request": "launch"
"name": "Launch",
"program": "${input:myPrompt}"
}
],
"inputs": [
{
"id": "myPrompt",
"type": "pickString",
"description": "Program to run: ",
"default": "foobar"
}
]
}

I won't add extra sugar for them for Lua, because as you pointed out there are already options for that like with vim.ui.select.

@dasupradyumna
Copy link
Author

dasupradyumna commented Jan 11, 2023

Alright, cool!
So may I assume this thread resolved?

Also, I noticed that #629 has a contributions welcome label. How exactly is it different from my proposal?
Cheers ~

@mfussenegger
Copy link
Owner

Also, I noticed that #629 has a contributions welcome label. How exactly is it different from my proposal?

That's about adding some kind of dap.utils.split_args function which splits a string into a list/table on whitespace but opposed to a vim.split call it should consider quotes and split something like '"foo bar" baz' into ['foo bar', 'baz']

mfussenegger added a commit that referenced this issue Aug 9, 2024
Fixes #629, #816 and #1267

Co-authored-by: Mathias Fussenegger <f.mathias@zignar.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants