Custom language autocompletion with nested properties

Hi all,

TL;DR: How can we recursively show suggestions in our custom language’s autocomplete for nested properties?

Long version:

We are using CodeMirror for a custom language with autocompletion on nested properties similarly to accessing properties on JSON. We have a somewhat functional autocomplete for our language itself and its functions but we are struggling with the nested properties aspect. We were wondering about the validity of our approach and whether anyone could weigh in on their implementations if they have used CodeMirror in a similar capacity with nested properties.

Here’s a quick example of our custom language and the autocomplete we are using for nested properties. This is a function to check the outputs of a HTTP request named ‘http1’, therefore we would like the autocomplete to let us step into the properties infinitely much like how JSON behaves. So far we can only get one level deep, i.e. into headers.

A simplified snippet of part of our autocomplete function:

(We have some if statements like so to catch various functions and run logic to generate options, before showing more generic autocomplete suggestions after.)

const splitContext = context.tokenBefore(["DotAccess"])!.text.split(".");

const prevWord = splitContext![splitContext!.length - 2].toLowerCase();

//In this section, we would generate suggestions for

//the input of [outputs(‘something’)] when the user adds a ‘.’ after the

//final parentheses. Intended to work like accessing nested JSON objs

if (prevWord.startsWith("outputs")) {

const nameInput = prevWord.split("'")[1];

const stepName = stepNames.find((s) => s.name === nameInput);

return {

from: word!.from,

to: word!.to,

options: stepName ? generateOutputsOptions(stepName!.kind) : [],

};

}

And then the functions that generate the options are essential big switch statements that for the case of the outputs function, we are manually reading what’s in the string literal and showing options like so:

switch (kind) {

case WorkflowStepKind.FilterArray:

return [

{

label: "Results",

type: "property",

apply: "results",

section: "Array output defaults",

},

];//Etc, etc for other cases…

We are doing this same approach whenever the autocomplete function is called by the CodeMirror instance, essentially checking the “function” (in this example: “outputs”) the user has written, and showing various suggestions. This approach works well for suggestions of function names etc but as mentioned, is falling short for showing nested properties.

One of our main concerns with this approach is how we could then access nested properties within (for example: [outputs(‘something’).header.thingInHeader]) without having to have a wall of switch statements where we would switch on header, then switch on thingInHeader, etc. We were wondering whether the TreeCursor could come in handy or perhaps a ‘visitor’ to navigate the tree and provide suggestions recursively. Any feedback or just general pointers regarding the approach we could take would be greatly appreciated.

1 Like