change implementation of 'new file' action to support escaping the package name and creating directory/package hierarchy
#KT-8362 Fixed #KT-11328 Fixed
This commit is contained in:
@@ -666,6 +666,8 @@
|
|||||||
|
|
||||||
<annotationSupport language="kotlin" implementationClass="com.intellij.psi.impl.source.tree.java.JavaAnnotationSupport"/>
|
<annotationSupport language="kotlin" implementationClass="com.intellij.psi.impl.source.tree.java.JavaAnnotationSupport"/>
|
||||||
|
|
||||||
|
<createFromTemplateHandler implementation="org.jetbrains.kotlin.idea.actions.KotlinCreateFromTemplateHandler"/>
|
||||||
|
|
||||||
<intentionAction>
|
<intentionAction>
|
||||||
<className>org.jetbrains.kotlin.idea.intentions.IfNullToElvisIntention</className>
|
<className>org.jetbrains.kotlin.idea.intentions.IfNullToElvisIntention</className>
|
||||||
<category>Kotlin</category>
|
<category>Kotlin</category>
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.actions
|
||||||
|
|
||||||
|
import com.intellij.ide.fileTemplates.DefaultCreateFromTemplateHandler
|
||||||
|
import com.intellij.ide.fileTemplates.FileTemplate
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
|
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
|
||||||
|
|
||||||
|
class KotlinCreateFromTemplateHandler : DefaultCreateFromTemplateHandler() {
|
||||||
|
override fun handlesTemplate(template: FileTemplate) = template.isTemplateOfType(KotlinFileType.INSTANCE)
|
||||||
|
|
||||||
|
override fun prepareProperties(props: MutableMap<String, Any>) {
|
||||||
|
val packageName = props[FileTemplate.ATTRIBUTE_PACKAGE_NAME] as? String
|
||||||
|
if (packageName != null) {
|
||||||
|
props[FileTemplate.ATTRIBUTE_PACKAGE_NAME] = packageName
|
||||||
|
.split('.')
|
||||||
|
.map { it.quoteIfNeeded() }
|
||||||
|
.joinToString(".")
|
||||||
|
}
|
||||||
|
|
||||||
|
val name = props[FileTemplate.ATTRIBUTE_NAME] as? String
|
||||||
|
if (name != null) {
|
||||||
|
props[FileTemplate.ATTRIBUTE_NAME] = name.quoteIfNeeded()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,18 +18,25 @@ package org.jetbrains.kotlin.idea.actions
|
|||||||
|
|
||||||
import com.intellij.ide.actions.CreateFileFromTemplateAction
|
import com.intellij.ide.actions.CreateFileFromTemplateAction
|
||||||
import com.intellij.ide.actions.CreateFileFromTemplateDialog
|
import com.intellij.ide.actions.CreateFileFromTemplateDialog
|
||||||
|
import com.intellij.ide.fileTemplates.FileTemplate
|
||||||
|
import com.intellij.ide.fileTemplates.FileTemplateManager
|
||||||
|
import com.intellij.ide.fileTemplates.actions.AttributesDefaults
|
||||||
|
import com.intellij.ide.fileTemplates.ui.CreateFromTemplateDialog
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
import com.intellij.openapi.actionSystem.LangDataKeys
|
import com.intellij.openapi.actionSystem.LangDataKeys
|
||||||
import com.intellij.openapi.actionSystem.PlatformDataKeys
|
import com.intellij.openapi.actionSystem.PlatformDataKeys
|
||||||
import com.intellij.openapi.module.ModuleUtilCore
|
import com.intellij.openapi.module.ModuleUtilCore
|
||||||
import com.intellij.openapi.project.DumbAware
|
import com.intellij.openapi.project.DumbAware
|
||||||
|
import com.intellij.openapi.project.DumbService
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.roots.ProjectRootManager
|
import com.intellij.openapi.roots.ProjectRootManager
|
||||||
import com.intellij.psi.PsiDirectory
|
import com.intellij.psi.PsiDirectory
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
|
import com.intellij.util.IncorrectOperationException
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||||
import org.jetbrains.kotlin.idea.configuration.showConfigureKotlinNotificationIfNeeded
|
import org.jetbrains.kotlin.idea.configuration.showConfigureKotlinNotificationIfNeeded
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class NewKotlinFileAction
|
class NewKotlinFileAction
|
||||||
: CreateFileFromTemplateAction("Kotlin File/Class",
|
: CreateFileFromTemplateAction("Kotlin File/Class",
|
||||||
@@ -74,4 +81,59 @@ class NewKotlinFileAction
|
|||||||
override fun equals(obj: Any?): Boolean {
|
override fun equals(obj: Any?): Boolean {
|
||||||
return obj is NewKotlinFileAction
|
return obj is NewKotlinFileAction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun createFileFromTemplate(name: String, template: FileTemplate, dir: PsiDirectory): PsiFile? {
|
||||||
|
val directorySeparators = if (template.name == "Kotlin File") arrayOf('/', '\\') else arrayOf('/', '\\', '.')
|
||||||
|
val (className, targetDir) = findOrCreateTarget(dir, name, directorySeparators)
|
||||||
|
|
||||||
|
val service = DumbService.getInstance(dir.project)
|
||||||
|
service.isAlternativeResolveEnabled = true
|
||||||
|
try {
|
||||||
|
return createFromTemplate(targetDir, className, template)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
service.isAlternativeResolveEnabled = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findOrCreateTarget(dir: PsiDirectory, name: String, directorySeparators: Array<Char>): Pair<String, PsiDirectory> {
|
||||||
|
var className = name.removeSuffix(".kt")
|
||||||
|
var targetDir = dir
|
||||||
|
|
||||||
|
for (splitChar in directorySeparators) {
|
||||||
|
if (splitChar in className) {
|
||||||
|
val names = className.trim().split(splitChar)
|
||||||
|
|
||||||
|
for (dirName in names.dropLast(1)) {
|
||||||
|
targetDir = targetDir.findSubdirectory(dirName) ?: targetDir.createSubdirectory(dirName)
|
||||||
|
}
|
||||||
|
|
||||||
|
className = names.last()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Pair(className, targetDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createFromTemplate(dir: PsiDirectory, className: String, template: FileTemplate): PsiFile? {
|
||||||
|
val project = dir.project
|
||||||
|
val defaultProperties = FileTemplateManager.getInstance(project).defaultProperties
|
||||||
|
|
||||||
|
val properties = Properties(defaultProperties)
|
||||||
|
|
||||||
|
val element = try {
|
||||||
|
CreateFromTemplateDialog(project, dir, template,
|
||||||
|
AttributesDefaults(className).withFixedName(true),
|
||||||
|
properties).create()
|
||||||
|
}
|
||||||
|
catch (e: IncorrectOperationException) {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
LOG.error(e)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return element.containingFile
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user