rioj7 / command-variable

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

Resolver that runs an external command or script and uses its stdout as the value #45

Open sammck opened 1 year ago

sammck commented 1 year ago

Would it violate some core principle to add a resolver that shells out to a command and uses the output of the command as the variable value? This would allow use of a keychain, database query, git configuration, AWS configuration, etc. to provide the value.

Would a pull request that adds this resolver be useful?

rioj7 commented 1 year ago

I think they are working on a way to let an extension read the terminal content or somehow hook into the stdin/stdout. I don't know the status of this feature.

You suggest that somehow the ${input:name} variable contains a shell command and that the stdout of the command is the result of the ${input:name} variable?

In issue #31 is the request to use the result of a task, also a shell command, in a pickString command.

If you can make this a pull request it would be nice.

sammck commented 1 year ago

Great, I'll look into it.

What I'm thinking of is the output of a non interactive script or command that does not need a terminal, and which can safely run every time the variable is expanded. Though I can see the use for an interactive script that could prompt the user, it's not what I need personally.

Perhaps the output of a task would be the cleanest way to achieve it.

tcm0116 commented 1 year ago

I think they are working on a way to let an extension read the terminal content or somehow hook into the stdin/stdout.

Is this different than what's provided by the Tasks Shell Input extension?

Using that extension, I'm able to run a shell command and get the output, which is demonstrated below via the bazelTargets input. I was attempting to utilize that input in conjunction with pickStringRemember, but selecting the "Targets" option doesn't seem to fire off the bazelTargets input. Is this possible? If not, could it be possible to add something like extension.commandvariable.shellCommand which uses a similar approach to the Tasks Shell Input extension?

    "inputs": [
        {
            "id": "bazelTargets",
            "type": "command",
            "command": "shellCommand.execute",
            "args": {
                "command": "echo '//...' && bazel query 'kind(cc_*, //...)'",
                "cwd": "${workspaceFolder}"
            }
        },
        {
            "id": "pickBazelTarget",
            "type": "command",
            "command": "extension.commandvariable.pickStringRemember",
            "args": {
                "description": "Choose a target",
                "key": "selectedBazelTarget",
                "options": [
                    [ "Previous Target", "${remember:selectedBazelTarget}" ],
                    [ "Targets", "${input:bazelTargets}" ],
                ]
            }
        }
    ]
sammck commented 1 year ago

Yes, in combination with useFirstResult, this seems to address my needs, though a bit more verbosely. Thank you...

rioj7 commented 1 year ago

@tcm0116 The fact that I do not support the ${input} variable is that I don't know which .json is the source of the command (task, launch, keybindings).

I'll look into the Task Shell Input extension how they do it and add it to this extension.

rioj7 commented 1 year ago

@tcm0116 You can use the ${command} variable. And use rememberTransformed to store/remember the result of the command.

    "inputs": [
        {
            "id": "pickBazelTarget",
            "type": "command",
            "command": "extension.commandvariable.pickStringRemember",
            "args": {
                "description": "Choose a target",
                "key": "selectedBazelTarget",
                "rememberTransformed": true,
                "options": [
                    [ "Previous Target", "${remember:selectedBazelTarget}" ],
                    [ "Targets", "${command:bazelTargets}" ],
                ],
               "command": {
                 "bazelTargets": {
                   "command": "shellCommand.execute",
                   "args": {
                     "command": "echo '//...' && bazel query 'kind(cc_*, //...)'",
                     "cwd": "${workspaceFolder}"
                   }
                 }
               }
            }
        }
    ]
tcm0116 commented 1 year ago

@rioj7 - that did the trick! Is there a way to resolve the "${remember:selectedBazelTarget}" value when it is displayed in the pciker? Currently, the picker shows "Previous Target ${remember:selectedBazelTarget}", but it would be much more helpful to the user if it could show the value stored in "${remember:selectedBazelTarget}" instead of just "${remember:selectedBazelTarget}".

rioj7 commented 1 year ago

@tcm0116 Created a separate issue

rioj7 commented 1 year ago

@sammck Does the example in this comment solve your issue?