diff --git a/plugins/devkit/intellij.devkit.scaffolding/src/NewIjModuleAction.kt b/plugins/devkit/intellij.devkit.scaffolding/src/NewIjModuleAction.kt index b7212464cd3f..7fe203883bca 100644 --- a/plugins/devkit/intellij.devkit.scaffolding/src/NewIjModuleAction.kt +++ b/plugins/devkit/intellij.devkit.scaffolding/src/NewIjModuleAction.kt @@ -6,10 +6,13 @@ import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.application.EDT import com.intellij.openapi.progress.currentThreadCoroutineScope import com.intellij.openapi.project.DumbAware import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext internal class NewIjModuleAction : AnAction(), DumbAware { @@ -33,6 +36,11 @@ internal class NewIjModuleAction : AnAction(), DumbAware { private suspend fun actionPerformed(dc: DataContext) { val project = dc.getData(CommonDataKeys.PROJECT) ?: return val root = dc.getData(CommonDataKeys.VIRTUAL_FILE) ?: return - val name = askForModuleName(project) + val suggestedNamePrefix = withContext(Dispatchers.IO) { + suggestModuleNamePrefix(root, project) + } + val name = withContext(Dispatchers.EDT) { + askForModuleName(project, suggestedNamePrefix) + } createIjModule(root, name) } diff --git a/plugins/devkit/intellij.devkit.scaffolding/src/impl.kt b/plugins/devkit/intellij.devkit.scaffolding/src/impl.kt index 1474ea26dc76..badc1016b37e 100644 --- a/plugins/devkit/intellij.devkit.scaffolding/src/impl.kt +++ b/plugins/devkit/intellij.devkit.scaffolding/src/impl.kt @@ -7,6 +7,7 @@ import com.intellij.lang.LangBundle import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.actionSystem.DataContext import com.intellij.openapi.application.backgroundWriteAction +import com.intellij.openapi.application.readAction import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.IntelliJProjectUtil.isIntelliJPlatformProject import com.intellij.openapi.project.Project @@ -45,10 +46,10 @@ internal fun isActionEnabled(dc: DataContext): Boolean { return !ProjectFileIndex.getInstance(project).isInSource(virtualFile) } -internal suspend fun askForModuleName(project: Project): @Nls String { +internal suspend fun askForModuleName(project: Project, suggestedNamePrefix: String): @Nls String { val contentPanel = NewItemSimplePopupPanel() val nameField: JTextField = contentPanel.textField - nameField.text = "intellij." + nameField.text = suggestedNamePrefix val popup: JBPopup = NewItemPopupUtil.createNewItemPopup(message("scaffolding.new.ij.module"), contentPanel, nameField) return suspendCancellableCoroutine { continuation -> contentPanel.applyAction = Consumer { event: InputEvent? -> @@ -76,6 +77,31 @@ internal suspend fun askForModuleName(project: Project): @Nls String { } } +internal suspend fun suggestModuleNamePrefix(parentDir: VirtualFile, project: Project): String { + return readAction { + val fileIndex = ProjectFileIndex.getInstance(project) + val parentContentRoot = fileIndex.getContentRootForFile(parentDir) + if (parentContentRoot == parentDir) { + val module = fileIndex.getModuleForFile(parentContentRoot) + if (module != null) { + return@readAction "${module.name.removeSuffix(".plugin").removeSuffix(".main").removeSuffix(".core")}." + } + } + if (parentDir.isDirectory) { + val siblingModuleNames = parentDir.children + .asSequence() + .filter { fileIndex.getContentRootForFile(it) == it } + .mapNotNull { fileIndex.getModuleForFile(it)?.name } + val commonPrefix = siblingModuleNames.reduceOrNull { acc, item -> acc.commonPrefixWith(item) } ?: "" + val suggestion = commonPrefix.substringBeforeLast('.', "") + if (suggestion.isNotEmpty()) { + return@readAction "$suggestion." + } + } + "intellij." + } +} + internal suspend fun createIjModule(vRoot: VirtualFile, moduleName: String) { val project = instance() val files = prepareFiles(vRoot.toNioPath(), moduleName)