CompareFolders — a Visual Studio Code extension journey — Part V

October 06, 2019

In the last post, we talked about how to add a button to a panel’s top bar — either in the “more” menu or as icon button in the top bar itself. Also we learned how to use _onDidChangeTreeData.fire() in TreeDataProvider class to refresh the view.

Like promised, the post will includes an explanation about the product challenge and how to solve it.

The challenge

The extension is supporting (currently) only comparing between a single workspace folder (or just a folder), and a folder that the user chosen. Which means that if there is not folder in the workspace (just open a new window of vscode) or if it has more than one folder the activity icon and the view shouldn’t be visible and vice-versa.

The challenge is even bigger because this can be changed without closing the window, therefor, vscode will not re-activate the extension. Which means that the extension need to “listen” to this change.

So, let’s break it to some steps.

  1. Now the extension need to be activate just when the vscode window is opened but not only when the extension’s view is visible. That’s because we need to check if the workspace has exactly one folder before it shows the view. In order to do this, the [activationEvents](https://code.visualstudio.com/api/references/activation-events) now should be *

1rwXn02dUYwuzmk0e5d9KcA

  1. To show / hide a view based on condition, a view has a configuration property called [when](https://code.visualstudio.com/api/extension-guides/tree-view#tree-view). For example:
1"contributes": {
2 "views": {
3 "package-explorer": [
4 {
5 "id": "nodeDependencies",
6 "name": "Node Dependencies",
7 "when": "explorer"
8 }
9 ]
10 }
11}

So the view will be visible only when the explorer panel is visible.

But what if we need a custom when clause? In our case, if the workspace has exactly one folder? (If you already know the answer, good for you 😀)

How to create a custom when clause?

Or, how to show / hide views, command menus and all the other UI components that have the when option in package.json?

In order to understand that, we need to understand what is the editorLangId or isInDiffEditor, or any other clauses in the list.

Well, vscode has context variables. isInDiffEditor is true when the current editor is.. well.. diff editor (the side by side one, yes?) and false in all other cases.

The extension has the power to create its own context variable. Well, don’t search this API in the docs.. It’s not there. Yah, I know.. There is an open issue on Github about that.

Anyway, there is an API to create a custom context variable

1commands.executeCommand('setContext', '[variableName]', [variableValue]);

In our case, the extension needs to check both on its activation and when the workspace folders changed (by listening to workspace.onDidChangeWorkspaceFolders) if the workspace has exactly one folder. If so, the extension will set a context variable workspaceHasOneFolder to true and false if not. Then, we could use that variable in the package.json

1"views": {
2 "foldersCompare": [
3 {
4 "id": "foldersCompareAppService",
5 "name": "Compare",
6 "when": "workspaceHasOneFolder"
7 }
8 ]
9}

and Voilà

Show activity bar icon only if workspace has only one folderShow activity bar icon only if workspace has only one folder

After we saw all this I’ve to admit, I cheated.. there is an appropriate when clause — workspaceFolderCount so the condition will be workspaceFolderCount == 1 but I wanted to show how to deal with custom context variable. I hope to find a different real example.

Source code for this post (short this time)

Have something to say? I’ll love to 👂

Original Post
© 2021 - Moshe Feuchtwander