11package com.tang.intellij.lua.editor.completion
22
3+ import com.intellij.codeInsight.completion.CompletionInitializationContext
34import com.intellij.codeInsight.completion.CompletionParameters
45import com.intellij.codeInsight.completion.CompletionResultSet
56import com.intellij.codeInsight.completion.CompletionType
67import com.intellij.codeInsight.completion.impl.CamelHumpMatcher
78import com.intellij.codeInsight.lookup.LookupElement
89import com.intellij.lang.PsiBuilderFactory
10+ import com.intellij.psi.PsiElement
911import com.intellij.psi.PsiFile
1012import com.intellij.util.Consumer
1113import com.tang.intellij.lua.configuration.IConfigurationManager
14+ import com.tang.intellij.lua.editor.CaretImpl
1215import com.tang.intellij.lua.lang.LuaParserDefinition
1316import com.tang.intellij.lua.lexer.LuaLexer
1417import com.tang.intellij.lua.parser.LuaParser
@@ -35,32 +38,48 @@ object CompletionService {
3538 LuaDocCompletionContributor ()
3639 )
3740
38- fun collectCompletion (psi : PsiFile , pos : Int , consumer : Consumer <LookupElement >) {
39- val config = IConfigurationManager .get(psi.project)
40- val text = psi.text.replaceRange(pos, pos, " emmy" )
41-
42- val parser = LuaParser ()
43- val builder = PsiBuilderFactory .getInstance().createBuilder(LuaParserDefinition (), LuaLexer (), text)
44- val node = parser.parse(LuaParserDefinition .FILE , builder)
45- val tempPsi = node.psi as LuaPsiFile
46- tempPsi.virtualFile = psi.virtualFile
47- val position = tempPsi.findElementAt(pos)
48-
41+ fun collectCompletion (file : PsiFile , caret : Int , consumer : Consumer <LookupElement >) {
42+ val config = IConfigurationManager .get(file.project)
4943 val parameters = CompletionParameters ()
5044 parameters.completionType = CompletionType .BASIC
51- parameters.position = position!!
52- parameters.originalFile = psi
53- parameters.offset = pos
45+ parameters.originalFile = file
46+ parameters.offset = caret
47+ val context = CompletionInitializationContext ()
48+ context.file = file
49+ context.caret = CaretImpl (caret)
50+ context.startOffset = caret
51+ context.dummyIdentifier = CompletionInitializationContext .DUMMY_IDENTIFIER
52+ contributors.forEach { it.beforeCompletion(context) }
53+ if (context.dummyIdentifier.isEmpty()) {
54+ parameters.position = file.findElementAt(caret)!!
55+ } else {
56+ parameters.position = insertDummyIdentifier(context)
57+ }
5458
59+ val text = file.text
5560 val result = CompletionResultSetImpl (consumer)
56- val prefix = findPrefix(text, pos )
61+ val prefix = findPrefix(text, caret )
5762 result.prefixMatcher = CamelHumpMatcher (prefix, config.completionCaseSensitive)
5863
5964 parameters.originalFile.putUserData(CompletionSession .KEY , CompletionSession (parameters, result))
6065
6166 contributors.forEach { it.fillCompletionVariants(parameters, result) }
6267 }
6368
69+ private fun insertDummyIdentifier (context : CompletionInitializationContext ): PsiElement {
70+ val oriFile = context.file
71+ val pos = context.startOffset
72+ val text = oriFile.text.replaceRange(pos, pos, context.dummyIdentifier)
73+ val parser = LuaParser ()
74+ val builder = PsiBuilderFactory .getInstance().createBuilder(LuaParserDefinition (), LuaLexer (), text)
75+ val node = parser.parse(LuaParserDefinition .FILE , builder)
76+ val copy = node.psi as LuaPsiFile
77+ copy.virtualFile = oriFile.virtualFile
78+ val position = copy.findElementAt(pos)
79+ context.file = copy
80+ return position!!
81+ }
82+
6483 private fun findPrefix (text : String , pos : Int ): String {
6584 var i = pos
6685 while (i > 0 ) {
0 commit comments