Reputation: 10463
I got an angular 8 app with the fantastic monaco editor embedded for some formula editing. it works well so far but the list of suggestions = CompletionItems needs to change dynamically.
I am using the ngx-monaco-editor module and provide my language definition in the app module:
MonacoEditorModule.forRoot(MyMonacoLanguageConfig)
which is configured similar to this:
const MonacoAirLanguageConfig: NgxMonacoEditorConfig = {
onMonacoLoad: function () {
monaco.languages.register({ id: 'myCoolLang' });
monaco.languages.setLanguageConfiguration('myCoolLang', { ...});
monaco.languages.registerCompletionItemProvider('myCoolLang', {
provideCompletionItems: (model, position) => {
return {
suggestions: [
{
label: 'ThisHasToBeReplaced',
kind: monaco.languages.CompletionItemKind.Function,
insertText: 'ThisHasToBeReplacedWithSomethingCool()',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
}]
};
}
});
}
};
export default MonacoAirLanguageConfig;
Then I am using the monaco editor in my components
<ngx-monaco-editor [options]="editorOptions" (onInit)="initLanguage($event)"></ngx-monaco-editor>
I could call the server in provideCompletionItems but I can't reference my services nor do I have the context from the component where the monaco editor is used. I tried to change the language registration in the onInit event, but thats too late it seems.
I am lost. Sorry :-/ and thanks for any help.
Upvotes: 0
Views: 2231
Reputation: 433
It seems that you're looking for a language server. If I understand your question right, you'd like to get completion items from the server.
You can have a look at monaco-languageclient, this npm package can help you connect Monaco editor with a language server. There is also a language server example written by javascript, I believe you can find any other Monaco language server written by other languages as well if your back-end server is not using Node.js. The completion logic is here, you can return your completion item by customizing this function:
protected completion(params: TextDocumentPositionParams): Thenable<CompletionList | null> {
const document = this.documents.get(params.textDocument.uri);
if (!document) {
return Promise.resolve(null);
}
const jsonDocument = this.getJSONDocument(document);
return this.jsonService.doComplete(document, params.position, jsonDocument);
}
If you're looking for an example to show how to connect Monaco editor with a language server, I have a repository angular-monaco-languageclient. Hope it can help you.
Upvotes: 2
Reputation: 10463
Solution/Workaround I document what I did to achieve asynchronously getting completion items. I am pretty sure it was not intended like this and I will update if I find a better way or get a better answer.
When the ngx module raises the onInit event with the editor instance
(onInit)="initEditor($event)"
I create a model for the editor and then I call the server to get the completionItems and put them in a model property. When the user starts asking for completion items the provideCompletionItems is called and I get the completion items from the model.
initEditor(editor) {
let editorModel = editor.getModel();
<call webserver>
.subscribe(completionItems => editorModel['completionItems'] = completionItems);
and in the language setup:
monaco.languages.registerCompletionItemProvider('air', {
provideCompletionItems: (model, position) => {
return {
suggestions: model.completionItems
};
});
Upvotes: 1