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

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

Related

Which language servers are supported by VSCode request forwarding?

I am working on a language server extension with embedded Lua code which I want to get Intellisense support on. My extension does not have any language features for Lua. I have decided to use request forwarding to achieve Intellisense.
I played around with the lsp-embedded-request-forwarding sample and tried using completions for different languages by changing the following code in the sample:
line 36: updating the slicing to remove .js extensions instead of .css
workspace.registerTextDocumentContentProvider('embedded-content', {
provideTextDocumentContent: uri => {
const originalUri = uri.path.slice(1).slice(0, -3);
const decodedUri = decodeURIComponent(originalUri);
return virtualDocumentContents.get(decodedUri);
}
});
line 56: changing the language authority and language extension
const vdocUriString = `embedded-content://js/${encodeURIComponent(
originalUri
)}.js`;
Doing so allowed me to get Javascript completions within the '' tags (just for testing's sake). However, when I try it with Python and Lua, I was unable to get any completion results when typing in their respective languages.
The VSCode documentation explains that
request forwarding sends the request back to VS Code to query all
language servers and forward their responses
I would like to clarify the scope of 'all language servers' - does that mean all third party ones available on the marketplace as well?
Initially, I thought it could be limited to language servers developed by Microsoft. But since I could not get it to work on Python, it is not behaving the way I expected.
Which language servers and languages are supported by this request forwarding feature? Is it possible to do request forwarding to marketplace language servers such as Lua and how do I do it?

how to debug VSCode custom language extension

I want to test my VSCode custom language extension, which introduces a new language and is implemented through Language Server Protocol.
Although my language server itself is tested workable, when binding to the VSCode client, the client just CANNOT show the expected result. For example, after I trigger a "textDocument/definition" request from the client by left click the variable name, the client just hold and displays the "in-progress" progress bar. However, the language server log shows that the request is send and the correct response is send back successfully...
How can I find the reason why the result is not displayed?
What I've tried:
debug the extension by pressing "F5", but the client source code is written in TypeScript and is complicated. I can't find the reason yet.

Flutter Web Get Chrome Extension info from Polkadot.js web3Enable

I am hoping to confer on a strategy for a flutter web app (as can ignore mobile cases here) to get chrome extension info for a Polkadot.js wallet from the Polkadot browser extension.
My first thought is to use dart's JS library and use the Polkadot extension JS package and then try and pull the info from there. However, I'm not sure how to properly use this in flutter as it is a whole package full of dependencies, not just a single JS file. Also it is in TS not JS. Any thoughts here?
Eg., I need a JS file to be able to call this; and for flutter to in turn call the JS file:
import {
web3Enable,
} from '#polkadot/extension-dapp';
By writing out a "bridging" layer, you can do it easily.
Firstly, create a normal javascript (or typescript) application (nothing related to Flutter). You should be able to happily use the polkadot lib in your js/ts code without any problem. You may need to learn a bit about how to develop js code normally (e.g. you can depend on polkadot using npm, etc).
One small thing is that, you should "expose" some object publicly in your js/ts code. For example, your code may look like window.myFancyFunction = function() { call_some_polkadot_function(); }. Of course you can do more things like exposing other functions/objects/...
Then, you can bundle this normal js/ts application into a .js file. This is still very normal for js/ts developers and should have nothing special to deal with here, and you still do not need to touch Flutter at this stage.
Next, load this single-filed .js file when you are loading your Flutter Web application. You may simply do this by editing your Flutter Web's html file and add <script src="my_single_filed_js_mentioned_above.js" />. Notice that, when loading this script, it simply sets window.myFancyFunction and does not do anything more. Still very trivial here, should have no problem.
Lastly, in your Flutter Web code, i.e. Dart code, call that window.myFancyFunction function. For example, Flutter Web : How to run javascript using dart js says you can do import 'dart:js' as js; js.context.callMethod('myFancyFunction', ['some arguments']);

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

Is there a way to execute a custom action through the CodeAction request?

I want to initiate a user action from Visual studio code. which would read the current opened text document, extract a piece of code by some kind of UI action (a custom button, or through CodeAction if possible), send it to the server using the Language Server Protocol, does some work and returns some output back to client.
I've read the Language Server Protocol specifications for CodeAction but its normally used only for quickfixes and refactoring, can i use it for any other custom action? If so, how?
Code actions can invoke arbitrary client-side commands when they're executed:
export interface CodeAction {
[...]
/**
* A command this code action executes. If a code action
* provides an edit and a command, first the edit is
* executed and then the command.
*/
command?: Command;
}
You can register new commands using the vscode.commands namespace.
[...] send it to the server using the Language Server Protocol, does some work and returns some output back to client
For this part, you can use custom methods to send data back and forth between the language server and the VSCode extension:
Vscode Language Client extension - how to send a message from the server to the client?
visual studio language extension, how do I call my own functions?
Both of these things of course make your language server much less compatible with clients other than VSCode. Are you sure you need client-side logic for this?