1
+ /* ******************************************************************************
2
+ * Copyright (c) 2024 Red Hat, Inc.
3
+ * Distributed under license by Red Hat, Inc. All rights reserved.
4
+ * This program is made available under the terms of the
5
+ * Eclipse Public License v2.0 which accompanies this distribution,
6
+ * and is available at http://www.eclipse.org/legal/epl-v20.html
7
+ *
8
+ * Contributors:
9
+ * Red Hat, Inc. - initial API and implementation
10
+ ******************************************************************************/
1
11
package com.redhat.devtools.intellij.kubernetes.editor.inlay.selector
2
12
3
13
import com.intellij.codeInsight.hints.InlayHintsSink
4
14
import com.intellij.codeInsight.hints.presentation.InlayPresentation
15
+ import com.intellij.codeInsight.hints.presentation.PresentationFactory
16
+ import com.intellij.codeInsight.navigation.actions.GotoDeclarationAction
5
17
import com.intellij.openapi.editor.Editor
6
18
import com.intellij.psi.PsiElement
7
- import com.intellij.psi.util.PsiTreeUtil
8
- import com.redhat.devtools.intellij.common.validation.KubernetesTypeInfo
9
- import com.redhat.devtools.intellij.kubernetes.editor.util.getKind
10
- import com.redhat.devtools.intellij.kubernetes.editor.util.getMatchExpressions
11
- import com.redhat.devtools.intellij.kubernetes.editor.util.getMatchLabels
12
- import com.redhat.devtools.intellij.kubernetes.editor.util.getMetadataName
13
- import com.redhat.devtools.intellij.kubernetes.editor.util.hasKindAndName
14
- import com.redhat.devtools.intellij.kubernetes.editor.util.isMatchingExpressions
15
- import com.redhat.devtools.intellij.kubernetes.editor.util.isMatchingLabels
16
- import org.jetbrains.yaml.psi.YAMLKeyValue
17
- import org.jetbrains.yaml.psi.YAMLMapping
19
+ import com.intellij.ui.IconManager
20
+ import com.intellij.ui.awt.RelativePoint
21
+ import com.redhat.devtools.intellij.kubernetes.editor.util.PsiFiles
22
+ import com.redhat.devtools.intellij.kubernetes.editor.util.getAllElements
23
+ import com.redhat.devtools.intellij.kubernetes.editor.util.getSelectorKey
24
+ import java.awt.event.MouseEvent
25
+
18
26
19
27
object SelectorPresentations {
20
28
21
- fun create (element : PsiElement , root : PsiElement , info : KubernetesTypeInfo , sink : InlayHintsSink , editor : Editor ): Collection <InlayPresentation >? {
22
- if (element is YAMLMapping ) {
23
- findMatchingResources(element, root)
29
+ private val selectorIcon = IconManager .getInstance().getIcon(" icons/selector.svg" , javaClass)
30
+
31
+ fun create (
32
+ element : PsiElement ,
33
+ sink : InlayHintsSink ,
34
+ editor : Editor ,
35
+ filter : LabelsFilter = LabelsFilter (element)
36
+ ): Collection <InlayPresentation > {
37
+ val project = editor.project ? : return emptyList()
38
+ val fileType = editor.virtualFile.fileType
39
+ val matchingElements = PsiFiles
40
+ .getAll(fileType, project)
41
+ .flatMap { file -> file.getAllElements() }
42
+ .filter(filter::isMatching)
43
+ if (matchingElements.isEmpty()) {
44
+ return emptyList()
24
45
}
25
- return emptyList()
26
- }
46
+ val factory = PresentationFactory (editor)
47
+
48
+ val offset = element.getSelectorKey()?.textRange?.endOffset
49
+ ? : return emptyList()
50
+
51
+ val presentation = createText(factory, matchingElements, editor, element)
52
+ sink.addInlineElement(offset, true , presentation, true )
27
53
28
- private fun findMatchingResources (selectorResource : YAMLMapping , root : PsiElement ): List <MatchingResource > {
29
- val matchLabels = selectorResource.getMatchLabels()
30
- val matchExpressions = selectorResource.getMatchExpressions()
31
- val allResources = PsiTreeUtil .findChildrenOfType(root, YAMLMapping ::class .java)
32
- .filter { it != selectorResource // dont match yourself
33
- it.hasKindAndName() }
54
+ val iconPresentation = createIcon(factory, editor, element)
55
+ sink.addInlineElement(offset, true , iconPresentation, true )
34
56
35
- return allResources
36
- .filter { resource ->
37
- resource.isMatchingLabels(matchLabels)
38
- && resource.isMatchingExpressions(matchExpressions)
39
- }
40
- .map { resource ->
41
- val kind = resource.getKind() ? : return emptyList()
42
- val name = resource.getMetadataName() ? : return emptyList()
43
- MatchingResource (kind, name, resource)
44
- }
57
+ return listOf (presentation, iconPresentation)
45
58
}
46
59
47
- private data class Resource (
48
- val name : String? ,
49
- val kind : String? ,
50
- val labels : Map <String , String >,
51
- val element : YAMLMapping
52
- ) {
53
- fun findMatchLabels (): List <Triple <String , String , YAMLKeyValue >> {
54
- return element.getMatchLabels()?.keyValues?.map { keyValue ->
55
- Triple (keyValue.keyText, keyValue.valueText, keyValue)
56
- }
57
- ? : emptyList()
58
- }
60
+ private fun createText (
61
+ factory : PresentationFactory ,
62
+ matchingElements : List <PsiElement >,
63
+ editor : Editor ,
64
+ element : PsiElement
65
+ ): InlayPresentation {
66
+ return factory.withTooltip(
67
+ " Click to see matching resources" ,
68
+ factory.referenceOnHover(
69
+ factory.roundWithBackground(
70
+ factory.text(
71
+ " ${matchingElements.size} matching"
72
+ )
73
+ ), onClick(editor, element)
74
+ )
75
+ )
59
76
}
60
77
61
- private data class MatchExpression (
62
- val key : String ,
63
- val operator : String ,
64
- val values : List <String >,
65
- val element : YAMLMapping
66
- )
78
+ private fun createIcon (
79
+ factory : PresentationFactory ,
80
+ editor : Editor ,
81
+ element : PsiElement
82
+ ): InlayPresentation {
83
+ val iconPresentation = factory.referenceOnHover(
84
+ factory.roundWithBackground(
85
+ factory.smallScaledIcon(selectorIcon)
86
+ ),
87
+ onClick(editor, element)
88
+ )
89
+ return iconPresentation
90
+ }
67
91
68
- private data class MatchingResource (val kind : String , val name : String , val element : PsiElement )
92
+ private fun onClick (
93
+ editor : Editor ,
94
+ element : PsiElement
95
+ ): (event: MouseEvent , point: java.awt.Point ) -> Unit {
96
+ return { event, point ->
97
+ GotoDeclarationAction .startFindUsages(editor, element.project, element, RelativePoint (event))
98
+ }
99
+ }
69
100
70
101
}
0 commit comments