Debug Diary: Vscode Extension Development Host Can't Fully Simulate Actual Vscode
Tags: vscode
Published: 2024-06-22 01:00:03

Encountered a problem while developing upon one of my favorite vscode extensions: [better comments](https://github.com/aaron-bond/better-comments) by [Aaron Bond](https://github.com/aaron-bond). I have figured it out, learned much new stuff, considering researching it (specifically vscode's Extension Development Host) a bit more, raise an issue to vscode and most importantly, share it with you guys so that you may prevent encountering issues like me.

## :skull: Problem

The extension works in vscode, but when I cloned the source code and test ran it in vscode's Extension Development Host, it fails to function properly (only some programming languages are properly highlighted).

## :mag: Cause (TLDR)

vscode's Extension Development Host fails to simulate an actual vscode instance, resulting the extension not able to detect installed language support extensions, resulting the extension not functioning properly in Extension Development Host, but does function properly in ordinary vscode instances.

## :beetle: Debugging Process

After briefly reading the source code, I found that this extension basically scans all extensions installed in user's vscode, pick extensions with language support, and store those language configurations, combined with user's customized comment configurations, finally decorate comments in the editor.

Inside Extension Development Host (EDH), through debugging with breakpoints, I found that some of extensions's variables (specifically `commentConfig` and `languageConfigFiles` in the `configuration.ts`) which should hold language configurations only contain a part of extensions by the time of decorating comments.

---

### :hourglass: _Interlude: I Was Wrong with "Watch" in vscode Debugging Variable Expressions..._

While I tried to use the "watch" functionality in vscode debugging, for some time I really thought these 2 variables were not properly initialized into empty `Map` objects, because the "watch" panel shows `Uncaught ReferenceError` for these 2 variables after executing the initialization statements:

```typescript
private readonly commentConfig = new Map<string, CommentConfig | undefined>();
private readonly languageConfigFiles = new Map<string, string>();
```

Turns out, my "watch" expressions were wrong. I should have used `this.commentConfig` and `this.languageConfigFiles` instead of `commentConfig` and `languageConfigFiles` in the "watch" panel. Seems that vscode's "watch" functionality have its own way of figuring out variable scopes, but I haven't really found the documentation for it. I would really appreciate it if you could point it out to me in the comment section.

---

### Test the "better comments" Extension by Packaging the Source Code and Installing It to vscode

If the problems lies in the EDH, then I should try to test the extension in an actual vscode instance. After packaging the source code into a `.vsix` file, and installing it to vscode (also disabling the extension originally installed from extension marketplace), all languages are decorated properly, which means the extension powered by the source code functions properly!!! :satisfied:

---

### Making a Little Extension to Confirm My Suspicions

I want to know the reason why the better comments extensions works well in an actual extension. Specifically, I want to know whether the `vscode.extensions.all` variables could actually pick up all extensions in an actual vscode instance.

But vscode doesn't allow me to **directly** inspect the `vscode.extension.all` variable in a vscode instance:


![vscode Developer Tools](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d36g41o4i0sqlftoz6a7.png)


With the help of Copilot, I created a little extension called `inspect-all-extensions` to inspect the `vscode.extensions.all` variable of a vscode instance. The `activate()` functin of `extension.ts` looks like this:

```typescript
export function activate(context: vscode.ExtensionContext) {
  console.log('Extension "inspect-all-extensions" is now active!');

  const disposable = vscode.commands.registerCommand(
    "inspect-all-extensions.inspect",
    () => {
      // Variables for formatted printing
      const publisherWidth = 20;
      const nameWidth = 30;
      const versionWidth = 10;

      // Create and show an output channel
      const outputChannel = vscode.window.createOutputChannel("AllExtensions");
      outputChannel.show(true);

      // Get all extensions
      const extensions = vscode.extensions.all;
      const extensionsInfo = extensions
        .map(
          (ext) =>
            `${ext.packageJSON.publisher.padEnd(
              publisherWidth
            )}\t${ext.packageJSON.name.padEnd(
              nameWidth
            )}\t${ext.packageJSON.version.padEnd(versionWidth)}`
        )
        .join("\n");

      // Print all extensions in the output channel and console
      outputChannel.appendLine(extensionsInfo);
      outputChannel.appendLine("Extensions count: " + extensions.length);
      console.log(extensionsInfo);
      console.log("Extensions count:", extensions.length);
    }
  );

  context.subscriptions.push(disposable);
}
```

After packing, installing this helper extension and running its command, here is the output

```
vscode              	configuration-editing         	1.0.0
vscode              	css-language-features         	1.0.0
vscode              	debug-auto-launch             	1.0.0
vscode              	debug-server-ready            	1.0.0
vscode              	emmet                         	1.0.0
vscode              	extension-editing             	1.0.0
vscode              	git                           	1.0.0
vscode              	git-base                      	1.0.0
vscode              	github                        	0.0.1
vscode              	grunt                         	1.0.0
vscode              	gulp                          	1.0.0
vscode              	html-language-features        	1.0.0
vscode              	ipynb                         	1.0.0
vscode              	jake                          	1.0.0
vscode              	json-language-features        	1.0.0
vscode              	markdown-language-features    	1.0.0
vscode              	markdown-math                 	1.0.0
vscode              	merge-conflict                	1.0.0
ms-vscode           	js-debug                      	1.90.0
ms-vscode           	vscode-js-profile-table       	1.0.9
vscode              	npm                           	1.0.1
vscode              	php-language-features         	1.0.0
vscode              	references-view               	1.0.0
vscode              	search-result                 	1.0.0
vscode              	tunnel-forwarding             	1.0.0
vscode              	typescript-language-features  	1.0.0
42Crunch            	vscode-openapi                	4.26.3
bierner             	github-markdown-preview       	0.3.0
bierner             	markdown-checkbox             	0.4.0
bierner             	markdown-emoji                	0.3.0
bierner             	markdown-footnotes            	0.1.1
bierner             	markdown-mermaid              	1.23.1
bierner             	markdown-preview-github-styles	2.0.4
bierner             	markdown-yaml-preamble        	0.1.0
dbaeumer            	vscode-eslint                 	3.0.10
eamodio             	gitlens                       	15.1.0
esbenp              	prettier-vscode               	10.4.0
GitHub              	copilot                       	1.206.0
GitHub              	copilot-chat                  	0.16.1
golang              	go                            	0.41.4
golang              	go-nightly                    	2024.5.3021
mhutchie            	git-graph                     	1.30.0
ms-python           	debugpy                       	2024.6.0
ms-python           	python                        	2024.8.1
ms-python           	vscode-pylance                	2024.6.1
ms-vscode           	extension-test-runner         	0.0.9
ms-vscode           	live-server                   	0.4.13
oderwat             	indent-rainbow                	8.3.1
redhat              	java                          	1.31.0
redhat              	vscode-yaml                   	1.15.0
undefined_publisher 	inspect-all-extensions        	0.0.1
VisualStudioExptTeam	intellicode-api-usage-examples	0.2.8
VisualStudioExptTeam	vscodeintellicode             	1.3.1
vscjava             	vscode-java-debug             	0.57.0
vscjava             	vscode-java-dependency        	0.23.6
vscjava             	vscode-java-pack              	0.27.0
vscjava             	vscode-java-test              	0.41.1
vscjava             	vscode-maven                  	0.44.0
Vue                 	volar                         	2.0.21
waderyan            	gitblame                      	11.0.1
Extensions count: 60
```

Now it shows all extensions properly, including vscode built-in extensions that are not overriden by third party extensions and third party extensions.

## :sob: What I Could Had Done Better & :rocket: Future Improvements

Somehow I am not able to reproduce the problem of "only partial extensions detected in EDH". This is a **VERY VERY BIG** mistake because now I can't reproduce the problem anymore, which means I couldn't raise an issue or question about this online anymore and everybody would think that I was hallucinating :sob:. Next time I would document the outputs (screenshots may better) somewhere else. Maybe I have just overturned the conclusion of this entire blog...

Since now the `vscode.extensions.all` variable seems to be working properly in EDH (showing 61 extensions), the real problem may lie somewhere else, such as the `UpdateLanguagesDefinitions()` function, where its result `languageConfigFiles` only picked up 15 of the extensions...