diff --git a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/CustomTextPaneKeyAdapter.kt b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/CustomTextPaneKeyAdapter.kt index 4b58a015..d9fea1c5 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/CustomTextPaneKeyAdapter.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/CustomTextPaneKeyAdapter.kt @@ -19,7 +19,6 @@ class CustomTextPaneKeyAdapter( onWebSearchIncluded: () -> Unit ) : KeyAdapter() { - private var updateSuggestionsJob: Job? = null private val scope = CoroutineScope(Dispatchers.Default + SupervisorJob()) private val suggestionsPopupManager = SuggestionsPopupManager(project, textPane, onWebSearchIncluded) @@ -99,8 +98,7 @@ class CustomTextPaneKeyAdapter( } private fun updateSuggestions() { - updateSuggestionsJob?.cancel() - updateSuggestionsJob = scope.launch { + scope.launch { withContext(Dispatchers.Main) { val text = textPane.text val lastAtIndex = text.lastIndexOf('@') @@ -110,10 +108,7 @@ class CustomTextPaneKeyAdapter( val searchText = text.substring(lastAtSearchIndex + 1) if (searchText.isNotEmpty()) { launch { - suggestionsPopupManager.updateSuggestions( - searchText, - updateSuggestionsJob - ) + suggestionsPopupManager.updateSuggestions(searchText) } } } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/suggestion/SuggestionsPopupManager.kt b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/suggestion/SuggestionsPopupManager.kt index 04f3a881..2e950966 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/suggestion/SuggestionsPopupManager.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/suggestion/SuggestionsPopupManager.kt @@ -73,9 +73,9 @@ class SuggestionsPopupManager( list.selectNext() } - suspend fun updateSuggestions(searchText: String? = null, updateSuggestionsJob: Job? = null) { + suspend fun updateSuggestions(searchText: String? = null) { val suggestions = withContext(Dispatchers.Default) { - selectedActionGroup?.getSuggestions(searchText, updateSuggestionsJob) ?: emptyList() + selectedActionGroup?.getSuggestions(searchText) ?: emptyList() } withContext(Dispatchers.Main) { diff --git a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/suggestion/item/SuggestionGroupItems.kt b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/suggestion/item/SuggestionGroupItems.kt index 21c5597c..5311ae4b 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/suggestion/item/SuggestionGroupItems.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/suggestion/item/SuggestionGroupItems.kt @@ -15,7 +15,6 @@ import ee.carlrobert.codegpt.ui.DocumentationDetails import ee.carlrobert.codegpt.util.ResourceUtil.getDefaultPersonas import ee.carlrobert.codegpt.util.file.FileUtil import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job import kotlinx.coroutines.withContext import java.time.Instant import java.time.format.DateTimeParseException @@ -25,7 +24,7 @@ class FileSuggestionGroupItem(private val project: Project) : SuggestionGroupIte override val groupPrefix = "file:" override val icon = AllIcons.FileTypes.Any_type - override suspend fun getSuggestions(searchText: String?, updateSuggestionsJob: Job?): List { + override suspend fun getSuggestions(searchText: String?): List { if (searchText == null) { val projectFileIndex = project.service() return readAction { @@ -34,7 +33,7 @@ class FileSuggestionGroupItem(private val project: Project) : SuggestionGroupIte .toFileSuggestions() } } - return FileUtil.searchProjectFiles(project, searchText, job = updateSuggestionsJob).toFileSuggestions() + return FileUtil.searchProjectFiles(project, searchText).toFileSuggestions() } private fun Iterable.toFileSuggestions() = take(10).map { FileActionItem(it) } @@ -47,7 +46,7 @@ class FolderSuggestionGroupItem(private val project: Project) : SuggestionGroupI override val groupPrefix = "folder:" override val icon = AllIcons.Nodes.Folder - override suspend fun getSuggestions(searchText: String?, updateSuggestionsJob: Job?): List { + override suspend fun getSuggestions(searchText: String?): List { if (searchText == null) { return getProjectFolders(project).toFolderSuggestions() } @@ -82,7 +81,7 @@ class PersonaSuggestionGroupItem : SuggestionGroupItem { override val groupPrefix = "persona:" override val icon = AllIcons.General.User - override suspend fun getSuggestions(searchText: String?, updateSuggestionsJob: Job?): List = + override suspend fun getSuggestions(searchText: String?): List = getDefaultPersonas() .filter { if (searchText.isNullOrEmpty()) { @@ -101,7 +100,7 @@ class DocumentationSuggestionGroupItem : SuggestionGroupItem { override val icon = AllIcons.Toolwindows.Documentation override val enabled = GeneralSettings.getSelectedService() == ServiceType.CODEGPT - override suspend fun getSuggestions(searchText: String?, updateSuggestionsJob: Job?): List = + override suspend fun getSuggestions(searchText: String?): List = service().state.documentations .sortedByDescending { parseDateTime(it.lastUsedDateTime) } .filter { diff --git a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/suggestion/item/SuggestionItem.kt b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/suggestion/item/SuggestionItem.kt index ea11d3ae..a83009c6 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/suggestion/item/SuggestionItem.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/suggestion/item/SuggestionItem.kt @@ -2,7 +2,6 @@ package ee.carlrobert.codegpt.ui.textarea.suggestion.item import com.intellij.openapi.project.Project import ee.carlrobert.codegpt.ui.textarea.CustomTextPane -import kotlinx.coroutines.Job import javax.swing.Icon interface SuggestionItem { @@ -19,8 +18,5 @@ interface SuggestionActionItem : SuggestionItem { interface SuggestionGroupItem : SuggestionItem { val groupPrefix: String - suspend fun getSuggestions( - searchText: String? = null, - updateSuggestionsJob: Job? - ): List + suspend fun getSuggestions(searchText: String? = null): List } \ No newline at end of file diff --git a/src/main/kotlin/ee/carlrobert/codegpt/util/file/FileUtil.kt b/src/main/kotlin/ee/carlrobert/codegpt/util/file/FileUtil.kt index 891df381..6e0fef67 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/util/file/FileUtil.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/util/file/FileUtil.kt @@ -11,11 +11,9 @@ import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ProjectFileIndex import com.intellij.openapi.util.io.FileUtil.createDirectory -import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileFilter import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings.getLlamaModelsPath -import kotlinx.coroutines.Job import java.io.File import java.io.FileOutputStream import java.io.IOException @@ -229,13 +227,12 @@ object FileUtil { project: Project, query: String, maxResults: Int = 6, - job: Job? = null ): List { - val results = TreeSet(compareByDescending { it.score }) + val results = mutableListOf() val fileIndex = project.service() fileIndex.iterateContent({ file -> - if (job != null && job.isCancelled) { + if (results.size > 9) { return@iterateContent false } @@ -260,31 +257,18 @@ object FileUtil { } private fun calculateScore(file: VirtualFile, query: String): Int { - var score = 0 - - val fileName = file.name - if (fileName.contains(query, ignoreCase = true)) { - score += 10 - if (fileName.startsWith(query, ignoreCase = true)) { - score += 5 - } - } - - if (StringUtil.containsIgnoreCase(fileName, query)) { - score += 3 + val fileName = file.nameWithoutExtension.lowercase() + val lowercaseQuery = query.lowercase() + + return when { + fileName == lowercaseQuery -> 100 + fileName.startsWith(lowercaseQuery) -> 50 + lowercaseQuery in fileName -> 25 + fileName.length < lowercaseQuery.length && lowercaseQuery.startsWith(fileName) -> 15 + else -> 0 } - - try { - val content = String(file.contentsToByteArray(), Charsets.UTF_8) - if (content.contains(query, ignoreCase = true)) { - score += 2 - } - } catch (e: Exception) { - // Ignore - } - - return score } + } data class SearchResult(val file: VirtualFile, val score: Int)