mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
[kotlin] specify script type when create script action
#KTIJ-33209 (cherry picked from commit 5ba94725e06edd678432ff1649feeb559dc306c8) IJ-CR-156458 GitOrigin-RevId: c67567a7061d3e98bb45cc94799e2e8c52d22b21
This commit is contained in:
committed by
intellij-monorepo-bot
parent
cb14a05149
commit
63cc596337
@@ -381,7 +381,7 @@ action.Kotlin.NewScript.text=Kotlin Script
|
||||
action.Kotlin.NewScript.description=Creates new Kotlin script or worksheet
|
||||
|
||||
action.new.file.dialog.title=New Kotlin Class/File
|
||||
action.new.script.dialog.title=New Kotlin File
|
||||
action.new.script.dialog.title=New Kotlin Script File
|
||||
|
||||
action.new.file.dialog.file.title=File
|
||||
action.new.file.dialog.class.title=Class
|
||||
|
||||
@@ -6,6 +6,8 @@ import com.intellij.openapi.projectRoots.JavaSdkType
|
||||
import com.intellij.openapi.projectRoots.ex.PathUtilEx
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import org.jetbrains.kotlin.idea.base.plugin.artifacts.KotlinArtifacts
|
||||
import org.jetbrains.kotlin.idea.core.script.k2.NewScriptFileInfo
|
||||
import org.jetbrains.kotlin.idea.core.script.k2.kotlinScriptTemplateInfo
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinitionsSource
|
||||
import java.io.File
|
||||
@@ -46,6 +48,10 @@ val Project.defaultDefinition: ScriptDefinition
|
||||
displayName("Default Kotlin Script")
|
||||
hostConfiguration(defaultJvmScriptingHostConfiguration)
|
||||
ide.dependenciesSources(JvmDependency(KotlinArtifacts.kotlinStdlibSources))
|
||||
ide.kotlinScriptTemplateInfo(NewScriptFileInfo().apply{
|
||||
id = "default-kts"
|
||||
title = ".kts"
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -32,6 +32,11 @@ class MainKtsScriptDefinitionSource(val project: Project) : ScriptDefinitionsSou
|
||||
ReportingExternalDependenciesResolver(it, DependencyResolutionService.getInstance(project))
|
||||
}.with {
|
||||
ide.dependenciesSources(JvmDependency(KotlinArtifacts.kotlinStdlibSources))
|
||||
ide.kotlinScriptTemplateInfo(NewScriptFileInfo().apply {
|
||||
id = "main-kts"
|
||||
title = ".main.kts"
|
||||
templateName = "Kotlin Script MainKts"
|
||||
})
|
||||
}
|
||||
|
||||
ScriptDefinition.FromConfigurations(
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.idea.core.script.k2
|
||||
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||
import javax.swing.Icon
|
||||
import kotlin.script.experimental.api.IdeScriptCompilationConfigurationKeys
|
||||
import kotlin.script.experimental.util.PropertiesCollection
|
||||
|
||||
|
||||
class NewScriptFileInfo(
|
||||
var id: String = "",
|
||||
var title: String = "",
|
||||
var templateName: String = "Kotlin Script",
|
||||
var icon: Icon = KotlinIcons.SCRIPT
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as NewScriptFileInfo
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return id.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
val IdeScriptCompilationConfigurationKeys.kotlinScriptTemplateInfo: PropertiesCollection.Key<NewScriptFileInfo> by PropertiesCollection.key()
|
||||
@@ -5,6 +5,8 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.EnvironmentUtil
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.idea.core.script.k2.NewScriptFileInfo
|
||||
import org.jetbrains.kotlin.idea.core.script.k2.kotlinScriptTemplateInfo
|
||||
import org.jetbrains.kotlin.idea.core.script.loadDefinitionsFromTemplatesByPaths
|
||||
import org.jetbrains.kotlin.idea.core.script.scriptingDebugLog
|
||||
import org.jetbrains.kotlin.idea.core.script.scriptingInfoLog
|
||||
@@ -231,6 +233,11 @@ class GradleKotlinScriptDefinitionWrapper(
|
||||
ScriptCompilationConfiguration.ide.acceptedLocations.put(listOf(ScriptAcceptedLocation.Project))
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
ScriptCompilationConfiguration.fileNamePattern.put(legacyDefinition.scriptFilePattern.pattern)
|
||||
ide.kotlinScriptTemplateInfo(NewScriptFileInfo().apply{
|
||||
id = "gradle-kts"
|
||||
title = ".gradle.kts"
|
||||
templateName = "Kotlin Script Gradle"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env kotlin
|
||||
|
||||
@@ -29,5 +29,8 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.util.jdom" />
|
||||
<orderEntry type="module" module-name="kotlin.code-insight.impl-base" />
|
||||
<orderEntry type="module" module-name="intellij.platform.diff.impl" />
|
||||
<orderEntry type="library" name="kotlinc.kotlin-scripting-common" level="project" />
|
||||
<orderEntry type="library" name="kotlinc.kotlin-scripting-compiler-impl" level="project" />
|
||||
<orderEntry type="module" module-name="kotlin.base.scripting" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -9,6 +9,7 @@ import com.intellij.ide.actions.JavaCreateTemplateInPackageAction
|
||||
import com.intellij.ide.fileTemplates.FileTemplate
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager
|
||||
import com.intellij.ide.fileTemplates.actions.AttributesDefaults
|
||||
import com.intellij.ide.fileTemplates.impl.BundledFileTemplate
|
||||
import com.intellij.ide.fileTemplates.ui.CreateFromTemplateDialog
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
@@ -26,6 +27,7 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.ui.InputValidatorEx
|
||||
import com.intellij.openapi.util.NlsContexts
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.openapi.util.registry.RegistryManager
|
||||
import com.intellij.psi.PsiDirectory
|
||||
import com.intellij.psi.PsiFile
|
||||
@@ -211,19 +213,24 @@ private fun List<String>.cutExistentPath(targetDir: PsiDirectory): List<String>
|
||||
|
||||
const val KOTLIN_WORKSHEET_EXTENSION: String = "ws.kts"
|
||||
|
||||
private fun removeKotlinExtensionIfPresent(name: String): String = when {
|
||||
name.endsWith(".$KOTLIN_WORKSHEET_EXTENSION") -> name.removeSuffix(".$KOTLIN_WORKSHEET_EXTENSION")
|
||||
name.endsWith(".$STD_SCRIPT_SUFFIX") -> name.removeSuffix(".$STD_SCRIPT_SUFFIX")
|
||||
name.endsWith(".${KotlinFileType.EXTENSION}") -> name.removeSuffix(".${KotlinFileType.EXTENSION}")
|
||||
else -> name
|
||||
}
|
||||
private val KOTLIN_KNOWS_SUFFIXES = arrayOf(
|
||||
".$KOTLIN_WORKSHEET_EXTENSION",
|
||||
".gradle.$STD_SCRIPT_SUFFIX",
|
||||
".main.$STD_SCRIPT_SUFFIX",
|
||||
".$STD_SCRIPT_SUFFIX",
|
||||
".${KotlinFileType.EXTENSION}"
|
||||
)
|
||||
|
||||
private fun removeKotlinExtensionIfPresent(name: String): String =
|
||||
KOTLIN_KNOWS_SUFFIXES.firstOrNull { name.endsWith(it) }?.let { name.removeSuffix(it) } ?: name
|
||||
|
||||
private fun createKotlinFileFromTemplate(dir: PsiDirectory, fileName: String, template: FileTemplate): PsiFile? {
|
||||
val project = dir.project
|
||||
val extraExtension = template.name.substringAfterLast('.', "").takeIf { it.isNotEmpty() }?.let { ".$it" } ?: ""
|
||||
val className = fileName.substringBefore('.')
|
||||
val attributesDefaults = AttributesDefaults(className).withFixedName(true)
|
||||
val defaultProperties = FileTemplateManager.getInstance(project).defaultProperties.apply {
|
||||
put(FileTemplate.ATTRIBUTE_FILE_NAME, fileName)
|
||||
put(FileTemplate.ATTRIBUTE_FILE_NAME, fileName + extraExtension)
|
||||
}
|
||||
val element = try {
|
||||
CreateFromTemplateDialog(
|
||||
@@ -246,15 +253,34 @@ private val FQNAME_SEPARATORS: CharArray = charArrayOf('/', '\\', '.')
|
||||
|
||||
internal fun createFileFromTemplateWithStat(name: String, template: FileTemplate, dir: PsiDirectory): PsiFile? {
|
||||
KotlinJ2KOnboardingFUSCollector.logFirstKtFileCreated(dir.project) // implementation checks if it is actually the first
|
||||
KotlinCreateFileFUSCollector.logFileTemplate(template.name)
|
||||
KotlinCreateFileFUSCollector.logFileTemplate(template.correctName())
|
||||
return createKotlinFileFromTemplate(name, template, dir)
|
||||
}
|
||||
|
||||
/*
|
||||
Kotlin Script file templates have '.kts' extension instead of ".main.kts" or ".gradle.kts"
|
||||
That leads to incorrect template naming such as 'Kotlin Script MainKts.main'
|
||||
//TODO enumify template names
|
||||
*/
|
||||
private fun FileTemplate.correctName(): @NlsSafe String {
|
||||
if (this !is BundledFileTemplate) return name
|
||||
if (extension != "kts") return name
|
||||
|
||||
return when (qualifiedName) {
|
||||
"Kotlin Script MainKts.main.kts" -> "Kotlin Script MainKts"
|
||||
"Kotlin Script Gradle.gradle.kts" -> "Kotlin Script Gradle"
|
||||
else -> name
|
||||
}
|
||||
}
|
||||
|
||||
fun createKotlinFileFromTemplate(name: String, template: FileTemplate, dir: PsiDirectory): PsiFile? {
|
||||
val directorySeparators = when (template.name) {
|
||||
val correctName = template.correctName()
|
||||
val directorySeparators = when (correctName) {
|
||||
"Kotlin File" -> FILE_SEPARATORS
|
||||
"Kotlin Worksheet" -> FILE_SEPARATORS
|
||||
"Kotlin Script" -> FILE_SEPARATORS
|
||||
"Kotlin Script Gradle" -> FILE_SEPARATORS
|
||||
"Kotlin Script MainKts" -> FILE_SEPARATORS
|
||||
else -> FQNAME_SEPARATORS
|
||||
}
|
||||
|
||||
@@ -262,7 +288,12 @@ fun createKotlinFileFromTemplate(name: String, template: FileTemplate, dir: PsiD
|
||||
|
||||
val service = DumbService.getInstance(dir.project)
|
||||
return service.computeWithAlternativeResolveEnabled<PsiFile?, Throwable> {
|
||||
val adjustedDir = CreateTemplateInPackageAction.adjustDirectory(targetDir, JavaModuleSourceRootTypes.SOURCES)
|
||||
val adjustedDir =
|
||||
if (KotlinScriptFileTemplate.entries.any { it.fileName == correctName }) {
|
||||
targetDir
|
||||
} else {
|
||||
CreateTemplateInPackageAction.adjustDirectory(targetDir, JavaModuleSourceRootTypes.SOURCES)
|
||||
}
|
||||
val psiFile = createKotlinFileFromTemplate(adjustedDir, fileName, template)
|
||||
if (psiFile is KtFile) {
|
||||
val singleClass = psiFile.declarations.singleOrNull() as? KtClass
|
||||
@@ -277,10 +308,16 @@ fun createKotlinFileFromTemplate(name: String, template: FileTemplate, dir: PsiD
|
||||
}
|
||||
}
|
||||
|
||||
internal fun CreateFileFromTemplateDialog.Builder.addKind(t: KotlinFileTemplate) =
|
||||
internal fun CreateFileFromTemplateDialog.Builder.addKind(t: KotlinTemplate) =
|
||||
addKind(t.title, t.icon, t.fileName)
|
||||
|
||||
internal enum class KotlinFileTemplate(@NlsContexts.ListItem val title: String, val icon: Icon, val fileName: String) {
|
||||
internal interface KotlinTemplate {
|
||||
val title: String
|
||||
val icon: Icon
|
||||
val fileName: String
|
||||
}
|
||||
|
||||
internal enum class KotlinFileTemplate(@NlsContexts.ListItem override val title: String, override val icon: Icon, override val fileName: String): KotlinTemplate {
|
||||
Class(KotlinBundle.message("action.new.file.dialog.class.title"), KotlinIcons.CLASS, "Kotlin Class"),
|
||||
File(
|
||||
KotlinBundle.message("action.new.file.dialog.file.title"),
|
||||
|
||||
@@ -10,9 +10,16 @@ import com.intellij.openapi.actionSystem.LangDataKeys
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.util.NlsContexts
|
||||
import com.intellij.psi.PsiDirectory
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import kotlin.collections.none
|
||||
import org.jetbrains.kotlin.idea.core.script.k2.K2ScriptDefinitionProvider
|
||||
import org.jetbrains.kotlin.idea.core.script.k2.kotlinScriptTemplateInfo
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinitionProvider
|
||||
import javax.swing.Icon
|
||||
import kotlin.script.experimental.api.ScriptCompilationConfiguration
|
||||
import kotlin.script.experimental.api.ide
|
||||
|
||||
internal class NewKotlinScriptAction : AbstractNewKotlinFileAction(), DumbAware {
|
||||
override fun isAvailable(dataContext: DataContext): Boolean {
|
||||
@@ -31,11 +38,31 @@ internal class NewKotlinScriptAction : AbstractNewKotlinFileAction(), DumbAware
|
||||
override fun buildDialog(project: Project, directory: PsiDirectory, builder: CreateFileFromTemplateDialog.Builder) {
|
||||
with(builder) {
|
||||
setTitle(KotlinBundle.message("action.new.script.dialog.title"))
|
||||
addKind(KotlinFileTemplate.Script)
|
||||
|
||||
val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(project) as? K2ScriptDefinitionProvider
|
||||
if (scriptDefinitionProvider != null) {
|
||||
K2ScriptDefinitionProvider.getInstance(project).getAllDefinitions().mapNotNull {
|
||||
it.compilationConfiguration[ScriptCompilationConfiguration.ide.kotlinScriptTemplateInfo]
|
||||
}.distinct().forEach {
|
||||
builder.addKind(it.title, it.icon, it.templateName)
|
||||
}
|
||||
} else {
|
||||
builder
|
||||
.addKind(KotlinScriptFileTemplate.GradleKts)
|
||||
.addKind(KotlinScriptFileTemplate.MainKts)
|
||||
.addKind(KotlinScriptFileTemplate.Kts)
|
||||
}
|
||||
|
||||
setValidator(NewKotlinFileNameValidator)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getActionName(directory: PsiDirectory, newName: String, templateName: String): String =
|
||||
KotlinBundle.message("action.Kotlin.NewScript.text")
|
||||
}
|
||||
|
||||
internal enum class KotlinScriptFileTemplate(@NlsContexts.ListItem override val title: String, override val icon: Icon, override val fileName: String): KotlinTemplate {
|
||||
GradleKts(".gradle.kts", KotlinIcons.GRADLE_SCRIPT, "Kotlin Script Gradle"),
|
||||
MainKts(".main.kts", KotlinIcons.SCRIPT, "Kotlin Script MainKts"),
|
||||
Kts(".kts", KotlinIcons.SCRIPT, "Kotlin Script"),
|
||||
}
|
||||
@@ -595,7 +595,7 @@
|
||||
|
||||
<action id="Kotlin.NewScript" class="org.jetbrains.kotlin.idea.actions.NewKotlinScriptAction"
|
||||
icon="org.jetbrains.kotlin.idea.KotlinIcons.SCRIPT">
|
||||
<add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewFromTemplate"/>
|
||||
<add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewWebDevelopment"/>
|
||||
</action>
|
||||
|
||||
<group id="KotlinToolsGroup" popup="true" icon="org.jetbrains.kotlin.idea.KotlinIcons.SMALL_LOGO"
|
||||
|
||||
Reference in New Issue
Block a user