[plugin-data] Fix state use jsfunction issue (#237)

* feat(monaco-editor-completion): 隔离不同代码编辑器自动补全的注册,变量声明增加自动补全去掉js函数和state变量的自动补全提示

* feat(state): 状态管理使用JS表达式创建变量的时候提示不可使用其他变量以及JS函数
This commit is contained in:
rhlin 2024-01-11 14:41:45 +08:00 committed by GitHub
parent 9b96d10fb2
commit 1cbecd2497
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 55 additions and 11 deletions

View File

@ -125,7 +125,8 @@ export default {
bindLifeCycles: {},
editorValue: '{}',
hasError: false,
linterWorker: null
linterWorker: null,
completionProvider: null
})
watchEffect(() => {
@ -210,7 +211,7 @@ export default {
return
}
// Lowcode API
initCompletion(editorRef.value.getMonaco())
state.completionProvider = initCompletion(editorRef.value.getMonaco(), editorRef.value.getEditor()?.getModel())
// ESLint worker
state.linterWorker = initLinter(editor, editorRef.value.getMonaco(), state)
@ -226,6 +227,9 @@ export default {
}
onBeforeUnmount(() => {
state.completionProvider.forEach((provider) => {
provider.dispose()
})
// ESLint worker
state.linterWorker?.terminate?.()
})

View File

@ -157,7 +157,7 @@ const getWords = (model, position) => {
const lastWord = model.getWordUntilPosition(lastPosition).word
? model.getWordUntilPosition(lastPosition)
: getCurrentChar(model, lastPosition)
if (!/[\w\.]/.test(lastWord.word)) break
if (!/[\w.]/.test(lastWord.word)) break
words.push(lastWord)
lastPosition.column = lastWord.startColumn
}
@ -172,9 +172,14 @@ const getRange = (position, words) => ({
endColumn: words[words.length - 1].endColumn
})
export const initCompletion = (monacoInstance) => {
export const initCompletion = (monacoInstance, editorModel, conditionFn) => {
const completionItemProvider = {
provideCompletionItems(model, position, _context, _token) {
if (editorModel && model.id !== editorModel.id) {
return {
suggestions: []
}
}
const words = getWords(model, position)
const wordContent = words.map((item) => item.word).join('')
const range = getRange(position, words)
@ -185,9 +190,10 @@ export const initCompletion = (monacoInstance) => {
const snippetSuggestions = getSnippetsSuggestions(monacoInstance, range, wordContent)
// 用户变量数据提示 e.g. this.dataSourceMap.xxx.load()
const userSuggestions = getUserSuggestions(monacoInstance, range, wordContent)
return {
suggestions: [...apiSuggestions, ...snippetSuggestions, ...userSuggestions]
suggestions: [...apiSuggestions, ...snippetSuggestions, ...userSuggestions].filter((item) =>
conditionFn ? conditionFn(item) : true
)
}
},
triggerCharacters: ['.']

View File

@ -46,6 +46,11 @@
<li class="ml20">示例2 function fnName() {}</li>
<li class="ml20">示例3 { getValue: () => {} }</li>
</ul>
<div class="create-content-foot">
<div class="create-content-tip">
注意使用JS表达式定义state变量的时候无法调用state其他变量定义<br />另由于JS函数定义在变量之后也无法调用JS面板定义的函数
</div>
</div>
</div>
</div>
<template #reference>
@ -112,10 +117,11 @@
</template>
<script>
import { reactive, ref, computed, watch } from 'vue'
import { reactive, ref, computed, watch, onBeforeUnmount } from 'vue'
import { Popover, Form, FormItem, Input, ButtonGroup } from '@opentiny/vue'
import { MonacoEditor } from '@opentiny/tiny-engine-common'
import { verifyJsVarName } from '@opentiny/tiny-engine-common/js/verification'
import { initCompletion } from '@opentiny/tiny-engine-common/js/completion'
import * as Monaco from 'monaco-editor'
import { validateMonacoEditorData } from './js/common'
import EditorI18nTool from './EditorI18nTool.vue'
@ -188,8 +194,14 @@ export default {
lineNumbers: true,
//
overviewRulerBorder: false,
renderLineHighlightOnlyWhenFocus: true
}
renderLineHighlightOnlyWhenFocus: true,
quickSuggestions: false, //
suggest: {
showFields: false,
showFunctions: false
}
},
completionProvider: null
})
const changeLanguage = (language) => {
@ -314,8 +326,21 @@ export default {
noSyntaxValidation: true,
noSemanticValidation: true
})
if (variableEditor.value) {
state.completionProvider = initCompletion(
variableEditor.value.editor.getMonaco(),
variableEditor.value.editor.getEditor()?.getModel(),
(item) => item.label !== 'this.state' && !item.label.startsWith('this.state.')
)
}
}
onBeforeUnmount(() => {
state.completionProvider?.forEach((provider) => {
provider.dispose()
})
})
const insertContent = (insertText = '') => {
const monacoEditor = getEditor().editor.getEditor()
const selection = monacoEditor.getSelection()
@ -445,6 +470,11 @@ export default {
margin-top: 8px;
}
}
.create-content-foot {
margin-top: 4px;
font-size: 14px;
line-height: 22px;
}
}
.create-content-description {

View File

@ -76,13 +76,16 @@ export default {
}
// Lowcode API
initCompletion(monaco.value.getMonaco())
state.completionProvider = initCompletion(monaco.value.getMonaco(), monaco.value.getEditor()?.getModel())
// ESLint worker
state.linterWorker = initLinter(editor, monaco.value.getMonaco(), state)
}
onBeforeUnmount(() => {
state.completionProvider?.forEach((provider) => {
provider.dispose()
})
// ESLint worker
state.linterWorker?.terminate?.()
})

View File

@ -26,7 +26,8 @@ const state = reactive({
script: '',
isChanged: false,
hasError: false,
editorSelection: null
editorSelection: null,
completionProvider: null
})
const monaco = ref(null)