gpt4 book ai didi

kotlin - 为文件顶层实现 IntelliJ Completion Contributor

转载 作者:行者123 更新时间:2023-12-02 12:44:52 26 4
gpt4 key购买 nike

我正在开发 custom language IntelliJ 插件,我想添加 code completion support使用 CompletionContributor .我正在为 IntelliJ 开发支持的语言使用 OOP,并提供使用典型类 ( class ) 和命名空间 ( namespace ) 的能力。
此刻,除了一件事,一切都无比清晰。我无法理解如何仅在文件范围的最高级别调用特定的完成提供程序。下面我举个例子,清楚地说明目前需要自动补全的地方(伪代码):

1. namespace Foo;
2.
3. class Test {
4.
5. }
6.
7. function foo() {
8.
9. }
在上面的例子中,完成提供者应该只用在第 1 行和第 2 行(类范围),部分用在第 3 行(直到大括号),以及第 6 行。简而言之,不应该调用完成提供者对于第 4 行和第 8 行。
请注意该文件可能为空:
1.
2.
在这种情况下,代码完成也应该起作用。
Bellow 是实现此目的的样板代码(Kotlin)。
贡献者:
// com.some.lang.core.completion.MyCompletionContributor

package com.some.lang.core.completion

import com.intellij.codeInsight.completion.CompletionContributor
import com.some.lang.core.completion.providers.FileScopeCompletionProvider

class MyCompletionContributor : CompletionContributor() {
private val providers = listOf(
FileScopeCompletionProvider
)

init {
providers.forEach { extend(it) }
}

private fun extend(provider: MyCompletionProvider) {
extend(provider.type, provider.context, provider)
}
}
抽象提供者:
// package com.some.lang.core.completion.MyCompletionProvider

package com.some.lang.core.completion

import com.intellij.codeInsight.completion.CompletionParameters
import com.intellij.codeInsight.completion.CompletionProvider
import com.intellij.codeInsight.completion.CompletionType
import com.intellij.patterns.ElementPattern
import com.intellij.psi.PsiElement

abstract class MyCompletionProvider : CompletionProvider<CompletionParameters>() {
abstract val context: ElementPattern<out PsiElement>
open val type: CompletionType = CompletionType.BASIC
}
文件范围提供程序:
// package com.some.lang.core.completion.providers.FileScopeCompletionProvider

package com.some.lang.core.completion.providers

import com.intellij.codeInsight.completion.CompletionParameters
import com.intellij.codeInsight.completion.CompletionResultSet
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.patterns.ElementPattern
import com.intellij.patterns.PlatformPatterns
import com.intellij.psi.PsiElement
import com.intellij.util.ProcessingContext
import com.some.lang.core.Language
import com.some.lang.core.completion.MyCompletionProvider

object FileScopeCompletionProvider : MyCompletionProvider() {
override val context: ElementPattern<PsiElement>
get() = PlatformPatterns.psiElement().withLanguage(Language)

override fun addCompletions(
parameters: CompletionParameters,
processingContext: ProcessingContext,
result: CompletionResultSet
) {
result.addElement(LookupElementBuilder.create("Hello"))
}
}
当然,这段代码并没有做需要的事情。但是,它确实显示了我使用的一般设计。我确定我需要修复以下几行:
    override val context: ElementPattern<PsiElement>
get() = PlatformPatterns.psiElement().withLanguage(Language)
主要问题是我不明白该怎么做。
更新:
相关BNF部分:
{
psiClassPrefix='My'

// ...
}

File ::= TopStatement*

private TopStatement ::= NamespaceStatement (ClassDefinition | InterfaceDefinition)

NamespaceStatement ::= 'namespace' ComplexId ';' {pin=2}

ClassDefinition ::= ClassModifier? 'class' Id SuperClass? ImplementsList? ClassBody {pin=3}

// ...

最佳答案

您可以使用 with添加您自己的 PatternCondition到您的元素模式。
假设你有一个 isTopLevel函数定义如下:

fun isTopLevel(elem: PsiElement): Boolean = elem.parent is MyLanguageFile
你可以用这个 ElementPattern使您的完成仅可用于顶级元素。
val context = PlatformPatterns
.psiElement()
.with(object : PatternCondition<PsiElement>("toplevel") {
override fun accepts(elem: PsiElement, context: ProcessingContext?) = isTopLevel(elem)
})
编辑:您也可以使用 withElementType控制完成将应用于哪些元素类型。例如:
context = psiElement()
.andOr(
psiElement().withElementType(NAMESPACE_NAME),
psiElement().withElementType(CLASS_NAME),
//other top level stuff
)

关于kotlin - 为文件顶层实现 IntelliJ Completion Contributor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62864961/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com