-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCssModulesClassNameCompletionContributor.kt
More file actions
81 lines (70 loc) · 3.31 KB
/
CssModulesClassNameCompletionContributor.kt
File metadata and controls
81 lines (70 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package com.peppa.css.completion
import com.intellij.codeInsight.completion.*
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementDecorator
import com.intellij.lang.ecmascript6.psi.ES6ImportedBinding
import com.intellij.lang.javascript.JavascriptLanguage
import com.intellij.lang.javascript.psi.JSIndexedPropertyAccessExpression
import com.intellij.lang.javascript.psi.JSLiteralExpression
import com.intellij.lang.javascript.psi.JSReferenceExpression
import com.intellij.patterns.PlatformPatterns
import com.intellij.psi.css.StylesheetFile
import com.intellij.util.ProcessingContext
private const val SPLIT_CHAR = "-"
private const val DOT_CHAR = "."
class CssModulesClassNameCompletionContributor : CompletionContributor() {
init {
val jsPattern = PlatformPatterns.psiElement().withLanguage(JavascriptLanguage.INSTANCE)
extend(
CompletionType.BASIC,
jsPattern
.withParent(JSLiteralExpression::class.java)
.withSuperParent(2, JSIndexedPropertyAccessExpression::class.java),
IndexAccessCompletionProvider()
)
extend(
CompletionType.BASIC,
jsPattern.withParent(JSReferenceExpression::class.java),
DotAccessCompletionProvider()
)
}
private class IndexAccessCompletionProvider : CompletionProvider<CompletionParameters>() {
override fun addCompletions(
parameters: CompletionParameters,
context: ProcessingContext,
resultSet: CompletionResultSet
) {
val literal = parameters.position.parent as? JSLiteralExpression ?: return
val stylesheetFile = findReferenceStyleFile(literal) ?: return
resultSet.addAllElements(generateLookupElementList(stylesheetFile))
}
}
private class DotAccessCompletionProvider : CompletionProvider<CompletionParameters>() {
override fun addCompletions(
parameters: CompletionParameters,
context: ProcessingContext,
resultSet: CompletionResultSet
) {
val position = parameters.position
val prevSibling = position.prevSibling ?: return
if (prevSibling.text != DOT_CHAR) return
val styleRef = prevSibling.prevSibling as? JSReferenceExpression ?: return
val binding = styleRef.reference?.resolve() as? ES6ImportedBinding ?: return
val stylesheetFile = binding.findReferencedElements().firstOrNull() as? StylesheetFile ?: return
val elements = generateLookupElementList(stylesheetFile, true).map { element ->
LookupElementDecorator.withInsertHandler(element) { ctx, item ->
if (item.lookupString.contains(SPLIT_CHAR)) {
convertToBracketSyntax(ctx, item.lookupString)
}
}
}
resultSet.addAllElements(elements)
}
private fun convertToBracketSyntax(context: InsertionContext, lookupString: String) {
val document = context.editor.document
val dotOffset = context.startOffset - 1
document.replaceString(dotOffset, context.tailOffset, "[$lookupString]")
context.editor.caretModel.moveToOffset(context.tailOffset)
}
}
}