@@ -9,90 +9,72 @@ import com.intellij.lang.javascript.psi.JSIndexedPropertyAccessExpression
99import com.intellij.lang.javascript.psi.JSLiteralExpression
1010import com.intellij.lang.javascript.psi.JSReferenceExpression
1111import com.intellij.patterns.PlatformPatterns
12- import com.intellij.psi.PsiElement
1312import com.intellij.psi.css.StylesheetFile
1413import com.intellij.util.ProcessingContext
1514
16- const val SplitChar = " -"
17- const val DotChar = " ."
15+ private const val SPLIT_CHAR = " -"
16+ private const val DOT_CHAR = " ."
1817
1918class CssModulesClassNameCompletionContributor : CompletionContributor () {
2019
2120 init {
22- val language = PlatformPatterns
23- .psiElement()
24- .withLanguage(JavascriptLanguage .INSTANCE )
21+ val jsPattern = PlatformPatterns .psiElement().withLanguage(JavascriptLanguage .INSTANCE )
2522
2623 extend(
2724 CompletionType .BASIC ,
28- language
25+ jsPattern
2926 .withParent(JSLiteralExpression ::class .java)
3027 .withSuperParent(2 , JSIndexedPropertyAccessExpression ::class .java),
31- CssModulesClassNameCompletionContributorProvider ()
28+ IndexAccessCompletionProvider ()
3229 )
3330 extend(
3431 CompletionType .BASIC ,
35- language
36- .withParent(JSReferenceExpression ::class .java),
37- CssModulesClassNameCompletionContributorWithDotProvider ()
32+ jsPattern.withParent(JSReferenceExpression ::class .java),
33+ DotAccessCompletionProvider ()
3834 )
3935 }
4036
41- private class CssModulesClassNameCompletionContributorProvider : CompletionProvider <CompletionParameters >() {
37+ private class IndexAccessCompletionProvider : CompletionProvider <CompletionParameters >() {
4238 override fun addCompletions (
4339 parameters : CompletionParameters ,
4440 context : ProcessingContext ,
4541 resultSet : CompletionResultSet
4642 ) {
47- val position = parameters.position
48- val stylesheetFile = findReferenceStyleFile(position.parent as JSLiteralExpression ) ? : return
43+ val literal = parameters.position.parent as ? JSLiteralExpression ? : return
44+ val stylesheetFile = findReferenceStyleFile(literal ) ? : return
4945 resultSet.addAllElements(generateLookupElementList(stylesheetFile))
5046 }
5147 }
5248
53- private class CssModulesClassNameCompletionContributorWithDotProvider : CompletionProvider <CompletionParameters >() {
49+ private class DotAccessCompletionProvider : CompletionProvider <CompletionParameters >() {
5450 override fun addCompletions (
5551 parameters : CompletionParameters ,
5652 context : ProcessingContext ,
5753 resultSet : CompletionResultSet
5854 ) {
59-
6055 val position = parameters.position
61- if (position.prevSibling is PsiElement
62- && position.prevSibling.text == DotChar
63- && position.prevSibling.prevSibling is JSReferenceExpression
64- ) {
65- val style = position.prevSibling.prevSibling
66- style.reference?.resolve()?.let { stylesFileImportStatement ->
67- if (stylesFileImportStatement !is ES6ImportedBinding || stylesFileImportStatement.findReferencedElements()
68- .isEmpty()
69- ) return
70- val first = stylesFileImportStatement.findReferencedElements().firstOrNull()
71- first?.let {
72- resultSet.addAllElements(generateLookupElementList(it as StylesheetFile , true ).map { element ->
73- // if choose completion with - , auto make to IndexedAccess
74- LookupElementDecorator .withInsertHandler(element) { context, item ->
75- StylesInsertHandler (item.lookupString.contains(SplitChar )).handleInsert(context, item)
76- }
77- })
56+ val prevSibling = position.prevSibling ? : return
57+ if (prevSibling.text != DOT_CHAR ) return
58+
59+ val styleRef = prevSibling.prevSibling as ? JSReferenceExpression ? : return
60+ val binding = styleRef.reference?.resolve() as ? ES6ImportedBinding ? : return
61+ val stylesheetFile = binding.findReferencedElements().firstOrNull() as ? StylesheetFile ? : return
62+
63+ val elements = generateLookupElementList(stylesheetFile, true ).map { element ->
64+ LookupElementDecorator .withInsertHandler(element) { ctx, item ->
65+ if (item.lookupString.contains(SPLIT_CHAR )) {
66+ convertToBracketSyntax(ctx, item.lookupString)
7867 }
7968 }
8069 }
70+ resultSet.addAllElements(elements)
8171 }
82- }
8372
84- private class StylesInsertHandler (private val needsBracketSyntax : Boolean ) : InsertHandler<LookupElement> {
85- override fun handleInsert (context : InsertionContext , item : LookupElement ) {
86- if (needsBracketSyntax) {
87- val editor = context.editor
88- val document = editor.document
89- val startOffset = context.startOffset
90- val dotPosOffset = startOffset - 1
91- val tailOffset = context.tailOffset
92- val lookupString = item.lookupString
93- document.replaceString(dotPosOffset, tailOffset, " [$lookupString ]" )
94- editor.caretModel.moveToOffset(dotPosOffset + lookupString.length + 2 )
95- }
73+ private fun convertToBracketSyntax (context : InsertionContext , lookupString : String ) {
74+ val document = context.editor.document
75+ val dotOffset = context.startOffset - 1
76+ document.replaceString(dotOffset, context.tailOffset, " ['$lookupString ']" )
77+ context.editor.caretModel.moveToOffset(dotOffset + lookupString.length + 4 )
9678 }
9779 }
9880
0 commit comments