rioj7 / command-variable

Visual Studio Code extension for variable substitution via ${command:commandID}
51 stars 9 forks source link

Is there an easy standard way to define a string value and use it in configurations? #92

Open woung717 opened 3 weeks ago

woung717 commented 3 weeks ago

I think this plugin is fantastic. But at first I couldn't figure out how to define a simple variable and use it in the configuration field value. After reading through the readme file, I can achieve this using something like this.

...
"${input:plain_text}",
...
"inputs": [
        {
            "id": "plain_text",
            "type": "command",
            "command": "extension.commandvariable.transform",
            "args": {
                "text": "Hello, World!"
            }
        }
    ]
...

Is there a simpler way to define and use variables in the launch.json file instead of using transform? If there is, it would be good to have an example in the readme file.

rioj7 commented 3 weeks ago

@woung717 We can't define new variables to use in the launch config or task. We have to use the ${input:name} and ${command:cmdID} variables.

An example is already in the readme: Custom Variables

Maybe an entry in the TOC would be an idea.

Another option is to use extension.commandvariable.remember but that will take the same amount of inputs code.

woung717 commented 3 weeks ago

@rioj7

We can't define new variables to use in the launch config or task. We have to use the ${input:name} and ${command:cmdID} variables.

Okay I got the idea, so we can't just define variables in json file and have to use values which created in some command that the plugin provides? Am I understanding right?

An example is already in the readme: Custom Variables

Maybe an entry in the TOC would be an idea.

Another option is to use extension.commandvariable.remember but that will take the same amount of inputs code.

Checked. I believe many use cases that involve using variables in the VSCode json file mostly focus on simply defining variables and reusing them in multiple locations. While the advanced features provided by plugin are undoubtedly useful, I think it would be beneficial to have a command for defining a variable with a static value (which still uses the "transform" function internally). This could simplify the process for users dealing with straightforward cases. Or, just we could include a use case example guide in the Table of Contents, as you mentioned earlier.

This is just my two cents, but if there's any part where I can help, I'd be glad to.

rioj7 commented 3 weeks ago

@woung717 A possible option would be to create a separate command for each variable:

"inputs": [
        {
            "id": "def_vars",
            "type": "command",
            "command": "extension.commandvariable.defVariables",
            "args": {
                "world": "Hello, World!",
                "lorem": "Lorem Ipsum",
                "carpe": "Carpe Diem"
            }
        }
    ]

These would then be used in the launch config or task as: ${command:var.lorem}, ${command:var.carpe}

And you would have to "call" the def_vars inputs in the first string of your launch config or task with ${input:def_vars}. Because extension.commandvariable.defVariables returns an empty string it does not mind where you put it.

I have tested it with the following task:

  "tasks": [
    {
      "label": "echo var",
      "type": "shell",
      "command": "echo",
      "args": [
        "User Variables: ${input:def_vars}${command:var.world} - ${command:var.lorem}",
      ],
      "problemMatcher": []
    }
woung717 commented 2 weeks ago

@rioj7 I appreciate your suggestion, and I see the benefit in naming the command "defVariables" for clarity. However, I have a concern about the need to invoke "${input:def_vars}" before using "command.var". This seems to mandate the registration of values within the "defVariables" command, I think we might be inadvertently skipping "${input:def_vars}". How about the following format for defining and using variables?

"inputs": [
        {
            "id": "lorem",
            "type": "command",
            "command": "extension.commandvariable.defVariable",
            "args": {
                "value": "Lorem Ipsum"
            }
        },
        {
            "id": "carpe",
            "type": "command",
            "command": "extension.commandvariable.defVariable",
            "args": {
                "value": "Carpe Diem"
            }
        },
    ]

And then use them like this in tasks:

"tasks": [
    {
      "label": "echo var",
      "type": "shell",
      "command": "echo",
      "args": [
        "User Variables: ${input:lorem} - ${input:var.carpe}",
      ],
      "problemMatcher": []
    }

While this approach might lead to more duplicated code, it appears clear and could potentially be easier to maintain if it's a feasible format to implement in the current code.

HyeonUng

rioj7 commented 2 weeks ago

@woung717 if I define extension.commandvariable.defVariable as an alias of extension.commandvariable.transform you have the same config code. With your suggestion the key of the variable (lorem, carpe) is not immediately clear. You can move the id line 2 down.

woung717 commented 2 weeks ago

@rioj7 Yes, you're right. Initially, I thought there might be a shorter and easier way to define variables. However, after understanding how the plugin and VSCode JSON work, I realized that simply creating an alias (with only a "text" argument) command is an easy way to achieve this. I like the format you suggested where we can define multiple variables in one place. It is much clearer and easier to understand. However, as I mentioned, the necessity to call the def_vars inputs before using the variables is somewhat unconventional and could be confusing, especially considering why an empty string command needs to be invoked. This is my only concern about your suggestion.

rioj7 commented 2 weeks ago

@woung717 You could use the extension.commandvariable.remember command to store a number of stuff to remember and return one of the keys. You have to do this in the first remember-input of the launch config. All other remember-inputs just retrieve a key from the remember store.