monaco-react icon indicating copy to clipboard operation
monaco-react copied to clipboard

Docs for adding custom language library

Open houston88 opened this issue 3 years ago • 12 comments

This is probably more of me not understanding how to use UMD libraries, but I am attempting to add yaml schema support to my monaco-react editor using this library: https://github.com/pengx17/monaco-yaml

They provide an example for UMD here: https://github.com/pengx17/monaco-yaml/blob/master/examples/umd/index.html

I am guessing I would need to add /vs/language/yaml following to the monaco.config:

monaco.config({
  paths: {
    monacoLoader: '/monaco-editor/min/vs/loader.js',
    vs: '/monaco-editor/min/vs',
    'vs/language/yaml': '/monaco-yaml'
  }
});

And then initialize or use the the editor provided by the monaco-yaml monaco.contribution,js? A little fuzzy on that part. Any help appreciated. Thanks!

In theory full yaml language support (with json schema) will make it into monaco-editor in a future release.

houston88 avatar Feb 24 '21 21:02 houston88

Hey @houston88, I'm trying to accomplish the exact same thing this week. I'm wondering if you managed to make any progress?

underyx avatar Mar 01 '21 16:03 underyx

@underyx Kind of put it on a shelf for now. I am thinking I could "eject" the CRA and then follow the guide for the webpack way of including the library.

houston88 avatar Mar 01 '21 18:03 houston88

Ah, I see. I've actually already ejected a while back, so that should be no problem.

underyx avatar Mar 01 '21 18:03 underyx

I am also trying to do this. Any one have luck?

Jacqueline-ms avatar Apr 05 '21 16:04 Jacqueline-ms

any new on this?

nadir-albajari-hs avatar Mar 16 '22 01:03 nadir-albajari-hs

I found a work around, let me find and post it.

Jacqueline-ms avatar Mar 16 '22 02:03 Jacqueline-ms

@Jacqueline-ms appreciate anything you can share!

amin-nas avatar Apr 06 '22 11:04 amin-nas

amin-nas I think I got my code from here: https://stackoverflow.com/questions/71710312/a-working-sample-of-code-action-and-quick-fix-in-the-playground


loader.init().then((monaco) => {
        // Register a new language
        monaco.languages.register({ id: "mySpecialLanguage" });

        // Register a tokens provider for the language
        monaco.languages.setMonarchTokensProvider("mySpecialLanguage", {
          tokenizer: {
            root: [
              [/\[[a-zA-Z 0-9:]+\]/, "custom-date"],
              [/\/\/.*/g, "comment"],
            ]
          }
        });

        // Define a new theme that contains only rules that match this language
        monaco.editor.defineTheme("myCoolTheme", {
          base: "vs-dark",
          inherit: true,
          rules: [
            // { token: "custom-info", foreground: "808080" },
            // { token: "custom-error", foreground: "ff0000", fontStyle: "bold" },
            // { token: "custom-notice", foreground: "FFA500" },
            // { token: "custom-date", foreground: "008800" },
            { token: "comment", foreground: "608b4e" },
          ]
        });

        // Register a completion item provider for the new language
        monaco.languages.registerCompletionItemProvider("mySpecialLanguage", {
          provideCompletionItems: () => {
            var suggestions = [
              {
                label: "simpleText",
                kind: monaco.languages.CompletionItemKind.Text,
                insertText: "simpleText"
              },
              {
                label: "testing",
                kind: monaco.languages.CompletionItemKind.Keyword,
                insertText: "testing(${1:condition})",
                insertTextRules:
                  monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
              },
              {
                label: "ifelse",
                kind: monaco.languages.CompletionItemKind.Snippet,
                insertText: [
                  "if (${1:condition}) {",
                  "\t$0",
                  "} else {",
                  "\t",
                  "}"
                ].join("\n"),
                insertTextRules:
                  monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
                documentation: "If-Else Statement"
              }
            ];
            return { suggestions: suggestions };
          }
        });
      });

<Editor
        className="startingEditor"
          height="300px"
          theme="myCoolTheme"
          language="mySpecialLanguage"
          value={initialValue}
          onChange={handleEditorChange}
      />

Jacqueline-ms avatar Apr 06 '22 20:04 Jacqueline-ms

@Jacqueline-ms are you able to provide the full file for your snippet here? I am not able to find anything that declares the loader variable. Thank you very much.

kduraiswami avatar Apr 25 '22 16:04 kduraiswami

@Jacqueline-ms are you able to provide the full file for your snippet here? I am not able to find anything that declares the loader variable. Thank you very much.

The loader comes from this very repo.

import { loader } from "@monaco-editor/react"

See the project readme section on using the loader.

gknapp avatar Apr 25 '23 15:04 gknapp

How does this work with the Monaco Editor playground examples? I'd like to constrain and provide suggestions for document structure and valid field values as shown here.

How do you set the model to pick up your schema? The playground sets the model (and not the language, as it's a subset of JSON). That's not something I've seen code for with @monaco-editor/react.

gknapp avatar Apr 25 '23 15:04 gknapp

I found a solution to applying a custom schema to a language in a neighbouring issue. I applied the example code from the Monaco playground and used it in a function passed to the onMount prop, as this has the editor in scope.

const CodeEditor = (props) => {
  function onMount(editor, monaco) {
    const modelUri = "foo://myapp/custom.json"
    const model = monaco.editor.createModel(
      `{ "type": "unknown" }`, "json", monaco.Uri.parse(modelUri)
    )
    editor.setModel(model)
    
    monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
      ...monaco.languages.json.jsonDefaults.diagnosticOptions,
      allowComments: true,
      schemas: [
        {
          uri: "foo://myapp/segment/type",
          fileMatch: ["*.json"],
          schema: {
            type: "object",
            properties: {
              type: {
                enum: ["customType1", "customType2"],
              }
            },
          },
        }
      ],
      validate: true
    })
  }

  return (
    <Editor
      onMount={onMount}
      language="json"
    />
  )
}

Would it be useful to add example code on applying a schema to the docs?

gknapp avatar Apr 26 '23 15:04 gknapp