How to launch a VSCode extension with a new file? - visual-studio-code

I'm developing a VSCode extension and since it should currently only run on JS files, when I run the Launch Extension task I want it to open with a new Javascript file. I've seen this related question and have tried adding, just passing an options object as per the docs
vscode.workspace.openTextDocument({language: 'javascript'})
This is an async call so I've tried awaiting it while my extension is activating to ensure the file exists before I am able to use my extension.
If I could add this functionality to the Launch Extension task that'd be great or even if I could just have it open a file when I run my command that'll do while I'm developing on it.
Any ideas on how I can do this?

I'm not 100% sure but I believe your extension is activated only once and stays like that until vscode shuts down. Hence you cannot trigger multiple activation calls. Instead you could listen to document opening
workspace.onDidOpenTextDocument((doc: TextDocument) => {
if (doc.languageId == "JS" && doc.uri.scheme === "file") {
...
}
});

Related

Is there a way to access env from vscode extension?

I am trying to build a VSCode extension that relies on process.env set on runtime from an application like Vue using process.env.VUE_APP_* syntax but accessing it on the extension always returns undefined.
I'm accessing it on registerCommand callback like so:
commands.registerCommand('command', () => console.log(process.env.VUE_APP_SOME_NAME));
I'm thinking that maybe it has something to do with the way it opened up a new window to run the extension when I'm testing it locally, no?

Do VSCode webviews support Web Workers?

I'm in the middle of making a vscode extension, noticed some strange interactions when I tried to implement a Dedicated Worker to my extensions webview.
I'm already using the vscode API to pass messages around the extension, however when using a dedicated worker(in the webview) & passing messages around else where in the extension, the web worker somehow gets called.
If I let my web worker send a call back an infinite loop occurs and VSCode crashes. This leaves me to believe that VSCode is actually utilising web workers already? But shouldn't a new dedicated worker be spawned when using new Worker(), regardless of VSCode?
I tried implementing a shared worker, but didn't have any success (no response at all from the SharedWorker), which leaves me to believe that webviews don't support this? Am I right in saying that? Has anyone implemented this before?
I tried finding more information online and on their GitHub issues, but wasn't able to :/
TLDR: Do Webviews in VSCode support web workers?
Yes, you can. I don't know about seperate files, but you can use URL.createObjectUrl() to create a worker. Here is some code that worked for me (inside the webview html).
const blob = new Blob(['self.postMessage("Message from worker")'])
const uri = URL.createObjectURL(blob)
new Worker(uri).addEventListener('message', e => {
console.log(e)
})

VS Code API - remote calls

I am currently investigating VS code extensions in conjunction with a code generation project. While I understand that the VS code API is fairly full-fledged to allow in-extension manipulation of documents I can't figure out how to do this outside of the extension.
Are there ways of remotely executing the vs code JavaScript APIs outside of vscode which in turn will drive the GUI.
I am trying to figure out if I can do any of the following:
Execute the API JavaScript code when through the code cli
Run a web server/socket within an extension to listen to events from external systems and execute the JS API accordingly
If not socket/rest server, should I listen to filesystem changes and react accordingly?
Basically, what are the options for remote control driving of vs code?
I've faced a similar problem with an editor extension I'm working on.
I would highly recommend listening to file changes outside of VSCode APIs. This way the majority of your code is not bound to a specific editor. I also had much more difficulty using the VSCode API called createFileSystemWatcher as it didn't capture all changes.
Upon activation, run a child process using a file watcher library. I'd recommend using chokidar - its the same library VSCode uses internally but with more extensive access to the API.
// get your workspace uri & root uri
const workspaceRoots = vscode.workspace.workspaceFolders
if (!workspaceRoots || !workspaceRoots.length) {
throw new Error('No workspace root path')
}
const workspaceRoot: vscode.WorkspaceFolder = workspaceRoots[0]
const rootUri = vscode.workspace.getWorkspaceFolder(workspaceUri);
// the action you want to trigger
const command = vscode.commands.registerCommand('YOUR_CUSTOM_COMMAND', yourCustomFunction)
// file watcher
const fsWatcher = chokidar.watch('watcher_name', {
cwd: rootUri.uri.path,
interval: 1000,
})
// listen to any add/update/delete fs events
fsWatcher.on('change', (path, event) => {
vscode.commands.executeCommand('YOUR_CUSTOM_COMMAND')
})
On any file change, it can trigger the action of your choice.
If a VS Code extension can achieve everything you are after, then the simplest approach would be to let the extension be driven externally. VS Code extensions run in a node.js environment, so they can start a http server, listen on a named pipe, or communicate with the outside world using pretty much any other mechanism.
You can also take a look at VS Code support for testing extensions, since tests also just use standard VS Code extension apis: https://code.visualstudio.com/api/working-with-extensions/testing-extension
For the development of VS Code itself, there are some automation scripts that simulate user actions. If you really need to, I believe you could adopt these script to your use case, however I can't say how much work it would be. These script also break if the UI changes. Better to go the extension route if possible

Can I execute an executable file from a webview?

Is there a way to execute an executable file(.bat/.sh) from a webview? I have a button on a webview and would like to run the executable when that button is clicked. I looked into window.open(...) and ActiveXObject() but since a webview is not a browser window, they are irrelevant.
You could do this by contributing a Command which executes the script, and then creating a link that runs that command using a command URI in the WebView.
Let's call the command my.ext.runScript. Then we can add in our webview:
Run Script
Clicking that link will then invoke the script.
edit: Example
edit 2: You can also pass a message from the webview to your extension to invoke the command - documentation here.
Good luck!
I believe this is not possible. You don't have any browser or Node.js environment available in the web view. Also for security reasons the webview is pretty limited in what it can do, besides showing HTML content.
I was able to find a way. A webview communicates with your node env using the vscode api using the postMessage function. In the node env, you can spawn and handle a child process.
Docs:
VSCode postMessage
Node childProcess
Edit 1:
Example: VSCode Extension Tutorial
Let me know if you need further help. Thanks (:

What is the developer flow for ember-engines?

I am just beginning to look into Ember.js engines. One thing that stands out is that for every change I make in the engine code I need to re-install it into the host application. There is no live reload, rebuild or any of this.
Is there a way to smooth out this flow as it would slow down development considerably.
The trick is to set isDevelopingAddon like so in the index.js file for the addon and use NPM link to get it into the main application node_packages folder - you will then get live reload, etc-:
// Addon index.js
isDevelopingAddon: function() {
return true;
}
To add to this I found an interesting article here: Ember and Yarn Workspaces