VS Code API - remote calls - visual-studio-code

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

Related

Can I use the VS Code API to implement language features in a web extension?

I generated a VS Code web extension, registered the language into the package.json file, and put this code snippet into the extension.ts file:
console.log('activation');
context.subscriptions.push(vscode.languages.registerHoverProvider(selector, {
provideHover: function (document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.ProviderResult<vscode.Hover> {
console.log('hover');
return new vscode.Hover('test');
}
}));
If I start the extension by pressing the F5 key (it starts a new VS Code instance to run the extension), it works fine, but if I run the run-in-browser npm script it doesn't work. The activate function runs in both cases, because I see the text 'activation' in the console, but if I run in the browser I can't see the text 'hover'.
In normal (not web) VS Code extensions I can use both the VS Code API and the Language Server Protocol to implement language features like hover, formatting, go to definition etc. In the web extensions page they don't mention that I can only use the Language Server Protocol (and not the API) in web extensions, but in the only web extension sample where they implement language features, they use the Language Server Protocol.
So, is it possible to use the VS Code API to implement language features in web extensions, or I have to use the Language Server Protocol? If it's possible, why my code doesn't work in the browser but it does in desktop VS Code (using the web environment)?

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)
})

Is it OK for me to develop against UWP with JavaScript on Visual Studio 2017?

My company is using RPG Maker MV (based on JavaScript) and looking to port over to Xbox UWP. It's no longer supported in the latest version of Visual Studio.
Is there a workaround or should I abandon this and convert over to C#?
Sadly this has indeed been deprecated, but as a workaround you can use a WebView to host the game which is what I do with mine. You'll still have to deal with a few extra things if you want to use the Xbox storage functions (see here for my commentary on this) and you still need to implement sign-in (which I'm still working on) but once you add the WebView to your MainPage.xaml name it something like ContentViewport and (immediately following your login and file processing logic) add the following line of code:
ContentViewport.Source = new Uri("ms-appx-web:///index.html");
Or wherever your index.html is, so if you prefer assets over package root with the www folder copied in as a base, you can use the following:
ContentViewport.Source = new Uri("ms-appx-web:///assets/www/index.html");

Only run my sails.js hook on `sails lift`, not `sails run`

I have a custom sails.js hook which implements a Websocket server (we can't use the built-in socket.js hook because we needed to match an old API).
I also have a custom sails run script that does background processing.
Right now, when the sails run -name-of-my-script command is run, it also runs my hook which makes extra listeners for all of the events used by this hook.
I would like to make it that the hook only starts on a main application startup (sails lift or the equivalent node app.js), not on sails run ....
I have looked through the code and the documentation, but I can't seem to see any official way to do this.
I can think of two options:
In the hook, check for whether a script is being run and don't initialize.
In the script, disable the hook.
Is there any way to do either of those things?
Right now, there is no built-in way to do this because Sails scripts have no way to modify configuration - they use the default sails instance with its default settings.
Here is the hack that I used to make it work:
Add a check for a configuration option in the hook's initialize method:
if (app.config.notifier.active === false) {
sails.log.verbose('Notifier disabled');
return cb();
}
// Continue with notifier hook setup here
Add setting an environment variable to the top of the script (before the module.exports:
process.env.sails_notifier__active = false;
(Note: Step 1 is based on this answer but the package linked there no longer uses this technique. That question and answer are also extremely old -- at least as Sails.js answers go -- from before sails run existed.)

Include runtime type definitions using VSCode extension

I'm working on a library that lets users run Node processes from inside another application. The library is called "max-api"; functions for sending data to the host application are exposed through a Node module and are loaded in the expected way:
const maxAPI = require("max-api");
However, the user never interacts with this module directly. Rather, when the host application launches the Node process, it intercepts the call to require, checks if the name of the module is "max-api", and provides the module if so.
This works great, the only issue is we have no way to provide type definitions for this modules. So, the user doesn't get any autocomplete or validation for functions in the "max-api" module. I was thinking of writing a VSCode extension to provide these, but I'm not 100% sure how to get started. Thanks in advance for any advice.
You could write a TS typings file (see Definitely Typed). This would be installed in node_modules/#types and vscode will automatically pick it up to provide code completion for your module.