refactor(自动完成): 重构代码自动完成逻辑

- 新增 IAutoCompleteHandler 接口,定义自动完成处理的标准
- 实现 SectionAutoCompleteHandler、KeyAutoCompleteHandler 和 ValueAutoComplete 处理器
- 重构 CodeAutoCompleteJob 类,使用新的自动完成处理器
- 更新 RustAutoCompleteProvider 和 RustLanguage 类,适应新的自动完成逻辑
- 优化 RustCompletionItem 类,增加插入后的自动完成处理
This commit is contained in:
Cold-Mint 2025-02-09 13:50:35 +08:00
parent ae8b52f358
commit 91961754e0
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
9 changed files with 317 additions and 387 deletions

View File

@ -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)

View File

@ -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
) )
} }
} }

View File

@ -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()
}
}
}
}
} }
} }

View File

@ -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)
} }

View File

@ -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
)
}
} }
} }
} }

View File

@ -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
)
}

View File

@ -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)
)
}
}
}
}

View File

@ -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))
}
}
}

View File

@ -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)
)
}
}
}
}
}
}
}
}
}