Skip to content

Commit e8f76cf

Browse files
committed
feat: hint ref'd by matchLabels/-Expressions & list them in editor (#642)
Signed-off-by: Andre Dietisheim <[email protected]>
1 parent 899bcc2 commit e8f76cf

31 files changed

+3688
-333
lines changed

build.gradle.kts

+5-1
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,13 @@ java {
3232

3333
repositories {
3434
mavenLocal()
35-
maven { url = uri("https://repository.jboss.org") }
35+
/*
36+
* github repo with intellij-common needs to be listed before jboss repository. Both have 1.9.9-SNAPSHOT
37+
* First hit wins regardless of timestamp
38+
*/
3639
maven { url = uri("https://raw.githubusercontent.com/redhat-developer/intellij-common/repository/snapshots") }
3740
maven { url = uri("https://raw.githubusercontent.com/redhat-developer/intellij-common/repository/releases") }
41+
maven { url = uri("https://repository.jboss.org") }
3842
mavenCentral()
3943
intellijPlatform {
4044
defaultRepositories()

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

+1-1
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

+26-13
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,17 @@ import com.intellij.codeInsight.hints.InlayHintsProvider
2020
import com.intellij.codeInsight.hints.InlayHintsSink
2121
import com.intellij.codeInsight.hints.NoSettings
2222
import com.intellij.codeInsight.hints.SettingsKey
23+
import com.intellij.codeInsight.hints.presentation.PresentationFactory
2324
import com.intellij.json.psi.JsonFile
24-
import com.intellij.openapi.application.ApplicationManager
2525
import com.intellij.openapi.application.ReadAction
2626
import com.intellij.openapi.editor.Editor
2727
import com.intellij.psi.PsiElement
2828
import com.intellij.psi.PsiFile
2929
import com.intellij.ui.dsl.builder.panel
3030
import com.redhat.devtools.intellij.common.validation.KubernetesTypeInfo
3131
import com.redhat.devtools.intellij.kubernetes.editor.inlay.base64.Base64Presentations
32+
import com.redhat.devtools.intellij.kubernetes.editor.inlay.selector.SelectorPresentations
33+
import com.redhat.devtools.intellij.kubernetes.editor.util.PsiElements
3234
import org.jetbrains.yaml.psi.YAMLFile
3335
import javax.swing.JComponent
3436

@@ -65,34 +67,45 @@ internal class ResourceEditorInlayHintsProvider : InlayHintsProvider<NoSettings>
6567
}
6668
return when(element) {
6769
is YAMLFile -> {
68-
create(element, sink, editor)
70+
create(element, sink, editor, factory)
6971
false
7072
}
7173
is JsonFile -> {
72-
create(element, sink, editor)
74+
create(element, sink, editor, factory)
7375
false
7476
}
7577
else -> true
7678
}
7779
}
7880

79-
private fun create(file: YAMLFile, sink: InlayHintsSink, editor: Editor) {
81+
private fun create(file: YAMLFile, sink: InlayHintsSink, editor: Editor, factory: PresentationFactory) {
8082
return ReadAction.run<Exception> {
81-
file.documents.forEach { document ->
82-
val info = KubernetesTypeInfo.create(document) ?: return@forEach
83-
val element = document.topLevelValue ?: return@forEach
84-
Base64Presentations.create(element, info, sink, editor)?.create()
85-
}
83+
file.documents
84+
.mapNotNull { document -> document.topLevelValue }
85+
.forEach { element ->
86+
createPresentations(element, sink, editor, factory)
87+
}
8688
}
8789
}
8890

89-
private fun create(file: JsonFile, sink: InlayHintsSink, editor: Editor) {
91+
private fun create(file: JsonFile, sink: InlayHintsSink, editor: Editor, factory: PresentationFactory) {
9092
return ReadAction.run<Exception> {
91-
val info = KubernetesTypeInfo.create(file) ?: return@run
92-
val element = file.topLevelValue ?: return@run
93-
Base64Presentations.create(element, info, sink, editor)?.create()
93+
file.allTopLevelValues.forEach { element ->
94+
createPresentations(element, sink, editor, factory)
95+
}
9496
}
9597
}
9698

99+
private fun createPresentations(element: PsiElement, sink: InlayHintsSink, editor: Editor, factory: PresentationFactory) {
100+
val info = KubernetesTypeInfo.create(element) ?: return
101+
Base64Presentations.create(element, info, sink, editor, factory)
102+
103+
val fileType = editor.virtualFile?.fileType ?: return
104+
val project = editor.project ?: return
105+
//PsiElements.getAll(fileType, project)
106+
val allElements = PsiElements.getAllNoExclusions(fileType, project)
107+
SelectorPresentations.createForSelector(element, allElements, sink, editor, factory)
108+
SelectorPresentations.createForAllLabels(element, allElements, sink, editor, factory)
109+
}
97110
}
98111
}

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

+40-25
Original file line numberDiff line numberDiff line change
@@ -40,26 +40,41 @@ object Base64Presentations {
4040
private const val SECRET_RESOURCE_KIND = "Secret"
4141
private const val CONFIGMAP_RESOURCE_KIND = "ConfigMap"
4242

43-
fun create(element: PsiElement, info: KubernetesTypeInfo, sink: InlayHintsSink, editor: Editor): InlayPresentationsFactory? {
44-
return when {
43+
fun create(
44+
element: PsiElement,
45+
info: KubernetesTypeInfo,
46+
sink: InlayHintsSink,
47+
editor: Editor,
48+
factory: PresentationFactory,
49+
/* for testing purposes */
50+
stringPresentationFactory: (element: PsiElement, sink: InlayHintsSink, editor: Editor, factory: PresentationFactory) -> Unit
51+
= { element, sink, editor, factory ->
52+
StringPresentationsFactory(element, sink, editor, factory).create()
53+
},
54+
/* for testing purposes */
55+
binaryPresentationFactory: (element: PsiElement, sink: InlayHintsSink, editor: Editor, factory: PresentationFactory) -> Unit
56+
= { element, sink, editor, factory ->
57+
BinaryPresentationsFactory(element, sink, editor, factory).create()
58+
},
59+
) {
60+
when {
4561
isKubernetesResource(SECRET_RESOURCE_KIND, info) -> {
46-
val data = getDataValue(element) ?: return null
47-
StringPresentationsFactory(data, sink, editor)
62+
val data = element.getDataValue() ?: return
63+
stringPresentationFactory.invoke(data, sink, editor, factory)
4864
}
4965

5066
isKubernetesResource(CONFIGMAP_RESOURCE_KIND, info) -> {
51-
val binaryData = getBinaryData(element) ?: return null
52-
BinaryPresentationsFactory(binaryData, sink, editor)
67+
val binaryData = element.getBinaryData() ?: return
68+
binaryPresentationFactory.invoke(binaryData, sink, editor, factory)
5369
}
54-
55-
else -> null
5670
}
5771
}
5872

5973
abstract class InlayPresentationsFactory(
6074
private val element: PsiElement,
6175
protected val sink: InlayHintsSink,
62-
protected val editor: Editor
76+
protected val editor: Editor,
77+
protected val factory: PresentationFactory
6378
) {
6479

6580
protected companion object {
@@ -69,17 +84,15 @@ object Base64Presentations {
6984

7085
fun create(): Collection<InlayPresentation> {
7186
return element.children.mapNotNull { child ->
72-
val adapter = Base64ValueAdapter(child)
73-
create(adapter)
87+
create(Base64ValueAdapter(child))
7488
}
7589
}
7690

7791
protected abstract fun create(adapter: Base64ValueAdapter): InlayPresentation?
78-
7992
}
8093

81-
class StringPresentationsFactory(element: PsiElement, sink: InlayHintsSink, editor: Editor)
82-
: InlayPresentationsFactory(element, sink, editor) {
94+
class StringPresentationsFactory(element: PsiElement, sink: InlayHintsSink, editor: Editor, factory: PresentationFactory)
95+
: InlayPresentationsFactory(element, sink, editor, factory) {
8396

8497
override fun create(adapter: Base64ValueAdapter): InlayPresentation? {
8598
val decoded = adapter.getDecoded() ?: return null
@@ -89,20 +102,22 @@ object Base64Presentations {
89102
onValidValue(adapter::set, editor.project),
90103
editor
91104
)::show
92-
val presentation = create(decoded, onClick, editor) ?: return null
105+
val presentation = create(decoded, onClick, factory) ?: return null
93106
sink.addInlineElement(offset, false, presentation, false)
94107
return presentation
95108
}
96109

97-
private fun create(text: String, onClick: (event: MouseEvent) -> Unit, editor: Editor): InlayPresentation? {
98-
val factory = PresentationFactory(editor)
110+
private fun create(text: String, onClick: (event: MouseEvent) -> Unit, factory: PresentationFactory): InlayPresentation? {
99111
val trimmed = trimWithEllipsis(text, INLAY_HINT_MAX_WIDTH) ?: return null
100-
val textPresentation = factory.smallText(trimmed)
101-
val hoverPresentation = factory.referenceOnHover(textPresentation) { event, _ ->
102-
onClick.invoke(event)
103-
}
104-
val tooltipPresentation = factory.withTooltip("Click to change value", hoverPresentation)
105-
return factory.roundWithBackground(tooltipPresentation)
112+
return factory.roundWithBackground(
113+
factory.withTooltip(
114+
"Click to change value",
115+
factory.referenceOnHover(
116+
factory.smallText(trimmed)) { event, _ ->
117+
onClick.invoke(event)
118+
}
119+
)
120+
)
106121
}
107122

108123
private fun onValidValue(setter: (value: String, wrapAt: Int) -> Unit, project: Project?)
@@ -118,8 +133,8 @@ object Base64Presentations {
118133

119134
}
120135

121-
class BinaryPresentationsFactory(element: PsiElement, sink: InlayHintsSink, editor: Editor)
122-
: InlayPresentationsFactory(element, sink, editor) {
136+
class BinaryPresentationsFactory(element: PsiElement, sink: InlayHintsSink, editor: Editor, factory: PresentationFactory)
137+
: InlayPresentationsFactory(element, sink, editor, factory) {
123138

124139
override fun create(adapter: Base64ValueAdapter): InlayPresentation? {
125140
val decoded = adapter.getDecodedBytes() ?: return null

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

+7-1
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
}

0 commit comments

Comments
 (0)