Extending Groovy Editor - "injecting" global variable to script


Hi, I am building plugin that will allow our consultants to develop scripts with business logic that is then executed in our cloud application. 

These are just simple groovy scripts and consultants can use predefined variable "api" that has type e.g. MyAPI that provide white-listed public API that consultants are "allowed" to use.

To make consultants life easier, I would like to provide code-complete assistant that will show them all public methods available in MyAPI class. 

Question is how to do that - I don't want to add "MyAPI api = new MyAPI();" to each script just to make auto-complete available.

Any ideas?


See example below:

def rawMatrix = api.datamartLookup("CustTX","CustomerName","CustomerID","NetMargin%+")

def resultMatrix = api.newMatrix("Margin Status","Customer Id","Name","Net Margin %")
if(rawMatrix == null) return 0


Comment actions Permalink

Are you talking about IDEA plugin?

Comment actions Permalink

Correct, I am talking about IDEA plugin.

Comment actions Permalink

There are 3 ways:

  1. Plug into org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor.
    Qualifier type will be the type corresponding to the script class and results are to be fed to the processor.

  2. Use gdsl https://confluence.jetbrains.com/display/GRVY/Scripting+IDE+for+DSL+awareness

    IDEA can pick gdsls from its plugins or from user libraries.

    If you want your gdsl to be in your plugin then register org.jetbrains.plugins.groovy.dsl.GdslScriptProvider extension and make sure the gdsl file is under /standardDsls. The plugin needs to be deployed as the second way in the http://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_content.html. For example layout see Groovy plugin in your IDEA distribution.

    Another way is to package the gdsl into some jar (probably along with MyApi class) and add it as a dependency to user project (AFAIU this dependency should already be added). This is much simpler and does not require to create an IDEA plugin at all.

    The example gdls which adds foobar property of pckg.MyApi type to all groovy scripts:
     contributor(context(scope: scriptScope(), filetypes: ['groovy'])) {
    property name: "foobar", type: "pckg.MyApi"
  3. Use dynamic properties.
    Just type `api`, alt+enter, 'Add dynamic property'. 
    This approach is out-of-the-box feaure, hence no need for plugin. These properties can be shared between users if you include .idea/dynamic.xml in your VCS. 

From most to less preferable:

  1. Gdsl in library (simplest and most used way)
  2. NonCodeMembersContributor
  3. Gdsl in plugin
  4. Dynamic properties
Comment actions Permalink

Thank you! Will try and let you know.

Comment actions Permalink

I used #1 approach using Gdsl in library and works fine. Really pleased to see how easy was to solve this. IDEA architecture and you guys really rock!

Comment actions Permalink

Hi Milan/Daniil,


I am trying to do a similar thing but I just cannot get it to work in IntelliJ 2016.1.3...

I have a set of static functions that I want available by default from short versions, or a standard object, e.g.:

static def com.blah.groovy.api.OrderFunctions.createOrder(...)

static def com.blah.groovy.api.OrderFunctions.cancelOrder(...)

I want to register this through GDSL in a way it would be accessible as e.g. orderapi.createOrder(), orderapi.cancelOrder()

I've tried various permutations of GDSL and although I can get the autocomplete to work, I can't get orderapi available as a property in all scripts...

Am I missing the point here somewhere?




Please sign in to leave a comment.