npm install monaco-editor
import * as monaco from "monaco-editor";
在Vue中使用
<template>
<div ref="container" style="width: 100vw; height: 100vh"></div>
</template>
<script>
import * as monaco from "monaco-editor";
export default {
data() {
return {
myEditor: {},
};
},
mounted() {
...................................................
}
};
</script>
在mounted中
在monaco里注册一下我们的mylang语言
monaco.languages.register({ id: "mylang" });
monaco.editor.defineTheme("myTheme", {
//基础
base: "vs-dark",
//继承
inherit: true,
//规则
rules: [
{ token: "my-built-in-function", foreground: "ff0000", fontStyle: 'bold' },
{ token: "my-keyword", foreground: "FFA500" },
{ token: "my-function", foreground: "008800" },
],
});
monaco.languages.setMonarchTokensProvider("mylang", {
//将defaultToken设置为invalid,可以查看尚未标记的内容
//defaultToken: "invalid",
tokenizer: {
root: [
[/[{}()\[\]]/, '@brackets'],
[/\b\d*\.\d+([eE][\-+]?\d+)?\b/, "number.float"],
[/\b0[xX][0-9a-fA-F]+\b/, "number.hex"],
[/\b\d+\b/, "number"],
[/\b(if|else|return)\b/, "my-keyword"],
[/\b(and|or|not)\b/, "my-built-in-function"],
[/([a-zA-Z0-9_]+)\s*(\(.*\))/, "@rematch", "@matchfunc"],
[/'([^'\\]|\\.)*$/, "string.invalid"],
[/'/, { token: "string.quote", bracket: "@open", next: "@string" }],
{ include: "@whitespace" },
],
matchfunc: [
[/([a-zA-Z0-9_]+)/, { token: "my-function", next: "@popall"}],
],
string: [
[/[^\\'']+/, "string"],
[/\\./, "string.escape.invalid"],
[/'/, { token: "string.quote", bracket: "@close", next: "@pop" }],
],
comment: [[/#.*$/, "comment"]],
whitespace: [
[/[ \t\r\n]+/, "white"],
[/#.*$/, "comment"],
],
},
//语言大小写不敏感吗
ignoreCase: true,
});
其中这两处的意思是当匹配到([a-zA-Z0-9_]+)\s*((.*))时,不做操作(@rematch的意思是,匹配到了当前文本,但是,不做任何操作)进行next的规则的匹配,也就是进入到matchfunc规则,在matchfunc规则中,如果匹配到([a-zA-Z0-9_]+)则应用’my-function’的token,下一步就是进行popall的操作("@popall":从记号赋予器堆栈弹出所有东西并返回到顶部状态。这可以在恢复期间使用,从深嵌套级别“跳”回初始状态。)
monaco.languages.setLanguageConfiguration("mylang", {
brackets: [
["{", "}"],
["[", "]"],
["(", ")"],
],
autoClosingPairs: [
{ open: "{", close: "}" },
{ open: "[", close: "]" },
{ open: "(", close: ")" },
// { open: '"', close: '"', notIn: ["string"] },
{ open: "'", close: "'", notIn: ["string", "comment"] },
// { open: "`", close: "`", notIn: ["string", "comment"] },
// { open: "/**", close: " */", notIn: ["string"] },
],
});
monaco.languages.registerCompletionItemProvider("mylang", {
provideCompletionItems: () => {
var suggestions = [
{
label: "if",
kind: monaco.languages.CompletionItemKind.Snippet,
insertText: ["if ${0:condition} {", "\t", "}"].join("\n"),
insertTextRules:
monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
detail: "if 声明",
},
{
label: "ifelse",
kind: monaco.languages.CompletionItemKind.Snippet,
insertText: [
"if ${0:condition} {",
"\t",
"} else {",
"\t",
"}",
].join("\n"),
insertTextRules:
monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
detail: "if-else 声明",
},
]
return { suggestions: suggestions };
},
});
monaco.languages.registerHoverProvider("mylang", {
provideHover: function (document, position, token) {
console.log(document.getWordAtPosition(position));
if (document.getWordAtPosition(position) != null) {
const word = document.getWordAtPosition(position).word;
if (word == "if") {
return {
contents: [
{ value: "**if**" },
{
value: [
"这是",
"if",
"的一些介绍",
].join("\n\n"),
},
],
};
}
}
},
});
this.myEditor = monaco.editor.create(this.$refs.container, {
language: "mylang",
theme: "myTheme",
wordWrap: "wordWrapColumn",
wordWrapColumn: 120,
wordWrapMinified: true,
wrappingIndent: "indent",
});