美文网首页
monaco-editor搜索

monaco-editor搜索

作者: 大乔是个美少女 | 来源:发表于2020-04-03 17:34 被阅读0次

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>

相关文章

网友评论

      本文标题:monaco-editor搜索

      本文链接:https://www.haomeiwen.com/subject/heskphtx.html