mirror of
https://github.com/lana-k/sqliteviz.git
synced 2025-12-08 11:08:55 +08:00
106 lines
2.4 KiB
Vue
106 lines
2.4 KiB
Vue
<template>
|
|
<div class="codemirror-container">
|
|
<codemirror v-model="query" :options="cmOptions" @changes="onCmChange" />
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import CM from 'codemirror'
|
|
import { codemirror } from 'vue-codemirror'
|
|
import 'codemirror/lib/codemirror.css'
|
|
import 'codemirror/mode/sql/sql.js'
|
|
import 'codemirror/theme/neo.css'
|
|
import 'codemirror/addon/hint/show-hint.js'
|
|
import 'codemirror/addon/hint/show-hint.css'
|
|
import 'codemirror/addon/hint/sql-hint.js'
|
|
import { debounce } from 'debounce'
|
|
|
|
const sqlHint = CM.hint.sql
|
|
CM.hint.sql = (cm, options) => {
|
|
const token = cm.getTokenAt(cm.getCursor()).string.toUpperCase()
|
|
const result = sqlHint(cm, options)
|
|
// Don't show the hint if there is only one option
|
|
// and the token is already completed with this option
|
|
if (result.list.length === 1 && result.list[0].text.toUpperCase() === token) {
|
|
result.list = []
|
|
}
|
|
return result
|
|
}
|
|
|
|
export default {
|
|
name: 'SqlEditor',
|
|
props: ['value'],
|
|
components: {
|
|
codemirror
|
|
},
|
|
data () {
|
|
return {
|
|
query: this.value,
|
|
cmOptions: {
|
|
// codemirror options
|
|
tabSize: 4,
|
|
mode: 'text/x-mysql',
|
|
theme: 'neo',
|
|
lineNumbers: true,
|
|
line: true
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
tables () {
|
|
const tables = {}
|
|
if (this.$store.state.schema) {
|
|
this.$store.state.schema.forEach(table => {
|
|
tables[table.name] = table.columns.map(column => column.name)
|
|
})
|
|
}
|
|
return tables
|
|
}
|
|
},
|
|
watch: {
|
|
query () {
|
|
this.$emit('input', this.query)
|
|
}
|
|
},
|
|
methods: {
|
|
onCmChange: debounce(function (editor) {
|
|
// Don't show autocomplete after a space or semicolon or in string literals
|
|
const ch = editor.getTokenAt(editor.getCursor()).string.slice(-1)
|
|
const tokenType = editor.getTokenAt(editor.getCursor()).type
|
|
if (tokenType === 'string' || !ch || ch === ' ' || ch === ';') {
|
|
return
|
|
}
|
|
|
|
const hintOptions = {
|
|
tables: this.tables,
|
|
completeSingle: false,
|
|
completeOnSingleClick: true,
|
|
alignWithWord: false
|
|
}
|
|
|
|
CM.showHint(editor, CM.hint.sql, hintOptions)
|
|
}, 400)
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.codemirror-container {
|
|
flex-grow: 1;
|
|
min-height: 0;
|
|
}
|
|
|
|
>>> .vue-codemirror {
|
|
height: 100%;
|
|
max-height: 100%;
|
|
}
|
|
>>> .CodeMirror {
|
|
height: 100%;
|
|
max-height: 100%;
|
|
}
|
|
>>> .CodeMirror-cursor {
|
|
width: 1px;
|
|
background: var(--color-text-base);
|
|
}
|
|
</style>
|