Skip to content

Commit e3941af

Browse files
committed
Return to the lite inlay provider for parameters
1 parent 626c20b commit e3941af

6 files changed

Lines changed: 45 additions & 101 deletions

File tree

src/main/kotlin/space/whitememory/pythoninlayparams/PythonInlayHintsProvider.kt

Lines changed: 0 additions & 64 deletions
This file was deleted.

src/main/kotlin/space/whitememory/pythoninlayparams/PythonInlayHintsCollector.kt renamed to src/main/kotlin/space/whitememory/pythoninlayparams/PythonInlayParameterHintsProvider.kt

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,70 @@
11
package space.whitememory.pythoninlayparams
22

3-
import com.intellij.codeInsight.hints.FactoryInlayHintsCollector
4-
import com.intellij.codeInsight.hints.InlayHintsSink
53
import com.intellij.codeInsight.hints.InlayInfo
6-
import com.intellij.openapi.editor.Editor
4+
import com.intellij.codeInsight.hints.InlayParameterHintsProvider
5+
import com.intellij.codeInsight.hints.Option
76
import com.intellij.psi.PsiElement
87
import com.intellij.psi.util.PsiTreeUtil
98
import com.jetbrains.python.psi.*
109
import com.jetbrains.python.psi.types.TypeEvalContext
1110

11+
1212
@Suppress("UnstableApiUsage")
13-
class PythonInlayHintsCollector(
14-
editor: Editor, private val settings: PythonInlayHintsProvider.Settings
15-
) : FactoryInlayHintsCollector(editor) {
13+
class PythonInlayParameterHintsProvider : InlayParameterHintsProvider {
14+
15+
companion object {
16+
val classHints = Option("hints.classes.parameters", { "Class hints" }, true)
17+
val functionHints = Option("hints.functions.parameters", { "Function hints" }, true)
18+
val lambdaHints = Option("hints.lambdas.parameters", { "Lambda hints" }, true)
19+
}
1620

1721
private val forbiddenBuiltinFiles = setOf("builtins.pyi", "typing.pyi")
1822

19-
override fun collect(element: PsiElement, editor: Editor, sink: InlayHintsSink): Boolean {
23+
override fun getDefaultBlackList() = setOf<String>()
24+
25+
override fun isBlackListSupported() = false
26+
27+
override fun getDescription() = "Help you pass correct arguments by showing parameter names at call sites"
28+
29+
override fun getSupportedOptions() = listOf(classHints, functionHints, lambdaHints)
30+
31+
override fun getProperty(key: String?): String? {
32+
val prefix = "inlay.parameters"
33+
return when (key) {
34+
"$prefix.hints.classes.parameters" -> "Show parameter names for class constructors and dataclasses."
35+
"$prefix.hints.functions.parameters" -> "Show parameter names for function and method calls."
36+
"$prefix.hints.lambdas.parameters" -> "Show parameter names for lambda calls."
37+
else -> null
38+
}
39+
}
40+
41+
override fun getParameterHints(element: PsiElement): MutableList<InlayInfo> {
42+
val inlayInfos = mutableListOf<InlayInfo>()
43+
2044
// This method gets every element in the editor,
2145
// so we have to verify it's a Python call expression
2246
if (element !is PyCallExpression || element is PyDecorator) {
23-
return true
47+
return inlayInfos
2448
}
2549

2650
// Don't show hints if there's no arguments
2751
// Or the only argument is unpacking (*list, **dict)
2852
if (element.arguments.isEmpty() || (element.arguments.size == 1 && element.arguments[0] is PyStarArgument)) {
29-
return true
53+
return inlayInfos
3054
}
3155

3256
// Try to resolve the object that made this call
33-
var resolved = element.callee?.reference?.resolve() ?: return true
57+
var resolved = element.callee?.reference?.resolve() ?: return inlayInfos
3458
if (isForbiddenBuiltinElement(resolved)) {
35-
return true
59+
return inlayInfos
3660
}
3761

3862
var classAttributes = listOf<PyTargetExpression>()
39-
if (resolved is PyTargetExpression && settings.lambdaHints) {
63+
if (resolved is PyTargetExpression && lambdaHints.isEnabled()) {
4064
// TODO: Handle cases other than lambda expressions
4165
// Use the target to find the lambda expression object, and assign it to get its parameters up ahead
42-
resolved = PsiTreeUtil.getNextSiblingOfType(resolved, PyLambdaExpression::class.java) ?: return true
43-
} else if (resolved is PyClass && settings.classHints) {
66+
resolved = PsiTreeUtil.getNextSiblingOfType(resolved, PyLambdaExpression::class.java) ?: return inlayInfos
67+
} else if (resolved is PyClass && classHints.isEnabled()) {
4468
// This call is made by a class (initialization), so we want to find the parameters it takes.
4569
// In order to do so, we first have to check for an init method, and if not found,
4670
// We will use the class attributes instead. (Handle dataclasses, attrs, etc.)
@@ -55,8 +79,8 @@ class PythonInlayHintsCollector(
5579
classAttributes = resolved.classAttributes
5680
entryMethod ?: resolved
5781
}
58-
} else if (!settings.functionHints) {
59-
return true
82+
} else if (!functionHints.isEnabled()) {
83+
return inlayInfos
6084
}
6185

6286
val resolvedParameters = getElementFilteredParameters(resolved)
@@ -66,7 +90,7 @@ class PythonInlayHintsCollector(
6690
// in case this is a class
6791
classAttributes
6892
} else if (resolvedParameters.isEmpty()) {
69-
return true
93+
return inlayInfos
7094
} else {
7195
resolvedParameters
7296
}
@@ -75,27 +99,11 @@ class PythonInlayHintsCollector(
7599
// Don't need a hint if there's only one parameter,
76100
// Make an exception for *args
77101
finalParameters[0].let {
78-
if (it !is PyNamedParameter || !it.isPositionalContainer) return true
102+
if (it !is PyNamedParameter || !it.isPositionalContainer) return inlayInfos
79103
}
80104
}
81105

82-
getInlayInfos(finalParameters, element.arguments).forEach {
83-
val hintText = factory.smallText("${it.text}:")
84-
val presentation = factory.roundWithBackground(hintText)
85-
86-
sink.addInlineElement(it.offset, false, presentation, false)
87-
}
88-
89-
return true
90-
}
91-
92-
/**
93-
* Gets the list of [InlayInfo] that represents parameters worth showing along with their offset.
94-
*/
95-
private fun getInlayInfos(parameters: List<PyElement>, arguments: Array<PyExpression>): MutableList<InlayInfo> {
96-
val inlayInfos = mutableListOf<InlayInfo>()
97-
98-
parameters.zip(arguments).forEach { (param, arg) ->
106+
finalParameters.zip(element.arguments).forEach { (param, arg) ->
99107
val paramName = param.name ?: return@forEach
100108
if (arg is PyStarArgument || arg is PyKeywordArgument) {
101109
// It's a keyword argument or unpacking,

src/main/resources/META-INF/plugin.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<depends>com.intellij.modules.platform</depends>
1010

1111
<extensions defaultExtensionNs="com.intellij">
12-
<codeInsight.inlayProvider language="Python"
13-
implementationClass="space.whitememory.pythoninlayparams.PythonInlayHintsProvider"/>
12+
<codeInsight.parameterNameHints language="Python"
13+
implementationClass="space.whitememory.pythoninlayparams.PythonInlayParameterHintsProvider"/>
1414
</extensions>
1515
</idea-plugin>

src/main/resources/inlayProviders/python.inlay.parameters/hints.classes.parameters.py renamed to src/main/resources/inlayProviders/Parameters/hints.classes.parameters.py

File renamed without changes.

src/main/resources/inlayProviders/python.inlay.parameters/hints.functions.parameters.py renamed to src/main/resources/inlayProviders/Parameters/hints.functions.parameters.py

File renamed without changes.

src/main/resources/inlayProviders/python.inlay.parameters/hints.lambda.parameters.py renamed to src/main/resources/inlayProviders/Parameters/hints.lambdas.parameters.py

File renamed without changes.

0 commit comments

Comments
 (0)