Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Provide type hints to monaco editor

I am trying to provide intellisense / code completion into a javascript editor using the Monaco editor. The code needs to be valid javascript, not typescript.

Given some user entered script like this:

function onMyEvent(event)
{
    event.someProperty
}

I want to provide code completion on the event parameter, which is a typescript class I have the t.ds of, and can infer at runtime.

Ideally, I would just like to tell Monaco that the type of event is SomeEventClass, and let it do the rest. Even if that meant adding type hints to the script. But I can't see how to do that. I tried using JSDoc syntax and various combinations in the user script, but it looks like thats blocked FTB see: https://github.com/Microsoft/monaco-editor/issues/203 and Adding JavaScript type hints for VSCode/Monaco Intellisence

I also tried injecting a dynamic d.ts, as per https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-configure-javascript-defaults

But declaring the function didn't seem to mean anything to the editor. Declaring a new class definitely worked, I just can't work out how to tell Monaco that event in that function is a specific type.

I can see the registerCompletionItemProvider API, but that doesn't give you any context of where the item was declared etc, and also doesn't let me automatically use the d.ts file that I want to.

like image 246
Jon N Avatar asked Mar 27 '17 02:03

Jon N


People also ask

What is the use of Monaco editor?

The Monaco Editor is the code editor that powers VS Code. A good page describing the code editor's features is here. It is licensed under the MIT License and supports Edge, Chrome, Firefox, Safari and Opera. The Monaco editor is not supported in mobile browsers or mobile web frameworks.

How do I use editor in react in Monaco?

The easiest way to use the react-monaco-editor with create-react-app is to use the react-app-rewired project. For setting it up, the following steps are required: Install react-app-rewired : npm install -D react-app-rewired. Replace react-scripts by react-app-rewired in the scripts section of your packages.

How do I start Monaco editor?

You'll need to copy the files from node_modules/monaco-editor/min/vs to your preferred location of choice. Since I'm using ASP.NET Core, I use gulp to copy the files from node_modules to wwwroot/js/vs . Here is condensed sample of how to set up the Monaco Editor, since I could not find a quick start elsewhere.


2 Answers

As of Monaco version 0.90, since https://github.com/Microsoft/monaco-editor/issues/203 has been fixed, you can add achieve this partially if you use JSDoc in the editing code.

For this code in the left side of the Monaco playgound:

    // validation settings
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
    noSemanticValidation: true,
    noSyntaxValidation: false
});

// compiler options
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
    target: monaco.languages.typescript.ScriptTarget.ES6,
    allowNonTsExtensions: true,
    allowJs: true
});

// extra libraries
monaco.languages.typescript.javascriptDefaults.addExtraLib([
    'declare class SomeEventType {',
    '    /**',
    '     * Heres the doco for someProperty',
    '     */',
    '    someProperty: string',
    '}',
].join('\n'), 'filename/facts.d.ts');

var jsCode = [
    '"use strict";',
    '',
    "/**",
    " * @param {SomeEventType} event",
    " */",
    "function onMyEvent(event) {",
    "",
    "}"
].join('\n');

monaco.editor.create(document.getElementById("container"), {
    value: jsCode,
    language: "javascript"
});

Means that the editor can now interpret the event parameter as a SomeEventType:

editor screenshot showing code complete

like image 106
Jon N Avatar answered Sep 22 '22 14:09

Jon N


Put this in the editor in the Monaco Playground:

monaco.editor.create(document.getElementById("container"), {
    value: "function hello() {\n\talert('Hello world!');\n}",
    language: "typescript"
});

const fact = `declare function onMyEvent(event: string): void; 
`;
const factFilename = 'myCustomNamespace1';
this.monaco.languages.typescript.typescriptDefaults.addExtraLib(fact, factFilename);

Now when you type onMyEvent in the right-hand pane, you'll get enter image description here

like image 31
Josh Wulf Avatar answered Sep 20 '22 14:09

Josh Wulf