Skip to content

Commit c277e19

Browse files
committed
feat: refactor inlay
1 parent 7db2acd commit c277e19

File tree

1 file changed

+33
-44
lines changed

1 file changed

+33
-44
lines changed

src/main/kotlin/com/github/xepozz/call/base/inlay/ExecutionInlayProvider.kt

Lines changed: 33 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,6 @@ import java.util.concurrent.ConcurrentHashMap
3535
import javax.swing.Icon
3636
import javax.swing.JPanel
3737

38-
/**
39-
* Unified InlayHintsProvider that uses the new extensible mechanism:
40-
* - LanguageTextExtractor EP to collect text blocks
41-
* - FeatureGenerator EP to match features within blocks
42-
* - WrapperFactory EP to create output wrappers on Run
43-
*
44-
* Minimal Phase 1: renders a single Run action per match.
45-
*/
4638
@Suppress("UnstableApiUsage")
4739
class ExecutionInlayProvider : InlayHintsProvider<NoSettings> {
4840
// key: editorId + featureId + line
@@ -83,31 +75,25 @@ class ExecutionInlayProvider : InlayHintsProvider<NoSettings> {
8375

8476
private fun computeMatches(file: PsiFile): Map<PsiElement, List<FeatureMatch>> {
8577
val project = file.project
86-
val applicable = LanguageTextExtractor.getApplicable(file)
87-
if (applicable.isEmpty()) return emptyMap()
78+
val allExtractors = LanguageTextExtractor.getApplicable(file).ifEmpty { return emptyMap() }
8879

89-
// Prefer language-specific extractors over the generic fallback (AdapterLanguageExtractor)
90-
val specific = applicable.filter { it !is AdapterLanguageExtractor }
91-
val extractors = specific.ifEmpty { applicable }
80+
val languageSpecificExtractors = allExtractors.filter { it !is AdapterLanguageExtractor }
81+
val extractors = languageSpecificExtractors.ifEmpty { allExtractors }
9282
println("file: $file, extractors: ${extractors.map { it.javaClass }}")
9383

94-
val blocks = extractors.flatMap { it.extract(file) }
95-
if (blocks.isEmpty()) return emptyMap()
84+
val blocks = extractors.flatMap { it.extract(file) }.ifEmpty { return emptyMap() }
9685

97-
val features = FeatureGenerator.getApplicable(project)
98-
if (features.isEmpty()) return emptyMap()
86+
val featureGenerators = FeatureGenerator.getApplicable(project).ifEmpty { return emptyMap() }
9987

10088
val matches = mutableMapOf<PsiElement, MutableList<FeatureMatch>>()
101-
for (b in blocks) {
102-
for (f in features) {
103-
val ms = f.match(b, project)
104-
if (ms.isNotEmpty()) {
105-
matches.computeIfAbsent(b.element) { mutableListOf() }.addAll(ms)
106-
}
89+
for (block in blocks) {
90+
for (featureGenerator in featureGenerators) {
91+
val featureMatches = featureGenerator.match(block, project).ifEmpty { continue }
92+
93+
matches.computeIfAbsent(block.element) { mutableListOf() }.addAll(featureMatches)
10794
}
10895
}
10996

110-
// Sort matches by start offset for stable rendering
11197
matches.values.forEach { list ->
11298
list.sortBy { it.originalRange.startOffset }
11399
}
@@ -120,7 +106,6 @@ class ExecutionInlayProvider : InlayHintsProvider<NoSettings> {
120106
val icon: Icon? = feature?.icon
121107
val tooltip = feature?.let { "${it.tooltipPrefix}: ${match.value}" } ?: match.value
122108

123-
// Compute session key
124109
val start = match.originalRange.startOffset
125110
val line = editor.document.getLineNumber(start)
126111
val lineEndOffset = editor.document.getLineEndOffset(line)
@@ -134,7 +119,7 @@ class ExecutionInlayProvider : InlayHintsProvider<NoSettings> {
134119
val collapseIcon = if (session.collapsed) AllIcons.General.ArrowRight else AllIcons.General.ArrowDown
135120
val collapseTooltip = if (session.collapsed) "Expand" else "Collapse"
136121
parts += clickableIcon(collapseIcon, collapseTooltip) {
137-
toggleCollapse(key)
122+
toggleCollapse(session)
138123
refreshInlays(editor)
139124
}
140125
}
@@ -152,6 +137,7 @@ class ExecutionInlayProvider : InlayHintsProvider<NoSettings> {
152137
refreshInlays(editor)
153138
}
154139
}
140+
155141
ExecutionState.IDLE -> {
156142
// Initial Run button
157143
val runText = factory.inset(factory.roundWithBackground(factory.text(" Run ")), left = 2, right = 2)
@@ -165,6 +151,7 @@ class ExecutionInlayProvider : InlayHintsProvider<NoSettings> {
165151
}
166152
parts += runPres
167153
}
154+
168155
ExecutionState.FINISHED -> {
169156
// After first launch: show Rerun icon + "Run" text
170157
val rerunIcon = AllIcons.Actions.Rerun
@@ -200,7 +187,7 @@ class ExecutionInlayProvider : InlayHintsProvider<NoSettings> {
200187
return p
201188
}
202189

203-
private fun <TWrapper: Wrapper> run(
190+
private fun <TWrapper : Wrapper> run(
204191
editor: Editor,
205192
project: Project,
206193
feature: FeatureGenerator<TWrapper>,
@@ -231,11 +218,14 @@ class ExecutionInlayProvider : InlayHintsProvider<NoSettings> {
231218
// Replace previous wrapper in the existing container
232219
val container = current.container
233220
val oldWrapper = current.wrapper
234-
if (oldWrapper!=null) {
221+
if (oldWrapper != null) {
235222
container.remove(oldWrapper.component)
236223
}
237224
mountWrapperIntoContainer(container, wrapper)
238-
try { oldWrapper?.dispose() } catch (_: Throwable) {}
225+
try {
226+
oldWrapper?.dispose()
227+
} catch (_: Throwable) {
228+
}
239229
current.wrapper = wrapper
240230
current.state = ExecutionState.RUNNING
241231
}
@@ -266,28 +256,27 @@ class ExecutionInlayProvider : InlayHintsProvider<NoSettings> {
266256
}
267257

268258
private fun stop(key: String) {
269-
val s = sessions[key] ?: return
270-
s.processHandler?.destroyProcess()
271-
s.processHandler = null
272-
s.state = ExecutionState.FINISHED
259+
val session = sessions[key] ?: return
260+
session.processHandler?.destroyProcess()
261+
session.processHandler = null
262+
session.state = ExecutionState.FINISHED
273263
}
274264

275265
private fun delete(key: String) {
276-
val s = sessions.remove(key) ?: return
277-
try { s.processHandler?.destroyProcess() } catch (_: Throwable) {}
278-
s.processHandler = null
266+
val session = sessions.remove(key) ?: return
267+
try { session.processHandler?.destroyProcess() } catch (_: Throwable) { }
268+
session.processHandler = null
279269
invokeLater {
280-
s.container?.parent?.remove(s.container)
270+
session.container?.parent?.remove(session.container)
281271
}
282-
try { s.wrapper?.dispose() } catch (_: Throwable) {}
283-
Disposer.dispose(s.disposable)
272+
try { session.wrapper?.dispose() } catch (_: Throwable) { }
273+
Disposer.dispose(session.disposable)
284274
}
285275

286-
private fun toggleCollapse(key: String) {
287-
val s = sessions[key] ?: return
288-
s.collapsed = !s.collapsed
289-
val visible = !s.collapsed
290-
invokeLater { s.container?.isVisible = visible }
276+
private fun toggleCollapse(session: Session) {
277+
session.collapsed = !session.collapsed
278+
val visible = !session.collapsed
279+
invokeLater { session.container?.isVisible = visible }
291280
}
292281

293282
private fun refreshInlays(editor: Editor) {

0 commit comments

Comments
 (0)