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
@Deprecated("已过时")
class RustAnalyzer() : EnglishMode {
class RustAnalyzer : EnglishMode {
// private val labels: ArrayList<NavigationItem> by lazy {
// ArrayList()
// }

View File

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

View File

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

View File

@ -2,6 +2,7 @@ package com.coldmint.rust.pro.edit
import android.os.Bundle
import android.util.Log
import com.coldmint.rust.core.database.code.CodeDataBase
import com.coldmint.rust.core.database.file.FileDataBase
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 java.util.*
class RustLanguage() : Language, EnglishMode {
class RustLanguage : Language, EnglishMode {
private var isEnglishMode = false
private val rustAnalyzeManager by lazy {
RustIncrementalAnalyzeManager()
}
private val codeAutoCompleteJob: CodeAutoCompleteJob by lazy {
CodeAutoCompleteJob()
}
/* private val newlineHandler: Array<NewlineHandler> by lazy {
private val codeAutoCompleteJob = CodeAutoCompleteJob()
private val newlineHandler: Array<NewlineHandler> by lazy {
arrayOf(object : NewlineHandler {
override fun matchesRequirement(beforeText: String?, afterText: String?): Boolean {
return true
override fun matchesRequirement(
text: Content,
position: CharPosition,
style: Styles?
): Boolean {
val currentLine = text.getLine(position.line)
return currentLine.startsWith("[") && !currentLine.endsWith("]")
}
override fun handleNewline(
beforeText: String,
afterText: String?,
text: Content,
position: CharPosition,
style: Styles?,
tabSize: Int
): NewlineHandleResult {
var text = "\n"
if (beforeText.startsWith("[")) {
if (beforeText.endsWith("_")) {
text = "name]"
} else if (!beforeText.endsWith("]")) {
text = "]"
val currentLine = text.getLine(position.line)
val currentLineStr = currentLine.toString()
val appendStr = if (currentLineStr.endsWith("_")) {
UUID.randomUUID().toString().replace("-", "") + "]"
} else {
"]"
}
}
val newlineHandleResult = NewlineHandleResult(text, 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)
Log.d("RustLanguage", "handleNewline: $appendStr")
return NewlineHandleResult(appendStr, 0)
}
})
}
private val autoCompleteProvider: RustAutoCompleteProvider by lazy {
val a = RustAutoCompleteProvider()
a.addJob(codeAutoCompleteJob)
a
RustAutoCompleteProvider()
}
private var codeDataBase: CodeDataBase? = null
/**
* 设置代码数据库
* @param codeDataBean CodeDataBase
@ -95,6 +72,7 @@ class RustLanguage() : Language, EnglishMode {
fun setCodeDataBase(codeDataBase: CodeDataBase) {
this.codeDataBase = 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 var codeDataBase: CodeDataBase? = null
@ -42,6 +42,7 @@ class CodeAutoCompleteJob : AutoCompleteJob {
DebugHelper.printLog(debugKey, "已链接数据库,数据库状态:${codeDataBase.isOpen}")
this.codeDataBase = codeDataBase
this.codeDao = codeDataBase.getCodeDao()
}
/**
@ -60,19 +61,19 @@ class CodeAutoCompleteJob : AutoCompleteJob {
AppSettings.getValue(AppSettings.Setting.EnglishEditingMode, false)
}
override fun getName(): String {
fun getName(): String {
return debugKey
}
override fun needPerform(
fun needPerform(
contentReference: ContentReference,
charPosition: CharPosition
): Boolean {
return true
return !contentReference.getLine(charPosition.getLine()).startsWith('#')
}
override fun respondingEmptyKeyword(
fun respondingEmptyKeyword(
contentReference: ContentReference,
charPosition: CharPosition,
completionPublisher: CompletionPublisher,
@ -101,14 +102,15 @@ class CodeAutoCompleteJob : AutoCompleteJob {
}
override fun requireAutoComplete(
fun requireAutoComplete(
contentReference: ContentReference,
charPosition: CharPosition,
completionPublisher: CompletionPublisher,
lineData: String,
keyWord: String
) {
if (codeDataBase == null) {
val finalCodeDataBase = codeDataBase
if (finalCodeDataBase == null) {
DebugHelper.printLog(debugKey, "数据库为空,无法使用", isError = true)
return
}
@ -121,10 +123,10 @@ class CodeAutoCompleteJob : AutoCompleteJob {
//搜索节
val name = lineData.subSequence(1, lineData.length).toString()
val list = if (isEnglishMode) {
codeDataBase!!.getSectionDao()
finalCodeDataBase.getSectionDao()
.searchSectionInfoByCode(name, limitNum = identifiersPromptNumber)
} else {
codeDataBase!!.getSectionDao()
finalCodeDataBase.getSectionDao()
.searchSectionInfoByTranslate(name, limitNum = identifiersPromptNumber)
}
list?.forEach {
@ -171,9 +173,7 @@ class CodeAutoCompleteJob : AutoCompleteJob {
}
}
// val value =
// lineData.subSequence(keyIndex + key.length, lineData.length).toString().trim()
// LogCat.d("值", value)
//搜索值
// frontIndex 前面冒号的位置
val frontIndex = lineData.lastIndexOf(key, keyIndex - key.length)
@ -194,13 +194,16 @@ class CodeAutoCompleteJob : AutoCompleteJob {
"值[" + keyValue + "]英文模式[" + isEnglishMode + "]代码信息[" + codeInfo + "]关键字[" + keyWord + "]",
"值检查"
)
if (codeInfo != null) {
if (codeInfo == null) {
return
}
val typeInfo = CompletionItemConverter.getValueType(codeInfo.type)
//获取代码的关联列表
if (typeInfo != null && typeInfo.list.isNotBlank()) {
DebugHelper.printLog(
debugKey,
"值类型[" + codeInfo.type + "]自动提示列表[" + typeInfo.list + "]", "关联提示"
"值类型[" + codeInfo.type + "]自动提示列表[" + typeInfo.list + "]",
"关联提示"
)
lineParser.text = typeInfo.list
lineParser.analyse { lineNum, lineData, isEnd ->
@ -231,7 +234,7 @@ class CodeAutoCompleteJob : AutoCompleteJob {
?: -1) + "]个结果",
"关联提示列表分析"
)
if (fileInfo != null && fileInfo.isNotEmpty()) {
if (!fileInfo.isNullOrEmpty()) {
for (fileTable in fileInfo) {
completionPublisher.addItem(
CompletionItemConverter.fileTableToCompletionItem(
@ -283,7 +286,8 @@ class CodeAutoCompleteJob : AutoCompleteJob {
}
DebugHelper.printLog(
debugKey,
"关联了值类型[" + type + "]获取[" + (list?.size ?: -1) + "]个结果",
"关联了值类型[" + type + "]获取[" + (list?.size
?: -1) + "]个结果",
"值类型引用"
)
if (!list.isNullOrEmpty()) {
@ -346,7 +350,6 @@ class CodeAutoCompleteJob : AutoCompleteJob {
true
}
}
}
} else {
//如果不包含:搜索键
val lineNumber = charPosition.getLine()
@ -367,7 +370,7 @@ class CodeAutoCompleteJob : AutoCompleteJob {
codeDao
.findCodeByKeyFromSection(keyWord, trueSection, identifiersPromptNumber)
}
if (list != null && list.isNotEmpty()) {
if (!list.isNullOrEmpty()) {
list.forEach {
completionPublisher.addItem(
CompletionItemConverter.codeInfoToCompletionItem(it)
@ -391,7 +394,7 @@ class CodeAutoCompleteJob : AutoCompleteJob {
* @param contentReference ContentReference
* @return String?
*/
fun getSection(lineNumber: Int, contentReference: ContentReference): String? {
private fun getSection(lineNumber: Int, contentReference: ContentReference): String? {
return if (lineNumber > 0) {
for (i in lineNumber downTo 0) {
val lineData = contentReference.getLine(i)
@ -416,7 +419,7 @@ class CodeAutoCompleteJob : AutoCompleteJob {
* @param section String
* @return String
*/
fun getSectionType(section: String): String {
private fun getSectionType(section: String): String {
if (sectionNameMap.containsKey(section)) {
return sectionNameMap[section] ?: SourceFile.getSectionType(section)
}