Open at055612 opened 4 years ago
Custom completions can be done roughly like this
AceEditor.addCompletionProvider(new AceCompletionProvider() {
@Override
public void getProposals(final AceEditor editor,
final AceEditorCursorPosition pos,
final String prefix,
final AceCompletionCallback callback) {
if (mode.equals(AceEditorMode.XML)) {
callback.invokeWithCompletions(getCompletions());
} else {
callback.invokeWithCompletions(new AceCompletion[]{});
}
}
});
private AceCompletion[] getCompletions() {
return new AceCompletion[]{
new AceCompletionValue(
"stroom-xxx",
"<xmlElm></xmlElm>",
"My meta",
300),
new AceCompletionSnippet(
"stroom-yyy",
"<xmlElm attr1=\"${1}\" attr2=\"${2}\">${3}</xmlElm>${0}",
300,
"My meta",
SafeHtmlUtils.htmlEscape("<xmlElm attr1=\"${1}\" attr2=\"${2}\">${3}</xmlElm>${0}"))
};
}
The addCompletionProvider
method is static so unless we change the 3rd party AceEditor class further we need to implement some kind of AceCompletionsFactory which will dish out the right completions based on the editor involved, i.e. the mode (XML, etc.) and the entity type, i.e. DataSplitter/XSLT/etc.
As a first cut of this feature we could have one config prop per snippet, but we would need the value to be a map with the following keys: name meta snippet
The html could be derived from the name, meta and snippet.
See similar code in ExpressionPresenter and DelegatingCompletionProvider
Another option for implementing configurable completions would be for completions to be a Doc. You would create a completions doc in the tree for say data splitter then there would be a config prop to link the completions for Data Splitter editors to the docRef of the desired set of completions. This would require parsing the completions from text. I think Ace already has code for parsing from text but that is in js and we may want to parse in java so we can cache the snippet objects. See https://cloud9-sdk.readme.io/docs/snippets#section-adding-snippets-to-a-bundle and here for example snippets https://github.com/ajaxorg/ace/tree/master/lib/ace/snippets
We would then have a config prop to link completions for each entity type, currently only data splitter & xslt.
See this for parsing snippets from text https://stackoverflow.com/a/66923593
It would useful if these could be editable by an admin/user, something like Viz scripts maybe or even a dictionary
Here is a jsfiddle for testing out snippets. https://jsfiddle.net/dkz06mwr/4/
Various stroom specific snippets have been baked into xml.js and stroom_query.js so these would need to be moved to app default snippets in stroom.
We also need to ensure that whatever we implement can support tab triggers, e.g. ident<tab>
to trigger the identity xslt skeleton rather than having to hit ctrl-space and then fuzzy find it in the list. The current completions added in for datasource fields and expr funcs do not support tab triggers.
The Ace editor can do code completion snippets. These are really handy for crafting XSLT and other content with a lot of frequently repeated constructs e.g.
It would be even better if we had a range of pre-defined snippets for stroom specific content fragments, e.g. stroom xslt function calls, data splitter constructs, events schema xslt skeletons, etc.
e.g. a snippet to enter
Some XSLT snippets are already hard coded in the XML mode but really we need a custom mode for XSLT that contains all the XSLT keywords and one for datasplitter that contains all the DS elements as keywords.
Ideally the snippets would be configurable rather than being baked in, either at a user level or the app level (or both, with user > app).