AnWeber / vscode-statusbar-command

MIT License
17 stars 4 forks source link

Make displayed icon/text conditional on the value of a VSCode setting variable? #18

Closed dandavison closed 2 years ago

dandavison commented 2 years ago

Hi, thanks for this extension!

Is it possible, or would it be an easy modification, to make this extension show a different icon/text message conditional on the boolean value of a VSCode setting variable? For example, I'd like to know when github.copilot.inlineSuggest.enable is true or false. I'm not sure whether that could be achieved reactively, or by creating a command that outputs the value of the variable. I'm not very familiar with VSCode extensions and configurations so I may be missing something obvious.

AnWeber commented 2 years ago

I'm thinking about adding a scripting block to query the values via Javascript. Or rather a special has config or has not config. Or maybe both, but Scripting could impact performance unnecessarily.

dandavison commented 2 years ago

That sounds great, thanks!

My other use case is that I sometimes disable the compiler error underline squiggles so that I can just concentrate on the code. But then, I end up wondering whether I've disabled them, or whether there truly are no errors :) So I'd use this to display something in the status bar to tell me which mode I'm in.

AnWeber commented 2 years ago

I have now published script support. In principle, almost anything can be acted upon in VSCode, but knowledge of the VSCode API is required. But your examples should be relatively easy to implement.

Monitor Github Copilot

{
  "alignment": "left",
  "command": "github.copilot.toggleCopilot",
  "id": "sbc.copilot",
  "text": "Github Copilot",
  "scriptEvents": ["vscode.workspace.onDidChangeConfiguration"],
  "script": "statusBarItem.text = vscode.workspace.getConfiguration('github.copilot.inlineSuggest').enable ? '$(github)' : '$(github-inverted)'"
}

If you tell me how you disable the compiler error underline squiggles, I can help you with your 2nd example as well.

ScriptEvents is used to subscribe to VSCode Events. Script is the Javascript which is executed. You can access vscode API and current statusBarItem

This only works in the NodeJS environment (not on vscode.dev).

dandavison commented 2 years ago

Wow, fantastic @AnWeber, I confirm that the Copilot toggle works perfectly (and the two icon states look nice as well).

So for my compiler squiggle "zen" mode, what I am doing is a silly hack, and you probably have a better idea. Nevertheless, here's what I'm doing:

I use the Settings Cycler extension to set up a toggle command as follows:

    {
      "id": "zen",
      "overrideWorkspaceSettings": true,
      "values": [
        {
          "editor.matchBrackets": "never",
          "workbench.colorCustomizations": {
            "editorError.foreground": "#00000000",
            "editorInfo.foreground": "#00000000",
            "editorWarning.foreground": "#00000000"
          }
        },
        {
          "editor.matchBrackets": "always",
          "workbench.colorCustomizations": {
            "editorError.foreground": "red",
            "editorInfo.foreground": "blue",
            "editorWarning.foreground": "orange"
          }
        }
      ]
    }

And I bind this to a key

  {
    "key": "ctrl+x shift+z",
    "command": "settings.cycle.zen",
    "when": "editorFocus"
  },

So, with that, I am able to use statusbar-commands to display the state with this:

    {
      "alignment": "right",
      "command": "dan.zen",
      "id": "sbc.zen",
      "text": "Zen Plus Mode",
      "scriptEvents": ["vscode.workspace.onDidChangeConfiguration"],
      "script": "statusBarItem.text = vscode.workspace.getConfiguration('editor').matchBrackets === 'never' ? '$(circle-slash)' : '$(circle-large-outline)'"
    }

Of course I would prefer a dedicated mode variable, rather than relying on matchBrackets being perfectly correlated with my mode.

How would you go about this?

AnWeber commented 2 years ago

I think you have already found the best solution. An issue that addresses the problem in general in VSCode had too few upvotes. And settings cycler remembers the current state only in memory and determines the current index again when reloading. You would have to create an issue in the Settings Cycler extension so that the current index is stored in the settings. The comment points to a bug when reloading the index anyway.

dandavison commented 2 years ago

OK, well thanks very much for this -- it's working perfectly and was easy to configure.

AnWeber commented 2 years ago

You are welcome. I would have thought that you can simply create your own setting with Settings Cycler and use this as criteria. VSCode allows any settings, but marks them as unused.

dandavison commented 2 years ago

OK, I was going to ask you about that. How would I do that? I've tried

     {
      "id": "zen",
      "overrideWorkspaceSettings": true,
      "values": [
        {
          "danZenPlus": true,
          ...
        },
        {
          "danZenPlus": false,
          ...
        }
      ]
    }

Then how would I query the variable? Neither of these seem to work:

      "script": "statusBarItem.text = danZenPlus ? '$(circle-slash)' : '$(circle-large-outline)'"

(Doesn't show an icon at all; instead shows the value of the text key in the statusbar-commands config entry.)

      "script": "statusBarItem.text = vscode.workspace.getConfiguration('danZenPlus') ? '$(circle-slash)' : '$(circle-large-outline)'"

(behaves as if always false)

AnWeber commented 2 years ago

Return value of getConfiguration is a proxy and not a boolean. You query a section and can access properties under this section. For this reason also the surprising separation with the copilot example (vscode.workspace.getConfiguration('github.copilot.inlineSuggest').enable)

      "script": "statusBarItem.text = vscode.workspace.getConfiguration('dan').ZenPlus ? '$(circle-slash)' : '$(circle-large-outline)'"
     {
      "id": "zen",
      "overrideWorkspaceSettings": true,
      "values": [
        {
          "dan.ZenPlus": true,
          ...
        },
        {
          "dan.ZenPlus": false,
          ...
        }
      ]
    }
dandavison commented 2 years ago

OK, thanks. However that doesn't seem to be working either: it is behaving as if vscode.workspace.getConfiguration('dan').ZenPlus always evaluates to false, but I know the toggle is taking effect.

AnWeber commented 2 years ago

The reason is that the update method used by Settings Cycler does not work for unknown values (configuration is not registered. I did not know that either. Then, unfortunately, the plan does not work, sorry. The cleanest solution would be Settings Cycler would persist the current index.