Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to access the Monaco instance to add custom languages? #328

Open
xtagon opened this issue Aug 21, 2021 · 3 comments
Open

How to access the Monaco instance to add custom languages? #328

xtagon opened this issue Aug 21, 2021 · 3 comments

Comments

@xtagon
Copy link

xtagon commented Aug 21, 2021

Hi,

Is it possible to access the Monaco instance (not the editor instance) to add custom language/intellisense support?

I thought about modifying the onReady callback to provide both the editor and monaco instances from the iframe, but it seems to me this should really be done in an initializer before any editor components are initialized, not as a callback on individual editors. But I'm not sure how to accomplish that without access to the global.

Any ideas? Thanks!

@dinager
Copy link

dinager commented Feb 24, 2022

I'm facing the same issue, @xtagon have you managed to figure out how to access the monaco instance for adding a custom language?

@xtagon
Copy link
Author

xtagon commented Feb 25, 2022

@dinager I don't know if it can be done without modifying ember-monaco. One idea is to change these lines to return the Monaco instance and not just the editor instance, and then you can in theory use the onReady callback in any way you like: https://github.com/mike-north/ember-monaco/blob/master/addon/components/code-editor.ts#L42-L51

...but I haven't tried it yet

@dinager
Copy link

dinager commented Feb 27, 2022

I managed to define a custom language using the current ember-monaco without modifying it.
here is my editor running:

image

here is my code:

templates/application.hbs

<CodeEditor
  @language="mySpecialLanguage"
  @fillContent={{true}}
  @code={{this.sample1}}
  @onChange={{this.handleChange}}
  @theme="myCoolTheme"
  @onReady={{this.editorReady}}
>
</CodeEditor>

controllers.application.js

import {action} from '@ember/object';
import Ember from 'ember';

export default Ember.Controller.extend({
  sample1: "if($model.has_children, max($model.children[0].age, 10), \"none\")",
  
  @action
  editorReady(editor) {
    const monacoIframe = document.querySelector('iframe[src*="ember-monaco"]');
    const iframeWindow = monacoIframe.contentWindow;
    // Get the editor reference and set monaco global
    this.editor = iframeWindow.editor;
    this.monaco = iframeWindow.monaco;


    // Register a new language
    this.monaco.languages.register({id: 'mySpecialLanguage'});
    // Register a tokens provider for the language

    this.monaco.languages.setMonarchTokensProvider('mySpecialLanguage', {
      tokenizer: {
        root: [
          ['(if|max|min)', 'custom-function'],
          ['\\$[a-zA-Z.-_]*', 'custom-model'],
          ['[0-9]+', 'custom-number'],
          ['".*"', 'custom-string'],
        ],
      },
    });
    //--
    // Define a new theme that contains only rules that match this language
    this.monaco.editor.defineTheme('myCoolTheme', {
      base: 'vs',
      inherit: false,
      rules: [
        {token: 'custom-function', foreground: '#0000FF', fontStyle: 'bold'},
        {token: 'custom-model', foreground: 'FFA500', fontStyle: 'bold'},
        {token: 'custom-number', foreground: '008800'},
        {token: 'custom-string', foreground: 'ff0000'}
      ],
      colors: {
        'editor.foreground': '#000000',
      }
    });
    this.monaco.editor.setTheme('myCoolTheme');

    this.monaco.languages.registerCompletionItemProvider('mySpecialLanguage', {
      provideCompletionItems: () => {
        var suggestions = [
          {
            label: 'ifelse',
            kind: this.monaco.languages.CompletionItemKind.Snippet,
            insertText: ['if (${1:condition}) {', '\t$0', '} else {', '\t', '}'].join('\n'),
            insertTextRules: this.monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
            documentation: 'If-Else Statement',
          },
        ];
        return {suggestions: suggestions};
      }
    });

  }
})


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants