Add "ML completion for Kotlin" experimental feature checkbox
- This checkbox should be shown only in IDEA >= 193 and should not be shown in AS - ML completion is enabled with `CompletionMLRankingSettings`, which resides in `com.intellij.stats.completion` plugin that is bundled by default - The `<depends>` section is required to be able to use classes from this plugin inside Kotlin plugin - `CompletionMLRankingSettings` have package-private setter for enabling ranking completion, so we have to use reflection to enable it (it will probably change in the future)
This commit is contained in:
committed by
Roman Golyshev
parent
4c6ea7c26a
commit
f29e665dce
@@ -87,6 +87,7 @@ dependencies {
|
|||||||
|
|
||||||
Platform[193].orHigher {
|
Platform[193].orHigher {
|
||||||
implementation(commonDep("org.jetbrains.intellij.deps.completion", "completion-ranking-kotlin"))
|
implementation(commonDep("org.jetbrains.intellij.deps.completion", "completion-ranking-kotlin"))
|
||||||
|
implementation(intellijPluginDep("stats-collector"))
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOnly(commonDep("org.jetbrains", "markdown"))
|
compileOnly(commonDep("org.jetbrains", "markdown"))
|
||||||
|
|||||||
@@ -285,3 +285,7 @@ scratch.inlay.output.mode.description=Inlay output mode
|
|||||||
# Code insight
|
# Code insight
|
||||||
dialog.import.on.paste.title3=Select Import to Remove
|
dialog.import.on.paste.title3=Select Import to Remove
|
||||||
copy.paste.reference.notification=<html>{0} {0, choice, 1#import was|2#imports were} added<p><span><a href='show'>Review Added Imports...</a></span></html>
|
copy.paste.reference.notification=<html>{0} {0, choice, 1#import was|2#imports were} added<p><span><a href='show'>Review Added Imports...</a></span></html>
|
||||||
|
|
||||||
|
# Experimental features
|
||||||
|
|
||||||
|
experimental.ml.completion=ML Completion for Kotlin
|
||||||
@@ -30,6 +30,8 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
|||||||
<depends optional="true" config-file="git4idea.xml">Git4Idea</depends>
|
<depends optional="true" config-file="git4idea.xml">Git4Idea</depends>
|
||||||
<depends optional="true" config-file="stream-debugger.xml">org.jetbrains.debugger.streams</depends>
|
<depends optional="true" config-file="stream-debugger.xml">org.jetbrains.debugger.streams</depends>
|
||||||
|
|
||||||
|
<depends>com.intellij.stats.completion</depends>
|
||||||
|
|
||||||
<!-- ULTIMATE-PLUGIN-PLACEHOLDER -->
|
<!-- ULTIMATE-PLUGIN-PLACEHOLDER -->
|
||||||
|
|
||||||
<!-- CIDR-PLUGIN-PLACEHOLDER-START -->
|
<!-- CIDR-PLUGIN-PLACEHOLDER-START -->
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
|||||||
<depends optional="true" config-file="git4idea.xml">Git4Idea</depends>
|
<depends optional="true" config-file="git4idea.xml">Git4Idea</depends>
|
||||||
<depends optional="true" config-file="stream-debugger.xml">org.jetbrains.debugger.streams</depends>
|
<depends optional="true" config-file="stream-debugger.xml">org.jetbrains.debugger.streams</depends>
|
||||||
|
|
||||||
|
<depends>com.intellij.stats.completion</depends>
|
||||||
|
|
||||||
<!-- ULTIMATE-PLUGIN-PLACEHOLDER -->
|
<!-- ULTIMATE-PLUGIN-PLACEHOLDER -->
|
||||||
|
|
||||||
<!-- CIDR-PLUGIN-PLACEHOLDER-START -->
|
<!-- CIDR-PLUGIN-PLACEHOLDER-START -->
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.intellij.openapi.util.registry.Registry
|
|||||||
import com.intellij.ui.components.JBCheckBox
|
import com.intellij.ui.components.JBCheckBox
|
||||||
import org.jdesktop.swingx.VerticalLayout
|
import org.jdesktop.swingx.VerticalLayout
|
||||||
import org.jetbrains.kotlin.config.KotlinCompilerVersion
|
import org.jetbrains.kotlin.config.KotlinCompilerVersion
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.PlatformVersion
|
import org.jetbrains.kotlin.idea.PlatformVersion
|
||||||
import org.jetbrains.kotlin.idea.projectWizard.WizardStatsService
|
import org.jetbrains.kotlin.idea.projectWizard.WizardStatsService
|
||||||
import org.jetbrains.kotlin.idea.util.isDev
|
import org.jetbrains.kotlin.idea.util.isDev
|
||||||
@@ -18,39 +19,60 @@ import javax.swing.JCheckBox
|
|||||||
import javax.swing.JPanel
|
import javax.swing.JPanel
|
||||||
|
|
||||||
object ExperimentalFeatures {
|
object ExperimentalFeatures {
|
||||||
val NewJ2k = ExperimentalFeature(
|
val NewJ2k = RegistryExperimentalFeature(
|
||||||
title = "New Java to Kotlin converter",
|
title = "New Java to Kotlin converter",
|
||||||
registryKey = "kotlin.experimental.new.j2k",
|
registryKey = "kotlin.experimental.new.j2k",
|
||||||
enabledByDefault = true
|
enabledByDefault = true
|
||||||
)
|
)
|
||||||
|
|
||||||
val NewWizard = ExperimentalFeature(
|
val NewWizard = object : RegistryExperimentalFeature(
|
||||||
title = "New Kotlin project wizard",
|
title = "New Kotlin project wizard",
|
||||||
registryKey = "kotlin.experimental.project.wizard",
|
registryKey = "kotlin.experimental.project.wizard",
|
||||||
enabledByDefault = false,
|
enabledByDefault = false
|
||||||
shouldBeShown = {
|
) {
|
||||||
val platformVersion = PlatformVersion.getCurrent() ?: return@ExperimentalFeature true
|
override fun shouldBeShown(): Boolean {
|
||||||
platformVersion.platform != PlatformVersion.Platform.ANDROID_STUDIO
|
val platformVersion = PlatformVersion.getCurrent() ?: return true
|
||||||
},
|
return platformVersion.platform != PlatformVersion.Platform.ANDROID_STUDIO
|
||||||
onFeatureStatusChanged = { enabled ->
|
}
|
||||||
|
|
||||||
|
override fun onFeatureStatusChanged(enabled: Boolean) {
|
||||||
WizardStatsService.logWizardStatusChanged(isEnabled = enabled)
|
WizardStatsService.logWizardStatusChanged(isEnabled = enabled)
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
|
object MLCompletionForKotlinFeature : ExperimentalFeature {
|
||||||
|
override val title: String
|
||||||
|
get() = KotlinBundle.message("experimental.ml.completion")
|
||||||
|
|
||||||
|
override fun shouldBeShown(): Boolean = MLCompletionForKotlin.isAvailable
|
||||||
|
|
||||||
|
override var isEnabled: Boolean
|
||||||
|
get() = MLCompletionForKotlin.isEnabled
|
||||||
|
set(value) {
|
||||||
|
MLCompletionForKotlin.isEnabled = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val allFeatures: List<ExperimentalFeature> = listOf(
|
val allFeatures: List<ExperimentalFeature> = listOf(
|
||||||
NewJ2k,
|
NewJ2k,
|
||||||
NewWizard
|
NewWizard,
|
||||||
|
MLCompletionForKotlinFeature
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExperimentalFeature(
|
interface ExperimentalFeature {
|
||||||
val title: String,
|
val title: String
|
||||||
|
var isEnabled: Boolean
|
||||||
|
fun shouldBeShown(): Boolean = true
|
||||||
|
fun onFeatureStatusChanged(enabled: Boolean) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class RegistryExperimentalFeature(
|
||||||
|
override val title: String,
|
||||||
private val registryKey: String,
|
private val registryKey: String,
|
||||||
private val enabledByDefault: Boolean,
|
private val enabledByDefault: Boolean
|
||||||
val shouldBeShown: () -> Boolean = { true },
|
) : ExperimentalFeature {
|
||||||
val onFeatureStatusChanged: (enabled: Boolean) -> Unit = {}
|
final override var isEnabled
|
||||||
) {
|
|
||||||
var isEnabled
|
|
||||||
get() = Registry.`is`(registryKey, enabledByDefault)
|
get() = Registry.`is`(registryKey, enabledByDefault)
|
||||||
set(value) {
|
set(value) {
|
||||||
Registry.get(registryKey).setValue(value)
|
Registry.get(registryKey).setValue(value)
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.configuration
|
||||||
|
|
||||||
|
import com.intellij.completion.settings.CompletionMLRankingSettings
|
||||||
|
import kotlin.reflect.jvm.isAccessible
|
||||||
|
|
||||||
|
internal object MLCompletionForKotlin {
|
||||||
|
const val isAvailable: Boolean = true
|
||||||
|
|
||||||
|
var isEnabled: Boolean
|
||||||
|
get() {
|
||||||
|
val settings = CompletionMLRankingSettings.getInstance()
|
||||||
|
return settings.isRankingEnabledHacked && settings.isLanguageEnabled("Kotlin")
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
val settings = CompletionMLRankingSettings.getInstance()
|
||||||
|
if (value && !settings.isRankingEnabledHacked) {
|
||||||
|
settings.isRankingEnabledHacked = true
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.setLanguageEnabled("Kotlin", value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setter for this property is package-private, so we have to use reflection to change its value.
|
||||||
|
*/
|
||||||
|
private var CompletionMLRankingSettings.isRankingEnabledHacked: Boolean
|
||||||
|
get() = isRankingEnabled
|
||||||
|
set(value) {
|
||||||
|
val rankingEnabledSetter = this::class.members.find { it.name == "setRankingEnabled" }
|
||||||
|
?: error("Cannot find 'setRankingEnabled' in class members: ${this::class.members}")
|
||||||
|
|
||||||
|
rankingEnabledSetter.isAccessible = true
|
||||||
|
rankingEnabledSetter.call(this, value)
|
||||||
|
rankingEnabledSetter.isAccessible = false
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.configuration
|
||||||
|
|
||||||
|
internal object MLCompletionForKotlin {
|
||||||
|
const val isAvailable: Boolean = false
|
||||||
|
|
||||||
|
override var isEnabled: Boolean
|
||||||
|
get() = false
|
||||||
|
set(value) {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.configuration
|
||||||
|
|
||||||
|
internal object MLCompletionForKotlin {
|
||||||
|
const val isAvailable: Boolean = false
|
||||||
|
|
||||||
|
override var isEnabled: Boolean
|
||||||
|
get() = false
|
||||||
|
set(value) {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.configuration
|
||||||
|
|
||||||
|
internal object MLCompletionForKotlin {
|
||||||
|
const val isAvailable: Boolean = false
|
||||||
|
|
||||||
|
override var isEnabled: Boolean
|
||||||
|
get() = false
|
||||||
|
set(value) {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.configuration
|
||||||
|
|
||||||
|
internal object MLCompletionForKotlin {
|
||||||
|
const val isAvailable: Boolean = false
|
||||||
|
|
||||||
|
override var isEnabled: Boolean
|
||||||
|
get() = false
|
||||||
|
set(value) {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user