refactor(自动完成): 重构代码自动完成逻辑
- 新增 IAutoCompleteHandler 接口,定义自动完成处理的标准 - 实现 SectionAutoCompleteHandler、KeyAutoCompleteHandler 和 ValueAutoComplete 处理器 - 重构 CodeAutoCompleteJob 类,使用新的自动完成处理器 - 更新 RustAutoCompleteProvider 和 RustLanguage 类,适应新的自动完成逻辑 - 优化 RustCompletionItem 类,增加插入后的自动完成处理
This commit is contained in:
parent
ae8b52f358
commit
91961754e0
|
@ -929,104 +929,6 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
||||||
} else if (item == getString(R.string.code_tip)) {
|
} else if (item == getString(R.string.code_tip)) {
|
||||||
viewBinding.codeEditor.getComponent(EditorAutoCompletion::class.java)
|
viewBinding.codeEditor.getComponent(EditorAutoCompletion::class.java)
|
||||||
.requireCompletion()
|
.requireCompletion()
|
||||||
// viewModel.executorService.submit {
|
|
||||||
// try {
|
|
||||||
// val list = ArrayList<CompletionItem>()
|
|
||||||
// //如果不包含:搜索键
|
|
||||||
// val lineNumber = viewBinding.codeEditor.selectedLineNumber
|
|
||||||
// val navigationList =
|
|
||||||
// viewBinding.codeEditor.textAnalyzeResult.navigation
|
|
||||||
// var section: String? = null
|
|
||||||
// if (navigationList != null && navigationList.isNotEmpty()) {
|
|
||||||
// for (navigation in navigationList) {
|
|
||||||
// if (navigation.line > lineNumber) {
|
|
||||||
// break
|
|
||||||
// } else {
|
|
||||||
// section = navigation.label
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// //如果不在任何节内
|
|
||||||
// if (section == null) {
|
|
||||||
// runOnUiThread {
|
|
||||||
// runOnUiThread {
|
|
||||||
// Snackbar.make(
|
|
||||||
// viewBinding.recyclerview,
|
|
||||||
// this.getString(R.string.code_tip_error1),
|
|
||||||
// Snackbar.LENGTH_SHORT
|
|
||||||
// ).show()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return@submit
|
|
||||||
// }
|
|
||||||
// val trueSection =
|
|
||||||
// rustLanguage.autoCompleteProvider.getSectionType(section)
|
|
||||||
// val codeDataBase = CodeDataBase.getInstance(this)
|
|
||||||
// val lineData =
|
|
||||||
// viewBinding.codeEditor.text.getLine(lineNumber).toString()
|
|
||||||
// if (lineData.startsWith('[') && lineData.endsWith(']')) {
|
|
||||||
// runOnUiThread {
|
|
||||||
// Snackbar.make(
|
|
||||||
// viewBinding.recyclerview,
|
|
||||||
// R.string.code_tip_error2,
|
|
||||||
// Snackbar.LENGTH_SHORT
|
|
||||||
// ).show()
|
|
||||||
// }
|
|
||||||
// return@submit
|
|
||||||
// }
|
|
||||||
// val offset = lineData.indexOf(':')
|
|
||||||
// if (offset > -1) {
|
|
||||||
// //如果包含:
|
|
||||||
// runOnUiThread {
|
|
||||||
// Snackbar.make(
|
|
||||||
// viewBinding.recyclerview,
|
|
||||||
// this.getString(R.string.can_not_tip_value),
|
|
||||||
// Snackbar.LENGTH_SHORT
|
|
||||||
// ).show()
|
|
||||||
// }
|
|
||||||
// return@submit
|
|
||||||
// } else {
|
|
||||||
// val codeInfoList = if (lineData.isBlank()) {
|
|
||||||
// codeDataBase.getCodeDao().findCodeBySection(trueSection)
|
|
||||||
// } else {
|
|
||||||
// val number = AppSettings.getValue(
|
|
||||||
// AppSettings.Setting.IdentifiersPromptNumber,
|
|
||||||
// 40
|
|
||||||
// )
|
|
||||||
// codeDataBase.getCodeDao()
|
|
||||||
// .findCodeByKeyFromSection(lineData, trueSection, number)
|
|
||||||
// }
|
|
||||||
// if (codeInfoList != null && codeInfoList.isNotEmpty()) {
|
|
||||||
// val CompletionItemConverter =
|
|
||||||
// CompletionItemConverter.instance.init(this)
|
|
||||||
// codeInfoList.forEach {
|
|
||||||
// list.add(
|
|
||||||
// CompletionItemConverter.codeInfoToCompletionItem(
|
|
||||||
// it
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// runOnUiThread {
|
|
||||||
// Snackbar.make(
|
|
||||||
// viewBinding.recyclerview,
|
|
||||||
// String.format(
|
|
||||||
// this.getString(R.string.code_tip_error3),
|
|
||||||
// SourceFile.getSectionType(section)
|
|
||||||
// ),
|
|
||||||
// Snackbar.LENGTH_SHORT
|
|
||||||
// ).show()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// runOnUiThread {
|
|
||||||
// viewBinding.codeEditor.createEditorAutoCompleteList(list)
|
|
||||||
// }
|
|
||||||
// } catch (e: Exception) {
|
|
||||||
// e.printStackTrace()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
viewBinding.codeEditor.insertText(item, item.length)
|
viewBinding.codeEditor.insertText(item, item.length)
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.coldmint.rust.pro.edit
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.coldmint.rust.core.database.code.CodeDataBase
|
import com.coldmint.rust.core.database.code.CodeDataBase
|
||||||
import com.coldmint.rust.core.tool.DebugHelper
|
import com.coldmint.rust.core.database.file.FileDataBase
|
||||||
import com.coldmint.rust.pro.edit.autoComplete.CodeAutoCompleteJob
|
import com.coldmint.rust.pro.edit.autoComplete.CodeAutoCompleteJob
|
||||||
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
|
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
|
||||||
import io.github.rosemoe.sora.text.CharPosition
|
import io.github.rosemoe.sora.text.CharPosition
|
||||||
|
@ -20,10 +20,14 @@ class RustAutoCompleteProvider {
|
||||||
var keyWord = ""
|
var keyWord = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setDataBase(codeDataBase: CodeDataBase){
|
fun setDataBase(codeDataBase: CodeDataBase) {
|
||||||
this.codeAutoCompleteJob.setCodeDataBase(codeDataBase)
|
this.codeAutoCompleteJob.setCodeDataBase(codeDataBase)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setFileDataBase(fileDataBase: FileDataBase) {
|
||||||
|
this.codeAutoCompleteJob.setFileDataBase(fileDataBase)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求自动完成
|
* 请求自动完成
|
||||||
* @param contentReference ContentReference
|
* @param contentReference ContentReference
|
||||||
|
@ -53,8 +57,8 @@ class RustAutoCompleteProvider {
|
||||||
cursorPrefix
|
cursorPrefix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (codeAutoCompleteJob.needPerform(contentReference, charPosition)) {
|
if (codeAutoCompleteJob.needPerform(lineData)) {
|
||||||
if (keyWord.isBlank()) {
|
if (keyWord.isBlank() && lineData.isBlank()) {
|
||||||
codeAutoCompleteJob.respondingEmptyKeyword(
|
codeAutoCompleteJob.respondingEmptyKeyword(
|
||||||
contentReference,
|
contentReference,
|
||||||
charPosition,
|
charPosition,
|
||||||
|
@ -62,10 +66,10 @@ class RustAutoCompleteProvider {
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
codeAutoCompleteJob.requireAutoComplete(
|
codeAutoCompleteJob.requireAutoComplete(
|
||||||
contentReference,
|
lineData,
|
||||||
charPosition,
|
keyWord,
|
||||||
completionPublisher,
|
completionPublisher, contentReference,
|
||||||
lineData, keyWord
|
charPosition
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
package com.coldmint.rust.pro.edit
|
package com.coldmint.rust.pro.edit
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.util.Log
|
||||||
|
import android.widget.Toast
|
||||||
|
import com.coldmint.rust.core.database.code.CodeDataBase
|
||||||
|
import com.coldmint.rust.pro.tool.AppSettings
|
||||||
|
import com.coldmint.rust.pro.tool.GlobalMethod
|
||||||
import io.github.rosemoe.sora.lang.completion.CompletionItem
|
import io.github.rosemoe.sora.lang.completion.CompletionItem
|
||||||
import io.github.rosemoe.sora.text.Content
|
import io.github.rosemoe.sora.text.Content
|
||||||
import io.github.rosemoe.sora.widget.CodeEditor
|
import io.github.rosemoe.sora.widget.CodeEditor
|
||||||
|
import io.github.rosemoe.sora.widget.component.EditorAutoCompletion
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rust完成器对象
|
* Rust完成器对象
|
||||||
|
@ -50,14 +60,46 @@ class RustCompletionItem(var title: String) : CompletionItem(title) {
|
||||||
*/
|
*/
|
||||||
//CodeEditor editor, Content text, int line, int column
|
//CodeEditor editor, Content text, int line, int column
|
||||||
override fun performCompletion(editor: CodeEditor, text: Content, line: Int, column: Int) {
|
override fun performCompletion(editor: CodeEditor, text: Content, line: Int, column: Int) {
|
||||||
if (label == null) {
|
val finalLabel = label ?: return
|
||||||
return
|
|
||||||
}
|
|
||||||
val keyOffset = RustAutoCompleteProvider.keyWord.length
|
val keyOffset = RustAutoCompleteProvider.keyWord.length
|
||||||
if (keyOffset == 0) {
|
if (keyOffset == 0) {
|
||||||
text.insert(line, column, label)
|
text.insert(line, column, label)
|
||||||
} else {
|
} else {
|
||||||
text.replace(line, column - keyOffset, line, column, label)
|
text.replace(line, column - keyOffset, line, column, label)
|
||||||
}
|
}
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
val codeInfo =
|
||||||
|
if (AppSettings.getValue(AppSettings.Setting.EnglishEditingMode, false)) {
|
||||||
|
CodeDataBase.getInstance(editor.context).getCodeDao()
|
||||||
|
.findCodeByCode(title)
|
||||||
|
} else {
|
||||||
|
CodeDataBase.getInstance(editor.context).getCodeDao()
|
||||||
|
.findCodeByTranslate(title)
|
||||||
|
}
|
||||||
|
if (codeInfo == null) {
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
when (codeInfo.type) {
|
||||||
|
"color" -> {
|
||||||
|
GlobalMethod.showColorPickerDialog(editor.context) {
|
||||||
|
editor.insertText(it, it.length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"int" -> {
|
||||||
|
editor.insertText("1", 1)
|
||||||
|
}
|
||||||
|
"float" -> {
|
||||||
|
editor.insertText("1.0", 3)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
editor.getComponent(EditorAutoCompletion::class.java)
|
||||||
|
.requireCompletion()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,7 +27,6 @@ class RustLanguage : Language, EnglishMode {
|
||||||
private val rustAnalyzeManager by lazy {
|
private val rustAnalyzeManager by lazy {
|
||||||
RustIncrementalAnalyzeManager()
|
RustIncrementalAnalyzeManager()
|
||||||
}
|
}
|
||||||
private val codeAutoCompleteJob = CodeAutoCompleteJob()
|
|
||||||
private val newlineHandler: Array<NewlineHandler> by lazy {
|
private val newlineHandler: Array<NewlineHandler> by lazy {
|
||||||
arrayOf(object : NewlineHandler {
|
arrayOf(object : NewlineHandler {
|
||||||
override fun matchesRequirement(
|
override fun matchesRequirement(
|
||||||
|
@ -71,7 +70,6 @@ class RustLanguage : Language, EnglishMode {
|
||||||
*/
|
*/
|
||||||
fun setCodeDataBase(codeDataBase: CodeDataBase) {
|
fun setCodeDataBase(codeDataBase: CodeDataBase) {
|
||||||
this.codeDataBase = codeDataBase
|
this.codeDataBase = codeDataBase
|
||||||
this.codeAutoCompleteJob.setCodeDataBase(codeDataBase)
|
|
||||||
this.autoCompleteProvider.setDataBase(codeDataBase)
|
this.autoCompleteProvider.setDataBase(codeDataBase)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +82,7 @@ class RustLanguage : Language, EnglishMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setFileDataBase(fileDataBase: FileDataBase) {
|
fun setFileDataBase(fileDataBase: FileDataBase) {
|
||||||
codeAutoCompleteJob.setFileDataBase(fileDataBase)
|
this.autoCompleteProvider.setFileDataBase(fileDataBase)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.coldmint.rust.pro.edit.autoComplete
|
||||||
import com.coldmint.rust.core.SourceFile
|
import com.coldmint.rust.core.SourceFile
|
||||||
import com.coldmint.rust.core.database.code.CodeDao
|
import com.coldmint.rust.core.database.code.CodeDao
|
||||||
import com.coldmint.rust.core.database.code.CodeDataBase
|
import com.coldmint.rust.core.database.code.CodeDataBase
|
||||||
|
import com.coldmint.rust.core.database.code.ValueTypeDao
|
||||||
import com.coldmint.rust.core.database.file.FileDataBase
|
import com.coldmint.rust.core.database.file.FileDataBase
|
||||||
import com.coldmint.rust.core.tool.DebugHelper
|
import com.coldmint.rust.core.tool.DebugHelper
|
||||||
import com.coldmint.rust.core.tool.LineParser
|
import com.coldmint.rust.core.tool.LineParser
|
||||||
|
@ -22,6 +23,7 @@ class CodeAutoCompleteJob {
|
||||||
private var codeDataBase: CodeDataBase? = null
|
private var codeDataBase: CodeDataBase? = null
|
||||||
private var fileDataBase: FileDataBase? = null
|
private var fileDataBase: FileDataBase? = null
|
||||||
private lateinit var codeDao: CodeDao
|
private lateinit var codeDao: CodeDao
|
||||||
|
private lateinit var valueTypeDao: ValueTypeDao
|
||||||
private val identifiersPromptNumber: Int by lazy {
|
private val identifiersPromptNumber: Int by lazy {
|
||||||
AppSettings.getValue(AppSettings.Setting.IdentifiersPromptNumber, 40)
|
AppSettings.getValue(AppSettings.Setting.IdentifiersPromptNumber, 40)
|
||||||
}
|
}
|
||||||
|
@ -42,6 +44,7 @@ class CodeAutoCompleteJob {
|
||||||
DebugHelper.printLog(debugKey, "已链接数据库,数据库状态:${codeDataBase.isOpen}。")
|
DebugHelper.printLog(debugKey, "已链接数据库,数据库状态:${codeDataBase.isOpen}。")
|
||||||
this.codeDataBase = codeDataBase
|
this.codeDataBase = codeDataBase
|
||||||
this.codeDao = codeDataBase.getCodeDao()
|
this.codeDao = codeDataBase.getCodeDao()
|
||||||
|
this.valueTypeDao = codeDataBase.getValueTypeDao()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,10 +70,9 @@ class CodeAutoCompleteJob {
|
||||||
|
|
||||||
|
|
||||||
fun needPerform(
|
fun needPerform(
|
||||||
contentReference: ContentReference,
|
lineData: String
|
||||||
charPosition: CharPosition
|
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return !contentReference.getLine(charPosition.getLine()).startsWith('#')
|
return !lineData.startsWith('#')
|
||||||
}
|
}
|
||||||
|
|
||||||
fun respondingEmptyKeyword(
|
fun respondingEmptyKeyword(
|
||||||
|
@ -102,287 +104,41 @@ class CodeAutoCompleteJob {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private val autoCompleteHandler =
|
||||||
|
arrayOf(SectionAutoCompleteHandler(), KeyAutoCompleteHandler(),ValueAutoComplete())
|
||||||
|
|
||||||
fun requireAutoComplete(
|
fun requireAutoComplete(
|
||||||
contentReference: ContentReference,
|
|
||||||
charPosition: CharPosition,
|
|
||||||
completionPublisher: CompletionPublisher,
|
|
||||||
lineData: String,
|
lineData: String,
|
||||||
keyWord: String
|
keyWord: String,
|
||||||
|
completionPublisher: CompletionPublisher, contentReference: ContentReference,
|
||||||
|
charPosition: CharPosition
|
||||||
) {
|
) {
|
||||||
val finalCodeDataBase = codeDataBase
|
val finalCodeDataBase = codeDataBase
|
||||||
if (finalCodeDataBase == null) {
|
val finalFileDataBase = fileDataBase
|
||||||
|
if (finalCodeDataBase == null || finalFileDataBase == null) {
|
||||||
DebugHelper.printLog(debugKey, "数据库为空,无法使用", isError = true)
|
DebugHelper.printLog(debugKey, "数据库为空,无法使用", isError = true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
DebugHelper.printLog(
|
val section = getSection(charPosition.getLine(), contentReference)
|
||||||
debugKey,
|
val trueSection = if (section == null) {
|
||||||
"行内容[" + lineData + "]关键字[" + keyWord + "]",
|
null
|
||||||
"关联提示列表分析"
|
|
||||||
)
|
|
||||||
if (lineData.startsWith('[')) {
|
|
||||||
//搜索节
|
|
||||||
val name = lineData.subSequence(1, lineData.length).toString()
|
|
||||||
val list = if (isEnglishMode) {
|
|
||||||
finalCodeDataBase.getSectionDao()
|
|
||||||
.searchSectionInfoByCode(name, limitNum = identifiersPromptNumber)
|
|
||||||
} else {
|
|
||||||
finalCodeDataBase.getSectionDao()
|
|
||||||
.searchSectionInfoByTranslate(name, limitNum = identifiersPromptNumber)
|
|
||||||
}
|
|
||||||
list?.forEach {
|
|
||||||
completionPublisher.addItem(CompletionItemConverter.sectionInfoToCompletionItem(it))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
val key = ":"
|
getSectionType(section)
|
||||||
val keyIndex = lineData.lastIndexOf(key)
|
}
|
||||||
if (keyIndex > -1) {
|
autoCompleteHandler.forEach {
|
||||||
//检查是否可响应变量
|
if (it.needPerform(isEnglishMode, lineData, keyWord)) {
|
||||||
val start = "\${"
|
it.perform(
|
||||||
val end = "}"
|
keyWord,
|
||||||
val startIndex = lineData.lastIndexOf(start)
|
identifiersPromptNumber,
|
||||||
if (startIndex > -1) {
|
isEnglishMode,
|
||||||
val endIndex = lineData.lastIndexOf(end)
|
lineData,
|
||||||
if (endIndex < startIndex) {
|
finalCodeDataBase,
|
||||||
//如果}的位置小于${的位置,说明没有闭合
|
codeDao,valueTypeDao,
|
||||||
val keyWord =
|
finalFileDataBase,
|
||||||
lineData.subSequence(startIndex + start.length, lineData.length)
|
section,
|
||||||
.toString()
|
trueSection,
|
||||||
val previousText =
|
completionPublisher
|
||||||
lineData.subSequence(keyIndex + key.length, startIndex).toString()
|
|
||||||
if (keyWord.isNotBlank()) {
|
|
||||||
RustAnalyzer.localVariableNameList.forEach {
|
|
||||||
if (it.name.contains(keyWord)) {
|
|
||||||
completionPublisher.addItem(
|
|
||||||
CompletionItemConverter.localVariableNameToCompletionItem(
|
|
||||||
it, previousText
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
RustAnalyzer.localVariableNameList.forEach {
|
|
||||||
completionPublisher.addItem(
|
|
||||||
CompletionItemConverter.localVariableNameToCompletionItem(
|
|
||||||
it, previousText
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// RustAutoComplete.keyWord = keyWord
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//搜索值
|
|
||||||
// frontIndex 前面冒号的位置
|
|
||||||
val frontIndex = lineData.lastIndexOf(key, keyIndex - key.length)
|
|
||||||
val keyValue = if (frontIndex > -1) {
|
|
||||||
lineData.subSequence(frontIndex + key.length, keyIndex)
|
|
||||||
} else {
|
|
||||||
lineData.subSequence(0, keyIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
val codeInfo =
|
|
||||||
if (isEnglishMode) {
|
|
||||||
codeDao.findCodeByCode(keyValue.toString())
|
|
||||||
} else {
|
|
||||||
codeDao.findCodeByTranslate(keyValue.toString())
|
|
||||||
}
|
|
||||||
DebugHelper.printLog(
|
|
||||||
debugKey,
|
|
||||||
"值[" + keyValue + "]英文模式[" + isEnglishMode + "]代码信息[" + codeInfo + "]关键字[" + keyWord + "]",
|
|
||||||
"值检查"
|
|
||||||
)
|
)
|
||||||
if (codeInfo == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val typeInfo = CompletionItemConverter.getValueType(codeInfo.type)
|
|
||||||
//获取代码的关联列表
|
|
||||||
if (typeInfo != null && typeInfo.list.isNotBlank()) {
|
|
||||||
DebugHelper.printLog(
|
|
||||||
debugKey,
|
|
||||||
"值类型[" + codeInfo.type + "]自动提示列表[" + typeInfo.list + "]",
|
|
||||||
"关联提示"
|
|
||||||
)
|
|
||||||
lineParser.text = typeInfo.list
|
|
||||||
lineParser.analyse { lineNum, lineData, isEnd ->
|
|
||||||
//分析关联提示项目
|
|
||||||
val temCodeInfo =
|
|
||||||
codeDao.findCodeByCode(lineData)
|
|
||||||
DebugHelper.printLog(
|
|
||||||
debugKey,
|
|
||||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是代码[" + (temCodeInfo != null) + "]",
|
|
||||||
"关联提示列表分析"
|
|
||||||
)
|
|
||||||
if (temCodeInfo == null) {
|
|
||||||
if (lineData.startsWith("@file(") && lineData.endsWith(")")) {
|
|
||||||
val fileType = lineData.subSequence(
|
|
||||||
lineData.indexOf('(') + 1,
|
|
||||||
lineData.indexOf(')')
|
|
||||||
)
|
|
||||||
|
|
||||||
val fileInfo = fileDataBase!!.getFileInfoDao()
|
|
||||||
.searchFileInfoByNameAndType(
|
|
||||||
keyWord,
|
|
||||||
fileType.toString(),
|
|
||||||
identifiersPromptNumber
|
|
||||||
)
|
|
||||||
DebugHelper.printLog(
|
|
||||||
debugKey,
|
|
||||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]搜索了[" + fileType + "]类型的文件,返回了[" + (fileInfo?.size
|
|
||||||
?: -1) + "]个结果",
|
|
||||||
"关联提示列表分析"
|
|
||||||
)
|
|
||||||
if (!fileInfo.isNullOrEmpty()) {
|
|
||||||
for (fileTable in fileInfo) {
|
|
||||||
completionPublisher.addItem(
|
|
||||||
CompletionItemConverter.fileTableToCompletionItem(
|
|
||||||
fileTable
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (lineData.startsWith("@customType(") && lineData.endsWith(
|
|
||||||
")"
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
//用户自动值类型提示
|
|
||||||
val customType = lineData.subSequence(
|
|
||||||
lineData.indexOf('(') + 1,
|
|
||||||
lineData.indexOf(')')
|
|
||||||
).toString()
|
|
||||||
fileDataBase!!.getValueDao()
|
|
||||||
.searchValueByKey(
|
|
||||||
keyWord,
|
|
||||||
customType,
|
|
||||||
identifiersPromptNumber
|
|
||||||
)
|
|
||||||
?.forEach {
|
|
||||||
completionPublisher.addItem(
|
|
||||||
CompletionItemConverter.valueTableToCompletionItem(
|
|
||||||
it
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (lineData.startsWith("@type(") && lineData.endsWith(")")) {
|
|
||||||
val type = lineData.subSequence(
|
|
||||||
lineData.indexOf('(') + 1,
|
|
||||||
lineData.indexOf(')')
|
|
||||||
).toString()
|
|
||||||
val list = if (isEnglishMode
|
|
||||||
) {
|
|
||||||
codeDao.findCodeByCodeInType(
|
|
||||||
keyWord,
|
|
||||||
type,
|
|
||||||
identifiersPromptNumber
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
codeDao.findCodeByTranslateInType(
|
|
||||||
keyWord,
|
|
||||||
type,
|
|
||||||
identifiersPromptNumber
|
|
||||||
)
|
|
||||||
}
|
|
||||||
DebugHelper.printLog(
|
|
||||||
debugKey,
|
|
||||||
"关联了值类型[" + type + "]获取[" + (list?.size
|
|
||||||
?: -1) + "]个结果",
|
|
||||||
"值类型引用"
|
|
||||||
)
|
|
||||||
if (!list.isNullOrEmpty()) {
|
|
||||||
list.forEach {
|
|
||||||
completionPublisher.addItem(
|
|
||||||
CompletionItemConverter.codeInfoToCompletionItem(
|
|
||||||
it
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (lineData.startsWith("@section") && lineData.endsWith(
|
|
||||||
")"
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
// val section = lineData.subSequence(
|
|
||||||
// lineData.indexOf('(') + 1,
|
|
||||||
// lineData.indexOf(')')
|
|
||||||
// ).toString()
|
|
||||||
// codeEditor!!.textAnalyzeResult.navigation.forEach {
|
|
||||||
// if (section == getSectionType(it.label)) {
|
|
||||||
// result.add(
|
|
||||||
// CompletionItemConverter.navigationItemToCompletionItem(
|
|
||||||
// it
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
} else {
|
|
||||||
//无法分析的关联项目
|
|
||||||
// result.add(
|
|
||||||
// CompletionItem(
|
|
||||||
// lineData,
|
|
||||||
// String.format(
|
|
||||||
// CompletionItemConverter.associatedTip,
|
|
||||||
// codeInfo.translate
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val show = if (isEnglishMode) {
|
|
||||||
temCodeInfo.code.contains(keyWord)
|
|
||||||
} else {
|
|
||||||
temCodeInfo.translate.contains(keyWord)
|
|
||||||
}
|
|
||||||
DebugHelper.printLog(
|
|
||||||
debugKey,
|
|
||||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是否包含" + keyWord + "关键字[" + show + "]",
|
|
||||||
"关联提示列表分析"
|
|
||||||
)
|
|
||||||
if (show) {
|
|
||||||
completionPublisher.addItem(
|
|
||||||
CompletionItemConverter.codeInfoToCompletionItem(
|
|
||||||
temCodeInfo
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//如果不包含:搜索键
|
|
||||||
val lineNumber = charPosition.getLine()
|
|
||||||
val section = getSection(lineNumber, contentReference)
|
|
||||||
//如果不在任何节内
|
|
||||||
if (section == null) {
|
|
||||||
DebugHelper.printLog(debugKey, "不在任何节内,无法提示。", isError = true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val trueSection = getSectionType(section)
|
|
||||||
val list = if (isEnglishMode) {
|
|
||||||
codeDao.findCodeByEnglishCodeKeyFromSection(
|
|
||||||
keyWord,
|
|
||||||
trueSection,
|
|
||||||
identifiersPromptNumber
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
codeDao
|
|
||||||
.findCodeByKeyFromSection(keyWord, trueSection, identifiersPromptNumber)
|
|
||||||
}
|
|
||||||
if (!list.isNullOrEmpty()) {
|
|
||||||
list.forEach {
|
|
||||||
completionPublisher.addItem(
|
|
||||||
CompletionItemConverter.codeInfoToCompletionItem(it)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DebugHelper.printLog(
|
|
||||||
debugKey,
|
|
||||||
"在${trueSection}节模糊搜索${keyWord}无结果。",
|
|
||||||
isError = true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.coldmint.rust.pro.edit.autoComplete
|
||||||
|
|
||||||
|
import com.coldmint.rust.core.database.code.CodeDao
|
||||||
|
import com.coldmint.rust.core.database.code.CodeDataBase
|
||||||
|
import com.coldmint.rust.core.database.code.ValueTypeDao
|
||||||
|
import com.coldmint.rust.core.database.file.FileDataBase
|
||||||
|
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
|
||||||
|
|
||||||
|
interface IAutoCompleteHandler {
|
||||||
|
|
||||||
|
fun getName(): String
|
||||||
|
fun needPerform(
|
||||||
|
isEnglishMode: Boolean,
|
||||||
|
lineData: String,
|
||||||
|
keyWord: String
|
||||||
|
): Boolean
|
||||||
|
|
||||||
|
fun perform(
|
||||||
|
keyWord: String,
|
||||||
|
identifiersPromptNumber: Int,
|
||||||
|
isEnglishMode: Boolean,
|
||||||
|
lineData: String,
|
||||||
|
codeDataBase: CodeDataBase,
|
||||||
|
codeDao: CodeDao,
|
||||||
|
valueTypeDao: ValueTypeDao,
|
||||||
|
fileDataBase: FileDataBase, section: String?, trueSection: String?,
|
||||||
|
completionPublisher: CompletionPublisher
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.coldmint.rust.pro.edit.autoComplete
|
||||||
|
|
||||||
|
import com.coldmint.rust.core.database.code.CodeDao
|
||||||
|
import com.coldmint.rust.core.database.code.CodeDataBase
|
||||||
|
import com.coldmint.rust.core.database.code.ValueTypeDao
|
||||||
|
import com.coldmint.rust.core.database.file.FileDataBase
|
||||||
|
import com.coldmint.rust.pro.tool.CompletionItemConverter
|
||||||
|
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
|
||||||
|
|
||||||
|
class KeyAutoCompleteHandler : IAutoCompleteHandler {
|
||||||
|
override fun getName(): String {
|
||||||
|
return "键处理器"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun needPerform(isEnglishMode: Boolean, lineData: String, keyWord: String): Boolean {
|
||||||
|
return !lineData.contains(":") && keyWord.isNotBlank()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun perform(
|
||||||
|
keyWord: String,
|
||||||
|
identifiersPromptNumber: Int,
|
||||||
|
isEnglishMode: Boolean,
|
||||||
|
lineData: String,
|
||||||
|
codeDataBase: CodeDataBase,
|
||||||
|
codeDao: CodeDao,
|
||||||
|
valueTypeDao: ValueTypeDao,
|
||||||
|
fileDataBase: FileDataBase,
|
||||||
|
section: String?,
|
||||||
|
trueSection: String?,
|
||||||
|
completionPublisher: CompletionPublisher
|
||||||
|
) {
|
||||||
|
//如果不在任何节内
|
||||||
|
if (section == null || trueSection == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val list = if (isEnglishMode) {
|
||||||
|
codeDao.findCodeByEnglishCodeKeyFromSection(
|
||||||
|
keyWord,
|
||||||
|
trueSection,
|
||||||
|
identifiersPromptNumber
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
codeDao
|
||||||
|
.findCodeByKeyFromSection(keyWord, trueSection, identifiersPromptNumber)
|
||||||
|
}
|
||||||
|
if (!list.isNullOrEmpty()) {
|
||||||
|
list.forEach {
|
||||||
|
completionPublisher.addItem(
|
||||||
|
CompletionItemConverter.codeInfoToCompletionItem(it)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.coldmint.rust.pro.edit.autoComplete
|
||||||
|
|
||||||
|
import com.coldmint.rust.core.database.code.CodeDao
|
||||||
|
import com.coldmint.rust.core.database.code.CodeDataBase
|
||||||
|
import com.coldmint.rust.core.database.code.ValueTypeDao
|
||||||
|
import com.coldmint.rust.core.database.file.FileDataBase
|
||||||
|
import com.coldmint.rust.pro.tool.CompletionItemConverter
|
||||||
|
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
|
||||||
|
|
||||||
|
class SectionAutoCompleteHandler : IAutoCompleteHandler {
|
||||||
|
override fun getName(): String = "节处理器"
|
||||||
|
override fun needPerform(isEnglishMode: Boolean, lineData: String, keyWord: String): Boolean {
|
||||||
|
return lineData.startsWith("[") && !lineData.endsWith("]")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun perform(
|
||||||
|
keyWord: String,
|
||||||
|
identifiersPromptNumber: Int,
|
||||||
|
isEnglishMode: Boolean,
|
||||||
|
lineData: String,
|
||||||
|
codeDataBase: CodeDataBase,
|
||||||
|
codeDao: CodeDao,
|
||||||
|
valueTypeDao: ValueTypeDao,
|
||||||
|
fileDataBase: FileDataBase,
|
||||||
|
section: String?,
|
||||||
|
trueSection: String?,
|
||||||
|
completionPublisher: CompletionPublisher
|
||||||
|
) {
|
||||||
|
val name = lineData.subSequence(1, lineData.length).toString()
|
||||||
|
val list = if (isEnglishMode) {
|
||||||
|
codeDataBase.getSectionDao()
|
||||||
|
.searchSectionInfoByCode(name, limitNum = identifiersPromptNumber)
|
||||||
|
} else {
|
||||||
|
codeDataBase.getSectionDao()
|
||||||
|
.searchSectionInfoByTranslate(name, limitNum = identifiersPromptNumber)
|
||||||
|
}
|
||||||
|
list?.forEach {
|
||||||
|
completionPublisher.addItem(CompletionItemConverter.sectionInfoToCompletionItem(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
package com.coldmint.rust.pro.edit.autoComplete
|
||||||
|
|
||||||
|
import com.coldmint.rust.core.database.code.CodeDao
|
||||||
|
import com.coldmint.rust.core.database.code.CodeDataBase
|
||||||
|
import com.coldmint.rust.core.database.code.ValueTypeDao
|
||||||
|
import com.coldmint.rust.core.database.file.FileDataBase
|
||||||
|
import com.coldmint.rust.pro.tool.CompletionItemConverter
|
||||||
|
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
|
||||||
|
|
||||||
|
class ValueAutoComplete : IAutoCompleteHandler {
|
||||||
|
override fun getName(): String {
|
||||||
|
return "值自动完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun needPerform(isEnglishMode: Boolean, lineData: String, keyWord: String): Boolean {
|
||||||
|
return lineData.contains(":")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun perform(
|
||||||
|
keyWord: String,
|
||||||
|
identifiersPromptNumber: Int,
|
||||||
|
isEnglishMode: Boolean,
|
||||||
|
lineData: String,
|
||||||
|
codeDataBase: CodeDataBase,
|
||||||
|
codeDao: CodeDao,
|
||||||
|
valueTypeDao: ValueTypeDao,
|
||||||
|
fileDataBase: FileDataBase,
|
||||||
|
section: String?,
|
||||||
|
trueSection: String?,
|
||||||
|
completionPublisher: CompletionPublisher
|
||||||
|
) {
|
||||||
|
val symbolPosition = lineData.lastIndexOf(':')
|
||||||
|
val key = lineData.substring(0, symbolPosition)
|
||||||
|
val keyInfo = if (isEnglishMode) {
|
||||||
|
codeDao.findCodeByCode(key)
|
||||||
|
} else {
|
||||||
|
codeDao.findCodeByTranslate(key)
|
||||||
|
}
|
||||||
|
if (keyInfo == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val valueTypeInfo = valueTypeDao.findTypeByType(keyInfo.type) ?: return
|
||||||
|
val type = valueTypeInfo.type
|
||||||
|
if (type.isBlank()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val types = valueTypeInfo.list.split(',')
|
||||||
|
types.forEach {
|
||||||
|
if (it.isNotBlank()) {
|
||||||
|
if (it.startsWith("@")) {
|
||||||
|
//处理特殊语法
|
||||||
|
if (it.startsWith("@file(") && it.endsWith(")")) {
|
||||||
|
val fileType = it.substring(6, it.length - 1)
|
||||||
|
val fileList = fileDataBase.getFileInfoDao()
|
||||||
|
.findFileInfoByType(fileType, identifiersPromptNumber)
|
||||||
|
if (!fileList.isNullOrEmpty()) {
|
||||||
|
fileList.forEach { file ->
|
||||||
|
if (keyWord.isBlank()) {
|
||||||
|
completionPublisher.addItem(
|
||||||
|
CompletionItemConverter.fileTableToCompletionItem(file)
|
||||||
|
)
|
||||||
|
} else if (file.fileName.contains(keyWord)) {
|
||||||
|
completionPublisher.addItem(
|
||||||
|
CompletionItemConverter.fileTableToCompletionItem(file)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val codeInfo = codeDao.findCodeByCode(it)
|
||||||
|
if (codeInfo != null) {
|
||||||
|
if (keyWord.isBlank()) {
|
||||||
|
completionPublisher.addItem(
|
||||||
|
CompletionItemConverter.codeInfoToCompletionItem(codeInfo)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
if (isEnglishMode) {
|
||||||
|
if (codeInfo.translate.contains(keyWord)) {
|
||||||
|
completionPublisher.addItem(
|
||||||
|
CompletionItemConverter.codeInfoToCompletionItem(codeInfo)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (codeInfo.code.contains(keyWord)) {
|
||||||
|
completionPublisher.addItem(
|
||||||
|
CompletionItemConverter.codeInfoToCompletionItem(codeInfo)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user