版本
"monaco-editor": "^0.30.1",
"monaco-editor-webpack-plugin": "^6.0.0",
使用代码
<template>
<div class="container1">
<div ref="codeContainer" style="height: 100vh" id="container"/>
</div>
</template>
<script>
import Login from './login'
import WebSocket from '@/components/WebSocket'
import LExprLexer from "../G4Test/rule/LExprLexer.js"
import LExprParser from "../G4Test/rule/LExprParser.js"
var LExprListener = require('../G4Test/rule/LExprListener.js').default
var antlr4 = require('antlr4').default;
// import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'
import * as monaco from 'monaco-editor'
export default {
components: { Login },
data() {
return {
dialog: false,
model: 'login',
treeData: [],
editMsg: null
}
},
created() {},
mounted() {
// this.ParseTree("8+5")
// setTimeout(() => {
// this.ParseTree("8+5*3+2*7*4")
// }, 1000)
this.initMonaco()
// this.iniTest()
},
methods: {
iniTest() {
function createDependencyProposals(range) {
console.log(99900)
// returning a static list of proposals, not even looking at the prefix (filtering is done by the Monaco editor),
// here you could do a server side lookup
return [
{
label: '"lodash"',
kind: monaco.languages.CompletionItemKind.Function,
documentation: 'The Lodash library exported as Node.js modules.',
insertText: '"flodash": "*"',
range: range
},
{
label: '"express"',
kind: monaco.languages.CompletionItemKind.Function,
documentation: 'Fast, unopinionated, minimalist web framework',
insertText: '"express": "*"',
range: range
},
{
label: '"mkdirp"',
kind: monaco.languages.CompletionItemKind.Function,
documentation: 'Recursively mkdir, like <code>mkdir -p</code>',
insertText: '"mkdirp": "*"',
range: range
},
{
label: '"my-third-party-library"',
kind: monaco.languages.CompletionItemKind.Function,
documentation: 'Describe your library here',
insertText: '"${1:my-third-party-library}": "${2:1.2.3}"',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
range: range
}
];
}
monaco.languages.registerCompletionItemProvider('json', {
provideCompletionItems: function (model, position) {
console.log(98876)
// find out if we are completing a property in the 'dependencies' object.
var textUntilPosition = model.getValueInRange({
startLineNumber: 1,
startColumn: 1,
endLineNumber: position.lineNumber,
endColumn: position.column
});
var match = textUntilPosition.match(
/"dependencies"\s*:\s*\{\s*("[^"]*"\s*:\s*"[^"]*"\s*,\s*)*([^"]*)?$/
);
if (!match) {
return { suggestions: [] };
}
var word = model.getWordUntilPosition(position);
var range = {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: word.startColumn,
endColumn: word.endColumn
};
return {
suggestions: createDependencyProposals(range)
};
},
triggerCharacters: [' ', '.']
});
monaco.editor.create(document.getElementById('container'), {
value: '{\n\t"dependencies": {\n\t\t\n\t}\n}\n',
language: 'json'
});
},
setLang() {
monaco.languages.register({id: 'myLang'});
monaco.languages.setMonarchTokensProvider('myLang', {
tokenizer: {
root: [
[/".*?"/, 'string'],
[/'.*?'/, 'variable'],
[/[0-9]+/, 'number']
]
}
});
monaco.languages.registerCompletionItemProvider('myLang', {
provideCompletionItems: (model, position, context, token) => {
console.log('position', position);
console.log('token', token)
console.log('context', context)
console.log('model', model)
console.log(JSON.stringify(model.getLinesContent()));
// //TODO 作为Demo,仅获取当前行的内容。未来需要获取整个文件的内容,因为语法解析需要整个文件的内容。
// let line = model.getLineContent(position.lineNumber);
// const result = await getSuggestions(line, position);
var textUntilPosition = model.getValueInRange({
startLineNumber: 1,
startColumn: 1,
endLineNumber: position.lineNumber,
endColumn: position.column
});
var word = model.getWordUntilPosition(position)
var range = {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: word.startColumn,
endColumn: word.endColumn
};
console.log("替代范围", range, "当前内容", textUntilPosition)
// 获取提示语
let suggestions = []
if( !textUntilPosition.replace(/\s*/g,"") ){
console.log(99438)
suggestions=[
{
label: '"如果"',
kind: monaco.languages.CompletionItemKind.Function,
documentation: '如果语句',
insertText: '如果\n\t<一个布尔>'
}
]
}
return {suggestions: suggestions}
// [
// {
// label: '"lodash"',
// kind: monaco.languages.CompletionItemKind.Function,
// documentation: 'The Lodash library exported as Node.js modules.',
// insertText: '"flodash": "*"'
// },
// {
// label: '"express"',
// kind: monaco.languages.CompletionItemKind.Function,
// documentation: 'Fast, unopinionated, minimalist web framework',
// insertText: '"express": "*"'
// },
// {
// label: '"mkdirp"',
// kind: monaco.languages.CompletionItemKind.Function,
// documentation: 'Recursively mkdir, like <code>mkdir -p</code>',
// insertText: '"mkdirp": "*"'
// },
// {
// label: '"my-third-party-library"',
// kind: monaco.languages.CompletionItemKind.Function,
// documentation: 'Describe your library here',
// insertText: '"${1:my-third-party-library}": "${2:1.2.3}"',
// insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
// }
// ]};
},
triggerCharacters: ["."," "]
});
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" },
],
});
},
initMonaco(){
this.setLang()
this.editMsg = monaco.editor.create(this.$refs.codeContainer, {
language: 'myLang', // 语言,需要引入相应文件
value: '', // 默认值
theme: 'vs-dark', // 编辑器主题
// readOnly: false, // 是否只读
// lineNumbers: true, // 是否显示行数
// lineHeight: 20, // 行高
// tabSize: 2, // 缩进
// automaticLayout: true, // 是否自适应宽高,设置为true的话会有性能问题
})
console.log(888777, this.editMsg)
// 更改光标位置
this.editMsg.onDidChangeCursorPosition(() => {
console.log(9994888)
})
},
change(data) {
if (this.model == 'login') {
this.model = 'register'
this.dialog = false
} else {
this.model = 'login'
}
},
closeDialog() {
this.dialog = false
},
ParseTree(sql){
console.log(999999, antlr4)
// sql = "SELECT * FROM `adb_mysql_dblink`.`adb_mysql_1124qie`.`courses`"
const chars = new antlr4.InputStream(sql);
const lexer = new LExprLexer(chars);
const tokens = new antlr4.CommonTokenStream(lexer);
const parser = new LExprParser(tokens);
parser.buildParseTrees = true;
// const tree = parser.statement();
const tree = parser.s();
console.log(78888, tree, 3, antlr4)
console.log("生成的语法树", tree.toStringTree())
class Visitor {
visitChildren(ctx) {
if (!ctx) {
return;
}
if (ctx.children) {
return ctx.children.map(child => {
if (child.children && child.children.length != 0) {
return child.accept(this);
} else {
return child.getText();
}
});
}
}
}
tree.accept(new Visitor());
// 自定义侦听器
class KeyPrinter extends LExprListener {
// override default listener behavior
exitKey(ctx) {
console.log("Oh, a key!");
}
}
const printer = new KeyPrinter();
antlr4.tree.ParseTreeWalker.DEFAULT.walk(printer, tree);
// const walker = new tree.ParseTreeWalker();
// console.log(8888, walker)
// // 自定义的监听器,采用Listener模式
// const extractor = new LExprListener({
// enterAliasedRelation: this.enterAliasedRelation, // this.enterAliasedRelatio是具体的业务逻辑
// enterQualifiedName: this.enterQualifiedName,
// });
// walker.walk(extractor, tree);
}
}
}
</script>
<style lang="scss" scoped>
.container {
position: relative;
height: 100vh;
}
</style>
浙公网安备 33010602011771号