refactor(edit): 重构自动完成功能

- 移除了 AutoCompleteJob 接口和相关的类- 重新设计了 CodeAutoCompleteJob 类,直接实现自动完成逻辑
- 更新了 RustAutoCompleteProvider 类,使用新的 CodeAutoCompleteJob
- 调整了 RustLanguage 类,集成了新的自动完成提供者
- 优化了自动完成相关的数据结构和方法
This commit is contained in:
Cold-Mint 2025-02-09 11:38:56 +08:00
parent 7395a39857
commit ae8b52f358
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
6 changed files with 190 additions and 300 deletions

View File

@ -9,7 +9,7 @@ import kotlin.collections.HashMap
import kotlin.collections.HashSet import kotlin.collections.HashSet
@Deprecated("已过时") @Deprecated("已过时")
class RustAnalyzer() : EnglishMode { class RustAnalyzer : EnglishMode {
// private val labels: ArrayList<NavigationItem> by lazy { // private val labels: ArrayList<NavigationItem> by lazy {
// ArrayList() // ArrayList()
// } // }

View File

@ -1,8 +1,9 @@
package com.coldmint.rust.pro.edit 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.tool.DebugHelper import com.coldmint.rust.core.tool.DebugHelper
import com.coldmint.rust.pro.edit.autoComplete.AutoCompleteJob 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
import io.github.rosemoe.sora.text.ContentReference import io.github.rosemoe.sora.text.ContentReference
@ -13,33 +14,16 @@ import io.github.rosemoe.sora.text.ContentReference
class RustAutoCompleteProvider { class RustAutoCompleteProvider {
private val key = "自动完成提供者" private val key = "自动完成提供者"
private val jobList = ArrayList<AutoCompleteJob>() private val codeAutoCompleteJob = CodeAutoCompleteJob()
companion object { companion object {
var keyWord = "" var keyWord = ""
} }
/** fun setDataBase(codeDataBase: CodeDataBase){
* 添加任务 this.codeAutoCompleteJob.setCodeDataBase(codeDataBase)
* @param job AutoCompleteJob
*/
fun addJob(job: AutoCompleteJob): AutoCompleteJob {
jobList.add(job)
DebugHelper.printLog(key, "添加了新任务${job.getName()}")
return job
} }
/**
* 移除任务
*/
fun removeJob(job: AutoCompleteJob): AutoCompleteJob {
jobList.remove(job)
DebugHelper.printLog(key, "移除了任务${job.getName()}")
return job
}
/** /**
* 请求自动完成 * 请求自动完成
* @param contentReference ContentReference * @param contentReference ContentReference
@ -53,10 +37,6 @@ class RustAutoCompleteProvider {
completionPublisher: CompletionPublisher, completionPublisher: CompletionPublisher,
bundle: Bundle bundle: Bundle
) { ) {
val requireKey = "请求自动完成"
if (jobList.isEmpty()) {
DebugHelper.printLog(key, "没有任务可执行。", requireKey, true)
} else {
//行内容 //行内容
val lineData = contentReference.getLine(charPosition.getLine()) val lineData = contentReference.getLine(charPosition.getLine())
keyWord = if (lineData.isNullOrBlank()) { keyWord = if (lineData.isNullOrBlank()) {
@ -73,20 +53,15 @@ class RustAutoCompleteProvider {
cursorPrefix cursorPrefix
} }
} }
var executeNumber = 0 if (codeAutoCompleteJob.needPerform(contentReference, charPosition)) {
jobList.forEach {
//如果需要执行
if (it.needPerform(contentReference, charPosition)) {
executeNumber++
if (keyWord.isBlank()) { if (keyWord.isBlank()) {
DebugHelper.printLog(key, "${it.getName()}执行了空关键字响应。", requireKey) codeAutoCompleteJob.respondingEmptyKeyword(
it.respondingEmptyKeyword(
contentReference, contentReference,
charPosition, charPosition,
completionPublisher, lineData completionPublisher, lineData
) )
} else { } else {
it.requireAutoComplete( codeAutoCompleteJob.requireAutoComplete(
contentReference, contentReference,
charPosition, charPosition,
completionPublisher, completionPublisher,
@ -95,9 +70,6 @@ class RustAutoCompleteProvider {
} }
} }
} }
DebugHelper.printLog(key, "执行了${executeNumber}个任务。", requireKey)
}
}
} }

View File

@ -44,7 +44,6 @@ class RustCompletionAdapter : EditorCompletionAdapter() {
parent: ViewGroup, parent: ViewGroup,
isCurrentCursorPosition: Boolean isCurrentCursorPosition: Boolean
): View { ): View {
val editItem = EditItemBinding.inflate(layoutInflater, parent, false) val editItem = EditItemBinding.inflate(layoutInflater, parent, false)
editItem.root.setBackgroundResource(R.drawable.edit_item_background) editItem.root.setBackgroundResource(R.drawable.edit_item_background)
val completionItem = getItem(position) as RustCompletionItem val completionItem = getItem(position) as RustCompletionItem
@ -77,7 +76,6 @@ class RustCompletionAdapter : EditorCompletionAdapter() {
editItem.contentView.isVisible = false editItem.contentView.isVisible = false
editItem.subTitleView.isVisible = false editItem.subTitleView.isVisible = false
editItem.iconView.isVisible = false editItem.iconView.isVisible = false
} else { } else {
editItem.contentView.isVisible = true editItem.contentView.isVisible = true
editItem.subTitleView.isVisible = true editItem.subTitleView.isVisible = true

View File

@ -2,6 +2,7 @@ package com.coldmint.rust.pro.edit
import android.os.Bundle import android.os.Bundle
import android.util.Log
import com.coldmint.rust.core.database.code.CodeDataBase import com.coldmint.rust.core.database.code.CodeDataBase
import com.coldmint.rust.core.database.file.FileDataBase import com.coldmint.rust.core.database.file.FileDataBase
import com.coldmint.rust.core.interfaces.EnglishMode import com.coldmint.rust.core.interfaces.EnglishMode
@ -20,74 +21,50 @@ import io.github.rosemoe.sora.widget.CodeEditor
import io.github.rosemoe.sora.widget.SymbolPairMatch import io.github.rosemoe.sora.widget.SymbolPairMatch
import java.util.* import java.util.*
class RustLanguage() : Language, EnglishMode { class RustLanguage : Language, EnglishMode {
private var isEnglishMode = false private var isEnglishMode = false
private val rustAnalyzeManager by lazy { private val rustAnalyzeManager by lazy {
RustIncrementalAnalyzeManager() RustIncrementalAnalyzeManager()
} }
private val codeAutoCompleteJob: CodeAutoCompleteJob by lazy { private val codeAutoCompleteJob = 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(beforeText: String?, afterText: String?): Boolean { override fun matchesRequirement(
return true text: Content,
position: CharPosition,
style: Styles?
): Boolean {
val currentLine = text.getLine(position.line)
return currentLine.startsWith("[") && !currentLine.endsWith("]")
} }
override fun handleNewline( override fun handleNewline(
beforeText: String, text: Content,
afterText: String?, position: CharPosition,
style: Styles?,
tabSize: Int tabSize: Int
): NewlineHandleResult { ): NewlineHandleResult {
var text = "\n" val currentLine = text.getLine(position.line)
if (beforeText.startsWith("[")) { val currentLineStr = currentLine.toString()
if (beforeText.endsWith("_")) { val appendStr = if (currentLineStr.endsWith("_")) {
text = "name]" UUID.randomUUID().toString().replace("-", "") + "]"
} else if (!beforeText.endsWith("]")) { } else {
text = "]" "]"
} }
} Log.d("RustLanguage", "handleNewline: $appendStr")
val newlineHandleResult = NewlineHandleResult(text, 0) return NewlineHandleResult(appendStr, 0)
return newlineHandleResult
}
})
}*/
private val newlineHandler: Array<NewlineHandler> by lazy {
arrayOf(object : NewlineHandler {
override fun matchesRequirement(text: Content, position: CharPosition, style: Styles?): Boolean {
// 判断是否需要进行换行操作
return false
}
override fun handleNewline(text: Content, position: CharPosition, style: Styles?, tabSize: Int): NewlineHandleResult {
var newText = "\n"
val beforeText = text.toString()
if (beforeText.startsWith("[")) {
if (beforeText.endsWith("_")) {
newText = "name]"
} else if (!beforeText.endsWith("]")) {
newText = "]"
}
}
return NewlineHandleResult(newText, 0)
} }
}) })
} }
private val autoCompleteProvider: RustAutoCompleteProvider by lazy { private val autoCompleteProvider: RustAutoCompleteProvider by lazy {
val a = RustAutoCompleteProvider() RustAutoCompleteProvider()
a.addJob(codeAutoCompleteJob)
a
} }
private var codeDataBase: CodeDataBase? = null private var codeDataBase: CodeDataBase? = null
/** /**
* 设置代码数据库 * 设置代码数据库
* @param codeDataBean CodeDataBase * @param codeDataBean CodeDataBase
@ -95,6 +72,7 @@ class RustLanguage() : Language, EnglishMode {
fun setCodeDataBase(codeDataBase: CodeDataBase) { fun setCodeDataBase(codeDataBase: CodeDataBase) {
this.codeDataBase = codeDataBase this.codeDataBase = codeDataBase
this.codeAutoCompleteJob.setCodeDataBase(codeDataBase) this.codeAutoCompleteJob.setCodeDataBase(codeDataBase)
this.autoCompleteProvider.setDataBase(codeDataBase)
} }
/** /**

View File

@ -1,61 +0,0 @@
package com.coldmint.rust.pro.edit.autoComplete
import android.os.Bundle
import com.coldmint.rust.pro.edit.RustCompletionItem
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
import io.github.rosemoe.sora.text.CharPosition
import io.github.rosemoe.sora.text.ContentReference
/**
* 自动完成工作接口
*/
interface AutoCompleteJob {
/**
* 获取工作名称
*/
fun getName(): String
/**
* 该任务是否需要执行返回true则执行
* @param contentReference ContentReference
* @param charPosition CharPosition
* @return String
*/
fun needPerform(
contentReference: ContentReference,
charPosition: CharPosition
): Boolean
/**
* 处理空白关键字或者行内容响应
* 即不输入任何内容执行的操作
* @return Boolean 返回true即响应返回false反之
*/
fun respondingEmptyKeyword(
contentReference: ContentReference,
charPosition: CharPosition,
completionPublisher: CompletionPublisher, lineData: String
)
/**
* 请求自动完成
* @param contentReference ContentReference
* @param charPosition CharPosition
* @param completionPublisher CompletionPublisher
* @param bundle Bundle
* @return ArrayList<RustCompletionItem>
*/
fun requireAutoComplete(
contentReference: ContentReference,
charPosition: CharPosition,
completionPublisher: CompletionPublisher,
lineData: String,
keyWord: String
)
}

View File

@ -16,7 +16,7 @@ import io.github.rosemoe.sora.text.ContentReference
/** /**
* 代码自动完成项目来自数据库 * 代码自动完成项目来自数据库
*/ */
class CodeAutoCompleteJob : AutoCompleteJob { class CodeAutoCompleteJob {
private val debugKey = "代码自动完成(数据库)" private val debugKey = "代码自动完成(数据库)"
private var codeDataBase: CodeDataBase? = null private var codeDataBase: CodeDataBase? = null
@ -42,6 +42,7 @@ class CodeAutoCompleteJob : AutoCompleteJob {
DebugHelper.printLog(debugKey, "已链接数据库,数据库状态:${codeDataBase.isOpen}") DebugHelper.printLog(debugKey, "已链接数据库,数据库状态:${codeDataBase.isOpen}")
this.codeDataBase = codeDataBase this.codeDataBase = codeDataBase
this.codeDao = codeDataBase.getCodeDao() this.codeDao = codeDataBase.getCodeDao()
} }
/** /**
@ -60,19 +61,19 @@ class CodeAutoCompleteJob : AutoCompleteJob {
AppSettings.getValue(AppSettings.Setting.EnglishEditingMode, false) AppSettings.getValue(AppSettings.Setting.EnglishEditingMode, false)
} }
override fun getName(): String { fun getName(): String {
return debugKey return debugKey
} }
override fun needPerform( fun needPerform(
contentReference: ContentReference, contentReference: ContentReference,
charPosition: CharPosition charPosition: CharPosition
): Boolean { ): Boolean {
return true return !contentReference.getLine(charPosition.getLine()).startsWith('#')
} }
override fun respondingEmptyKeyword( fun respondingEmptyKeyword(
contentReference: ContentReference, contentReference: ContentReference,
charPosition: CharPosition, charPosition: CharPosition,
completionPublisher: CompletionPublisher, completionPublisher: CompletionPublisher,
@ -101,14 +102,15 @@ class CodeAutoCompleteJob : AutoCompleteJob {
} }
override fun requireAutoComplete( fun requireAutoComplete(
contentReference: ContentReference, contentReference: ContentReference,
charPosition: CharPosition, charPosition: CharPosition,
completionPublisher: CompletionPublisher, completionPublisher: CompletionPublisher,
lineData: String, lineData: String,
keyWord: String keyWord: String
) { ) {
if (codeDataBase == null) { val finalCodeDataBase = codeDataBase
if (finalCodeDataBase == null) {
DebugHelper.printLog(debugKey, "数据库为空,无法使用", isError = true) DebugHelper.printLog(debugKey, "数据库为空,无法使用", isError = true)
return return
} }
@ -121,10 +123,10 @@ class CodeAutoCompleteJob : AutoCompleteJob {
//搜索节 //搜索节
val name = lineData.subSequence(1, lineData.length).toString() val name = lineData.subSequence(1, lineData.length).toString()
val list = if (isEnglishMode) { val list = if (isEnglishMode) {
codeDataBase!!.getSectionDao() finalCodeDataBase.getSectionDao()
.searchSectionInfoByCode(name, limitNum = identifiersPromptNumber) .searchSectionInfoByCode(name, limitNum = identifiersPromptNumber)
} else { } else {
codeDataBase!!.getSectionDao() finalCodeDataBase.getSectionDao()
.searchSectionInfoByTranslate(name, limitNum = identifiersPromptNumber) .searchSectionInfoByTranslate(name, limitNum = identifiersPromptNumber)
} }
list?.forEach { list?.forEach {
@ -171,9 +173,7 @@ class CodeAutoCompleteJob : AutoCompleteJob {
} }
} }
// val value =
// lineData.subSequence(keyIndex + key.length, lineData.length).toString().trim()
// LogCat.d("值", value)
//搜索值 //搜索值
// frontIndex 前面冒号的位置 // frontIndex 前面冒号的位置
val frontIndex = lineData.lastIndexOf(key, keyIndex - key.length) val frontIndex = lineData.lastIndexOf(key, keyIndex - key.length)
@ -194,13 +194,16 @@ class CodeAutoCompleteJob : AutoCompleteJob {
"值[" + keyValue + "]英文模式[" + isEnglishMode + "]代码信息[" + codeInfo + "]关键字[" + keyWord + "]", "值[" + keyValue + "]英文模式[" + isEnglishMode + "]代码信息[" + codeInfo + "]关键字[" + keyWord + "]",
"值检查" "值检查"
) )
if (codeInfo != null) { if (codeInfo == null) {
return
}
val typeInfo = CompletionItemConverter.getValueType(codeInfo.type) val typeInfo = CompletionItemConverter.getValueType(codeInfo.type)
//获取代码的关联列表 //获取代码的关联列表
if (typeInfo != null && typeInfo.list.isNotBlank()) { if (typeInfo != null && typeInfo.list.isNotBlank()) {
DebugHelper.printLog( DebugHelper.printLog(
debugKey, debugKey,
"值类型[" + codeInfo.type + "]自动提示列表[" + typeInfo.list + "]", "关联提示" "值类型[" + codeInfo.type + "]自动提示列表[" + typeInfo.list + "]",
"关联提示"
) )
lineParser.text = typeInfo.list lineParser.text = typeInfo.list
lineParser.analyse { lineNum, lineData, isEnd -> lineParser.analyse { lineNum, lineData, isEnd ->
@ -231,7 +234,7 @@ class CodeAutoCompleteJob : AutoCompleteJob {
?: -1) + "]个结果", ?: -1) + "]个结果",
"关联提示列表分析" "关联提示列表分析"
) )
if (fileInfo != null && fileInfo.isNotEmpty()) { if (!fileInfo.isNullOrEmpty()) {
for (fileTable in fileInfo) { for (fileTable in fileInfo) {
completionPublisher.addItem( completionPublisher.addItem(
CompletionItemConverter.fileTableToCompletionItem( CompletionItemConverter.fileTableToCompletionItem(
@ -283,7 +286,8 @@ class CodeAutoCompleteJob : AutoCompleteJob {
} }
DebugHelper.printLog( DebugHelper.printLog(
debugKey, debugKey,
"关联了值类型[" + type + "]获取[" + (list?.size ?: -1) + "]个结果", "关联了值类型[" + type + "]获取[" + (list?.size
?: -1) + "]个结果",
"值类型引用" "值类型引用"
) )
if (!list.isNullOrEmpty()) { if (!list.isNullOrEmpty()) {
@ -346,7 +350,6 @@ class CodeAutoCompleteJob : AutoCompleteJob {
true true
} }
} }
}
} else { } else {
//如果不包含:搜索键 //如果不包含:搜索键
val lineNumber = charPosition.getLine() val lineNumber = charPosition.getLine()
@ -367,7 +370,7 @@ class CodeAutoCompleteJob : AutoCompleteJob {
codeDao codeDao
.findCodeByKeyFromSection(keyWord, trueSection, identifiersPromptNumber) .findCodeByKeyFromSection(keyWord, trueSection, identifiersPromptNumber)
} }
if (list != null && list.isNotEmpty()) { if (!list.isNullOrEmpty()) {
list.forEach { list.forEach {
completionPublisher.addItem( completionPublisher.addItem(
CompletionItemConverter.codeInfoToCompletionItem(it) CompletionItemConverter.codeInfoToCompletionItem(it)
@ -391,7 +394,7 @@ class CodeAutoCompleteJob : AutoCompleteJob {
* @param contentReference ContentReference * @param contentReference ContentReference
* @return String? * @return String?
*/ */
fun getSection(lineNumber: Int, contentReference: ContentReference): String? { private fun getSection(lineNumber: Int, contentReference: ContentReference): String? {
return if (lineNumber > 0) { return if (lineNumber > 0) {
for (i in lineNumber downTo 0) { for (i in lineNumber downTo 0) {
val lineData = contentReference.getLine(i) val lineData = contentReference.getLine(i)
@ -416,7 +419,7 @@ class CodeAutoCompleteJob : AutoCompleteJob {
* @param section String * @param section String
* @return String * @return String
*/ */
fun getSectionType(section: String): String { private fun getSectionType(section: String): String {
if (sectionNameMap.containsKey(section)) { if (sectionNameMap.containsKey(section)) {
return sectionNameMap[section] ?: SourceFile.getSectionType(section) return sectionNameMap[section] ?: SourceFile.getSectionType(section)
} }