Load webSymbols.webTypes JSON file from URL
Hi all,
I am creating a plugin that needs to load a web-types JSON file from a URL and use the file to assist with type hinting and autocompletion.
From looking at the documentation (here and here), I need to use
<webSymbols.webTypes source="[SOURCE_HERE]"/>
which works fine, but I seem to be getting stuck, considering the following use cases;
- The framework which I am trying to support does not follow versioning, so it can change, meaning the plugin will need to re-fetch the web types file once in a while to keep up to date, since the framework releases periodically
- The plugin has an environment switch to toggle between a production version and a test version of the web-types file, so the plugin will need to switch environments & re-fetch the web types file
That means that I will need to support fetching the web types dynamically, making me believe that I cannot do this in the XML file, because that is static and won't change.
I might be mistaken, but I think it is not possible to write to the resources folder of my plugin. So my question is as follows.
How can I programmatically supply the web-types symbol parser with a web-types JSON file, and make it reload the file afterwards?
Please sign in to leave a comment.
Hi!
If you need a more advanced use case, you need to create a
WebSymbolsQueryConfigurator
, which will provide the loaded Web Types depending on the context. You would need to use some of the internal APIs, because I haven't yet exposed these to the public, but it is definitely doable. If you succeed we can consider making these APIs available of course.So, to load WebTypes from an
InputStream
you can use internalcom.intellij.webSymbols.webTypes#InputStream.readWebTypes()
function. Next you need to create a scope, which will be returned by the query configurator. For that extend internalWebTypesScopeBase
and calladdWebTypes
/removeWebTypes
to update the set of available WebTypes within the scope.WebSymbolsQueryConfigurator
can return scopes depending on the current location. Configurator is called very often, so the scope calculations should be as optimized as possible. Scopes should be cached, i.e. they should not be rebuilt on every call.Please note that there were some API changes between 2023.2 and 2023.3, as the framework is still under heavy development and is considered experimental for now.
Let me know if you have any more questions!
Hi Piotr,
Thanks for your response. Trying to create the plugin on Friday mornings, so excuse the slow progress.
I've been at work trying to grasp my head around the way to inject the web types to the scope.
As far as I understand, the
WebSymbolsQueryConfigurator.getScope()
is called for each line of the open file in the editor. In the getScope of an implementation ofWebSymbolsQueryConfigurator
, I need to add the webtypes to the scope, but how does one accomplish that? I've also extended theWebTypesScopeBase()
and exposed the addWebTypes, but besides a WebTypes object it also requires aWebTypesJsonOrigin
for context. I can't figure out where I get that context from..First time creating an IntelliJ plugin & working with Kotlin so please excuse me if I overlooked something obvious.
Hi!
The code looks more or less OK. I think it would be better to enclose all the stuff related to reading the WebTypes JSON into the
AuroraWebTypesScope
, it can be aProject
service. As far as theWebTypesJsonOrigin
is concerned, You need to implement the interface yourself. The interface allows to provide some basic things related to the symbols, like resolution to the source symbol, description rendering or context matching, as well as some info on the library, version or default icon. All these things are kind of optional, so you can gradually add the code.The most impactful part is the
framework
andmatchContext
/WebSymbolsContext
, failing to match the context disables symbols from a particular origin. Theframework
is special kind ofWebSymbolsContext
named“framework”
. There can be only one context of a particular kind, which means that there can be only one framework in the context. So far this type of context has been used to differentiate between web frameworks, likeangular
,vue
,svelte
,astro
, etc. I think that you can skip this part for now, and later on introduce some context limitations, so that your feature doesn't show in every file in unrelated projects.I am sorry, that it's so complicated, but again, this part of framework is still under
@Internal
API status, but I hope that your use case can help us better understand needs for such kinds of APIs. It would be great if afterwards, you could share the whole code and we could do some adjustments in the APIs if needed and improve documentation.Hi Piotr,
I'm back with another attempt at trying to get this working. I'm struggling quite a lot because of the unavailability of proper documentation. Understandable of course since the API is really new, but because of that please excuse me if I am missing something obvious. I've tried coding against decompiled function signatures, so without knowing what stuff does, making it fairly difficult.
I've tried to implement my own interface on top of the WebTypesJsonOrigin like below.
The rest of my implementation hasn't changed much, besides using
auroraWebTypesScopeBase.addWebTypes(parsedTypes, AuroraWebTypesJsonOrigin())
. ThematchContext
method of the AuroraWebTypesJsonOrigin is never called, leading me to believe that I should do that somewhere. I think I am really close to getting it working (at least somewhat). Do you mind pointing me in the right direction? Or maybe modifying the code a bit to get it in a working state?Thanks for bearing with me.
Basvanrooten I think it might be easier if you share a github repo with me (piotr.tomiak at jetbrains.com) :) I might be able to experiment with this locally and see what's wrong.