Skip to content

Commit 56c98a0

Browse files
committed
feat: display occurrences in std search usage (#642)
Signed-off-by: Andre Dietisheim <[email protected]>
1 parent 5ab207f commit 56c98a0

27 files changed

+2493
-484
lines changed

src/main/kotlin/com/redhat/devtools/intellij/kubernetes/editor/ResourceEditorFactory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,6 @@ open class ResourceEditorFactory protected constructor(
171171

172172
/* for testing purposes */
173173
protected open fun getTelemetryMessageBuilder(): TelemetryMessageBuilder {
174-
return TelemetryService.instance;
174+
return TelemetryService.instance
175175
}
176176
}

src/main/kotlin/com/redhat/devtools/intellij/kubernetes/editor/inlay/ResourceEditorInlayHintsProvider.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import com.intellij.codeInsight.hints.InlayHintsSink
2121
import com.intellij.codeInsight.hints.NoSettings
2222
import com.intellij.codeInsight.hints.SettingsKey
2323
import com.intellij.json.psi.JsonFile
24-
import com.intellij.openapi.application.ApplicationManager
2524
import com.intellij.openapi.application.ReadAction
2625
import com.intellij.openapi.editor.Editor
2726
import com.intellij.psi.PsiElement
@@ -83,7 +82,7 @@ internal class ResourceEditorInlayHintsProvider : InlayHintsProvider<NoSettings>
8382
val info = KubernetesTypeInfo.create(document) ?: return@forEach
8483
val element = document.topLevelValue ?: return@forEach
8584
Base64Presentations.create(element, info, sink, editor)
86-
SelectorPresentations.create(element, file, info, sink, editor)
85+
SelectorPresentations.create(element, sink, editor)
8786
}
8887
}
8988
}

src/main/kotlin/com/redhat/devtools/intellij/kubernetes/editor/inlay/base64/Base64Presentations.kt

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ object Base64Presentations {
4343
fun create(element: PsiElement, info: KubernetesTypeInfo, sink: InlayHintsSink, editor: Editor): Collection<InlayPresentation>? {
4444
return when {
4545
isKubernetesResource(SECRET_RESOURCE_KIND, info) -> {
46-
val data = getDataValue(element) ?: return null
46+
val data = element.getDataValue() ?: return null
4747
StringPresentationsFactory(data, sink, editor).create()
4848
}
4949

5050
isKubernetesResource(CONFIGMAP_RESOURCE_KIND, info) -> {
51-
val binaryData = getBinaryData(element) ?: return null
51+
val binaryData = element.getBinaryData() ?: return null
5252
BinaryPresentationsFactory(binaryData, sink, editor).create()
5353
}
5454

@@ -96,12 +96,15 @@ object Base64Presentations {
9696
private fun create(text: String, onClick: (event: MouseEvent) -> Unit, editor: Editor): InlayPresentation? {
9797
val factory = PresentationFactory(editor)
9898
val trimmed = trimWithEllipsis(text, INLAY_HINT_MAX_WIDTH) ?: return null
99-
val textPresentation = factory.smallText(trimmed)
100-
val hoverPresentation = factory.referenceOnHover(textPresentation) { event, _ ->
101-
onClick.invoke(event)
102-
}
103-
val tooltipPresentation = factory.withTooltip("Click to change value", hoverPresentation)
104-
return factory.roundWithBackground(tooltipPresentation)
99+
return factory.roundWithBackground(
100+
factory.withTooltip(
101+
"Click to change value",
102+
factory.referenceOnHover(
103+
factory.smallText(trimmed)) { event, _ ->
104+
onClick.invoke(event)
105+
}
106+
)
107+
)
105108
}
106109

107110
private fun onValidValue(setter: (value: String, wrapAt: Int) -> Unit, project: Project?)

src/main/kotlin/com/redhat/devtools/intellij/kubernetes/editor/inlay/base64/Base64ValueAdapter.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
******************************************************************************/
1111
package com.redhat.devtools.intellij.kubernetes.editor.inlay.base64
1212

13+
import com.intellij.json.psi.JsonProperty
1314
import com.intellij.psi.PsiElement
1415
import com.redhat.devtools.intellij.kubernetes.editor.util.decodeBase64
1516
import com.redhat.devtools.intellij.kubernetes.editor.util.decodeBase64ToBytes
1617
import com.redhat.devtools.intellij.kubernetes.editor.util.encodeBase64
1718
import com.redhat.devtools.intellij.kubernetes.editor.util.getValue
1819
import com.redhat.devtools.intellij.kubernetes.editor.util.setValue
20+
import org.jetbrains.yaml.psi.YAMLKeyValue
1921

2022
class Base64ValueAdapter(private val element: PsiElement) {
2123

@@ -80,6 +82,10 @@ class Base64ValueAdapter(private val element: PsiElement) {
8082
}
8183

8284
fun getStartOffset(): Int? {
83-
return com.redhat.devtools.intellij.kubernetes.editor.util.getStartOffset(element)
85+
return when(element) {
86+
is YAMLKeyValue -> element.value?.textRange?.startOffset
87+
is JsonProperty -> element.value?.textRange?.startOffset
88+
else -> null
89+
}
8490
}
8591
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 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+
******************************************************************************/
11+
package com.redhat.devtools.intellij.kubernetes.editor.inlay.selector
12+
13+
import com.intellij.psi.PsiElement
14+
import com.redhat.devtools.intellij.common.validation.KubernetesTypeInfo
15+
import com.redhat.devtools.intellij.kubernetes.editor.util.areMatchingMatchExpressions
16+
import com.redhat.devtools.intellij.kubernetes.editor.util.areMatchingMatchLabels
17+
import com.redhat.devtools.intellij.kubernetes.editor.util.getKubernetesTypeInfo
18+
import com.redhat.devtools.intellij.kubernetes.editor.util.getLabels
19+
import com.redhat.devtools.intellij.kubernetes.editor.util.getTemplate
20+
import com.redhat.devtools.intellij.kubernetes.editor.util.hasMatchExpressions
21+
import com.redhat.devtools.intellij.kubernetes.editor.util.hasMatchLabels
22+
import com.redhat.devtools.intellij.kubernetes.editor.util.hasSelector
23+
import com.redhat.devtools.intellij.kubernetes.editor.util.isCronJob
24+
import com.redhat.devtools.intellij.kubernetes.editor.util.isDaemonSet
25+
import com.redhat.devtools.intellij.kubernetes.editor.util.isDeployment
26+
import com.redhat.devtools.intellij.kubernetes.editor.util.isJob
27+
import com.redhat.devtools.intellij.kubernetes.editor.util.isNetworkPolicy
28+
import com.redhat.devtools.intellij.kubernetes.editor.util.isPersistentVolume
29+
import com.redhat.devtools.intellij.kubernetes.editor.util.isPersistentVolumeClaim
30+
import com.redhat.devtools.intellij.kubernetes.editor.util.isPod
31+
import com.redhat.devtools.intellij.kubernetes.editor.util.isPodDisruptionBudget
32+
import com.redhat.devtools.intellij.kubernetes.editor.util.isReplicaSet
33+
import com.redhat.devtools.intellij.kubernetes.editor.util.isService
34+
import com.redhat.devtools.intellij.kubernetes.editor.util.isStatefulSet
35+
36+
class SelectorFilter(private val selectingElement: PsiElement) {
37+
38+
private val selectingElementType: KubernetesTypeInfo? by lazy {
39+
selectingElement.getKubernetesTypeInfo()
40+
}
41+
42+
private val hasSelector: Boolean by lazy {
43+
selectingElement.hasSelector()
44+
}
45+
46+
private val hasMatchLabels: Boolean by lazy {
47+
selectingElement.hasMatchLabels()
48+
}
49+
50+
private val hasMatchExpressions: Boolean by lazy {
51+
selectingElement.hasMatchExpressions()
52+
}
53+
54+
fun filterMatching(toMatch: Collection<PsiElement>): Collection<PsiElement> {
55+
if (!hasSelector) {
56+
return emptyList()
57+
}
58+
return toMatch
59+
.filter(::isMatching)
60+
}
61+
62+
fun isMatching(element: PsiElement): Boolean {
63+
if (selectingElementType == null) {
64+
return false
65+
}
66+
67+
val selectableType = element.getKubernetesTypeInfo() ?: return false
68+
if (!isSelectable(selectableType)) {
69+
return false
70+
}
71+
72+
val labels = getLabels(selectableType, element, selectingElementType) ?: return false
73+
74+
return when {
75+
hasMatchLabels && hasMatchExpressions ->
76+
selectingElement.areMatchingMatchLabels(labels)
77+
&& selectingElement.areMatchingMatchExpressions(labels)
78+
79+
hasMatchLabels ->
80+
selectingElement.areMatchingMatchLabels(labels)
81+
82+
hasMatchExpressions ->
83+
selectingElement.areMatchingMatchExpressions(labels)
84+
85+
else -> false
86+
}
87+
}
88+
89+
private fun isSelectable(selectableType: KubernetesTypeInfo): Boolean {
90+
val selectingElementType = this.selectingElementType ?: return false
91+
return when {
92+
selectingElementType.isDeployment() ->
93+
selectableType.isPod()
94+
|| selectableType.isDeployment() // can select deployment template
95+
96+
selectingElementType.isCronJob() ->
97+
selectableType.isPod()
98+
|| selectableType.isCronJob() // template
99+
100+
selectingElementType.isDaemonSet() ->
101+
selectableType.isPod()
102+
|| selectableType.isDaemonSet() // template
103+
104+
selectingElementType.isJob() ->
105+
selectableType.isPod()
106+
|| selectableType.isJob() // template
107+
108+
selectingElementType.isReplicaSet() ->
109+
selectableType.isPod()
110+
|| selectableType.isReplicaSet() // template
111+
112+
selectingElementType.isStatefulSet() ->
113+
selectableType.isPod()
114+
|| selectableType.isStatefulSet() // template
115+
116+
selectingElementType.isNetworkPolicy()
117+
|| selectingElementType.isPodDisruptionBudget()
118+
|| selectingElementType.isService() ->
119+
selectableType.isPod()
120+
121+
selectingElementType.isPersistentVolumeClaim() ->
122+
selectableType.isPersistentVolume()
123+
|| selectableType.isPersistentVolumeClaim()
124+
125+
else ->
126+
false
127+
}
128+
}
129+
130+
private fun getLabels(
131+
selectableType: KubernetesTypeInfo,
132+
selectableElement: PsiElement,
133+
selectingElementType: KubernetesTypeInfo?
134+
): PsiElement? {
135+
return when {
136+
selectingElementType == null ->
137+
null
138+
139+
(selectingElementType.isCronJob()
140+
&& selectableType.isCronJob())
141+
|| (selectingElementType.isDaemonSet()
142+
&& selectableType.isDaemonSet())
143+
|| (selectingElementType.isDeployment()
144+
&& selectableType.isDeployment())
145+
|| (selectingElementType.isJob()
146+
&& selectableType.isJob())
147+
|| (selectingElementType.isReplicaSet()
148+
&& selectableType.isReplicaSet())
149+
|| (selectingElementType.isStatefulSet()
150+
&& selectableType.isStatefulSet()) ->
151+
selectableElement.getTemplate()
152+
153+
else ->
154+
selectableElement.getLabels()
155+
}
156+
}
157+
}

0 commit comments

Comments
 (0)