https://segmentfault.com/a/1190000019666661
https://cloud.tencent.com/developer/article/1597420
<template lang="pug">
div
slot(name="add-before")
label(v-if="showTheme") 主题选择:
el-select(
v-if="showTheme"
v-model="theme",
placeholder="主题色选择",
size="small",
@change="setTheme"
class="margin-bottom-20"
)
el-option(
v-for="option in theme_options",
key="option.value",
:label="option.label",
:value="option.value"
)
slot(name="add-after")
div.code-editor-container(ref="container")
</template>
<script lang="coffee">
has_init_editor = false
HINTS = [ "SELECT", "INSERT", "DELETE", "UPDATE", "CREATE TABLE",
"DROP TABLE", "ALTER TABLE", "CREATE VIEW", "DROP VIEW", "CREATE INDEX", "DROP INDEX", "CREATE PROCEDURE",
"DROP PROCEDURE", "CREATE TRIGGER", "DROP TRIGGER", "CREATE SCHEMA", "DROP SCHEMA", "CREATE DOMAIN",
"ALTER DOMAIN", "DROP DOMAIN", "GRANT", "DENY", "REVOKE", "COMMIT",
"ROLLBACK", "SET TRANSACTION", "DECLARE", "EXPLAN", "OPEN", "FETCH",
"CLOSE", "PREPARE", "EXECUTE", "DESCRIBE", "FORM", "ORDER BY"
]
import * as monaco from 'monaco-editor'
export default {
name: "editor",
data: ->
return {
theme_options:[
{
value:'vs',
label:'默认'
},
{
value:'hc-black',
label:'高亮'
},
{
value:'vs-dark',
label:'深色'
},
],
codes_copy: null, # 内容备份
instance: null
provider: null
}
,
props: {
codes: {
type: String,
default: ""
},
language: {
type: String,
default: 'sql'
},
readOnly: { # 只读类型
type: Boolean,
default: false
},
showTheme: {
type: Boolean,
default: true
},
theme: {
type: String,
default: 'vs'
}
}
mounted: ->
@initEditor()
,
methods: {
updateEditor: (new_val) ->
selection = @instance.getSelection()
range = new monaco.Range(
selection.startLineNumber,
selection.startColumn,
selection.endLineNumber,
selection.endColumn
)
id = { major: 1, minor: 1 }
op = {identifier: id, range: range, text: new_val, forceMoveMarkers: true}
@instance.executeEdits("my-source", [op])
@focusEditor()
focusEditor: ->
setTimeout =>
@instance.focus()
setTheme: ->
monaco.editor.setTheme(@theme)
dispose: ->
if @instance
if @instance.getModel()
@instance.getModel().dispose()
@instance.dispose()
@instance = null
createCompleters: (textUntilPosition) ->
#过滤特殊字符
_textUntilPosition = textUntilPosition.replace(/[\*\[\]@\$\(\)]/g, "").replace(/(\s+|\.)/g, " ")
#切割成数组
arr = _textUntilPosition.split(" ")
#取当前输入值
activeStr = arr[arr.length - 1]
#获得输入值的长度
len = activeStr.length
#获得编辑区域内已经存在的内容
rexp = new RegExp('([^\\w]|^)'+activeStr+'\\w*', "gim")
match = @codes_copy?.match(rexp)
if match
_hints = match.map((ele) ->
rexp = new RegExp(activeStr, "gim")
search = ele.search(rexp)
return ele.substr(search)
)
else
_hints = []
#查找匹配当前输入值的元素
hints = Array.from(new Set([...HINTS, ..._hints])).sort().filter((ele) ->
rexp = new RegExp(ele.substr(0, len), "gim")
if match && match.length == 1 && ele == activeStr || ele.length == 1
return false
else
return activeStr.match(rexp)
)
#添加内容提示
res = hints.map((ele) =>
return {
label: ele,
kind: if HINTS.indexOf(ele) > -1 then monaco.languages.CompletionItemKind.Keyword else monaco.languages.CompletionItemKind.Text,
documentation: ele,
insertText: ele
}
)
return res
initEditor: ->
@dispose()
if not has_init_editor
has_init_editor = true
@provider = monaco.languages.registerCompletionItemProvider("sql", {
provideCompletionItems: (model, position) =>
textUntilPosition = model.getValueInRange({
startLineNumber: position.lineNumber,
startColumn: 1,
endLineNumber: position.lineNumber,
endColumn: position.column
})
suggestions = @createCompleters(textUntilPosition)
return {
suggestions: suggestions
}
})
# monaco 单次只有一个全局主题色,不能针对一个实例配置。
# 最后通过css控制背景色
# monaco.editor.defineTheme('myTheme', {
# base: 'vs',
# inherit: false,
# rules: [{
# background: if @readOnly then 'EDF9FA' else 'FFFFFF'
# }],
# colors: {
# 'editor.foreground': '#000000',
# 'editor.background': '#eee',
# 'editorCursor.foreground': '#8B0000',
# 'editor.lineHighlightBackground': '#0000FF20',
# 'editorLineNumber.foreground': '#008800',
# 'editor.selectionBackground': '#88000030',
# 'editor.inactiveSelectionBackground': '#88000015'
# }
# })
monaco.editor.setTheme(@theme)
@instance = monaco.editor.create(this.$refs["container"], {
value: if @codes_copy then @codes_copy else @codes
language: @language
readOnly: @readOnly
fontSize: '14px',
folding: true,
foldingStrategy: 'indentation', # 代码可分小段折叠
automaticLayout: true, # 自适应布局
overviewRulerBorder: false, # 不要滚动条的边框
scrollBeyondLastLine: false, # 取消代码后面空白
roundedSelection: false # 右侧不显示编辑器预览框
autoIndent: true # 自动缩进
autoIndex: true,
minimap: {
enabled: false # 不要小地图
}
})
@instance.onDidChangeModelContent (e) =>
@codes_copy = @instance.getValue()
# @$emit('onCodeChange',@instance.getValue(), e)
if not @readOnly
@focusEditor()
}
beforeDestory: ->
@dispose()
@provider.dispose()
@provider = null
}
</script>
<style lang="less" scoped>
.code-editor-container {
border: 1px solid #eee;
min-height: 500px;
height: 100%;
}
</style>
网友评论