11package me.hiten.completion
22
33import com.intellij.codeInsight.completion.CompletionResultSet
4- import com.intellij.codeInsight.lookup.LookupElement
5- import com.intellij.codeInsight.lookup.LookupElementBuilder
6- import com.intellij.codeInsight.lookup.LookupElementPresentation
7- import com.intellij.codeInsight.lookup.LookupElementRenderer
4+ import com.intellij.codeInsight.completion.CompletionSorter
5+ import com.intellij.codeInsight.completion.impl.PreferStartMatching
6+ import com.intellij.codeInsight.lookup.*
87import com.intellij.util.containers.isNullOrEmpty
98import me.hiten.completion.androidsearch.AndroidDependencySearcher
109import me.hiten.completion.mavensearch.MavenDependencySearcher
10+ import java.awt.Color
1111
1212class DependencySearchManager (private val dependencyText : DependencyText ) {
1313
@@ -27,41 +27,74 @@ class DependencySearchManager(private val dependencyText: DependencyText) {
2727 private fun searchDefault (result : CompletionResultSet ) {
2828 var searchDefault = AndroidDependencySearcher ().searchDefault(dependencyText.text)
2929 if (needNextSearch(searchDefault)) {
30- searchDefault = MavenDependencySearcher ().searchDefault(dependencyText.text)
30+ searchDefault = mergeSearch(searchDefault, MavenDependencySearcher ().searchDefault(dependencyText.text) )
3131 }
3232 val list = searchDefault?.map { createLookupElement(it, dependencyText.text + it.groupId) }?.toList()
3333 list?.let {
34- result.addAllElements(list)
34+ result.restartCompletionOnPrefixChange(dependencyText.text)
35+ result.withRelevanceSorter(
36+ CompletionSorter .emptySorter().weigh(PreferStartMatching ())
37+ ).addAllElements(list)
3538 }
3639 }
3740
3841
3942 private fun searchArtifact (result : CompletionResultSet ) {
4043 var searchArtifact = AndroidDependencySearcher ().searchArtifact(dependencyText.groupId)
4144 if (needNextSearch(searchArtifact)) {
42- searchArtifact = MavenDependencySearcher ().searchArtifact(dependencyText.groupId)
45+ searchArtifact = mergeSearch(searchArtifact, MavenDependencySearcher ().searchArtifact(dependencyText.groupId) )
4346 }
4447 val list = searchArtifact?.map { createLookupElement(it, dependencyText.text + it.artifact) }?.toList()
4548 list?.let {
46- result.addAllElements(list)
49+ result.restartCompletionOnPrefixChange(dependencyText.text)
50+ result.withRelevanceSorter(
51+ CompletionSorter .emptySorter().weigh(PreferStartMatching ())
52+ ).addAllElements(list)
4753 }
4854 }
4955
5056 private fun searchVersion (result : CompletionResultSet ) {
5157 var searchVersion = AndroidDependencySearcher ().searchVersion(dependencyText.groupId, dependencyText.artifactId)
5258 if (needNextSearch(searchVersion)) {
53- searchVersion = MavenDependencySearcher ().searchVersion(dependencyText.groupId, dependencyText.artifactId)
59+ searchVersion = mergeSearch(searchVersion, MavenDependencySearcher ().searchVersion(dependencyText.groupId, dependencyText.artifactId) )
5460 }
5561 val list = searchVersion?.map { createLookupElement(it, dependencyText.text + it.version) }?.toList()
5662 list?.let {
57- result.addAllElements(list)
63+ result.restartCompletionOnPrefixChange(dependencyText.text)
64+ val withRelevanceSorter = result.withRelevanceSorter(
65+ CompletionSorter .emptySorter().weigh(object : LookupElementWeigher (" versionWeigher" ) {
66+ override fun weigh (element : LookupElement ): Comparable <VersionComparable > {
67+ val obj = (element as LookupElementBuilder ).`object ` as DependencySearcher .Result
68+ return VersionComparable (searchVersion!! .indexOf(obj))
69+ }
70+ })
71+ )
72+ withRelevanceSorter.addAllElements(list)
73+ }
74+ }
75+
76+
77+ private fun mergeSearch (before : List <DependencySearcher .Result >? , after : List <DependencySearcher .Result >? ): List <DependencySearcher .Result >? {
78+ if (before.isNullOrEmpty() && after.isNullOrEmpty()) {
79+ return null
80+ }
81+ return ArrayList <DependencySearcher .Result >().apply {
82+ before?.let {
83+ this .addAll(before)
84+ }
85+ after?.let {
86+ this .addAll(after)
87+ }
5888 }
5989 }
6090
6191 private fun needNextSearch (before : List <DependencySearcher .Result >? ): Boolean {
6292 if (before.isNullOrEmpty()) {
6393 return true
6494 }
95+ for (result in before!! ) {
96+ return result.artifact.isNullOrEmpty() && result.version.isNullOrEmpty()
97+ }
6598 return false
6699 }
67100
@@ -75,13 +108,13 @@ class DependencySearchManager(private val dependencyText: DependencyText) {
75108 text = result.getFullTextAndColon()
76109 } else {
77110 if (result.version.isNullOrEmpty() || result.artifact.isNullOrEmpty()) {
78- text = result.getFullText()
111+ text = result.getFullTextAndColon() + " $Q_SYMBOL$quoteArg "
79112 } else {
80113 if (quoteArg.isEmpty()) {
81- quoteArg = " ver_${result.artifact} "
114+ quoteArg = " ver_${result.artifact?.replace( " - " , " _ " ) } "
82115 }
83116 text = " ${result.groupId} :${result.artifact} :$$quoteArg "
84- insertArg = " // ext.$quoteArg = '${result.version} ' "
117+ insertArg = " ext.$quoteArg = '${result.version} ' //please move this code to a unified place. \n "
85118 }
86119 }
87120 val editor = context.editor
@@ -91,27 +124,37 @@ class DependencySearchManager(private val dependencyText: DependencyText) {
91124 val lineStartOffset = document.getLineStartOffset(lineNumber)
92125 val lineEndOffset = document.getLineEndOffset(lineNumber)
93126 val allText = document.text
94- var lineText = allText.substring(lineStartOffset, offset)
95- lineText = lineText.replace(cheatString, text)
127+ var lineText = allText.substring(lineStartOffset, lineEndOffset)
96128
97- if (lineText.contains(" '" )) {
98- lineText + = " '"
99- } else if (lineText.contains(" \" " )) {
100- lineText + = " \" "
129+ var i = lineText.indexOf(" \" " , offset - lineStartOffset)
130+ if (i == - 1 ) {
131+ i = lineText.indexOf(" '" , offset - lineStartOffset)
101132 }
102-
103- if (lineText.contains(" (" )) {
104- lineText + = " )"
133+ i + = lineStartOffset
134+ lineText = if (i > offset) {
135+ allText.substring(lineStartOffset, offset) + allText.substring(i, lineEndOffset)
136+ } else {
137+ allText.substring(lineStartOffset, lineEndOffset)
105138 }
139+ lineText = lineText.replace(cheatString, text)
106140 insertArg?.let {
107141 if (lineText.contains(" '" )) {
108142 lineText = lineText.replace(" '" , " \" " )
109143 }
110- if (! lineText.contains(insertArg)) {
111- lineText + = insertArg
112- }
113144 }
114145 document.replaceString(lineStartOffset, lineEndOffset, lineText)
146+ insertArg?.let {
147+ val stringBuilder = StringBuilder ()
148+ for (char in lineText.toList()) {
149+ if (char == ' ' ) {
150+ stringBuilder.append(char)
151+ } else {
152+ break
153+ }
154+ }
155+ stringBuilder.append(insertArg)
156+ document.insertString(lineStartOffset, stringBuilder.toString())
157+ }
115158 }
116159 }
117160
@@ -121,16 +164,20 @@ class DependencySearchManager(private val dependencyText: DependencyText) {
121164 override fun renderElement (element : LookupElement ? , presentation : LookupElementPresentation ? ) {
122165 element?.let {
123166 val result = (element as LookupElementBuilder ).`object ` as DependencySearcher .Result
124- presentation?.typeText = result.source
125- val quoteArg = dependencyText.quoteArg
167+ presentation?.setTypeText( null , Icons .getIcon( result.source))
168+ var quoteArg = dependencyText.quoteArg
126169 if (quoteArg == null ) {
127170 presentation?.itemText = result.getFullTextAndColon()
128171 } else {
129172 if (result.version.isNullOrEmpty() || result.artifact.isNullOrEmpty()) {
130- presentation?.itemText = result.getFullText () + " $$quoteArg "
173+ presentation?.itemText = result.getFullTextAndColon () + " $Q_SYMBOL $quoteArg "
131174 } else {
175+ if (quoteArg.isEmpty()) {
176+ quoteArg = " ver_${result.artifact?.replace(" -" , " _" )} "
177+ }
132178 presentation?.itemText = " ${result.groupId} :${result.artifact} :$$quoteArg =${result.version} "
133179 }
180+ presentation?.itemTextForeground = Color .BLUE
134181 }
135182 }
136183
@@ -139,6 +186,10 @@ class DependencySearchManager(private val dependencyText: DependencyText) {
139186
140187 companion object {
141188 const val Q_SYMBOL = " #"
189+
190+ class VersionComparable (private val index : Int ) : Comparable<VersionComparable> {
191+ override fun compareTo (other : VersionComparable ): Int = this .index - other.index
192+ }
142193 }
143194
144195}
0 commit comments