系列文章
本系列文章已收录到专栏,交流群号:689220994,也可点击链接加入。
前言
在上一篇文章中介绍了如何在 IDEA 中自定义项目脚手架,本文将介绍如何在WebStorm
、PyCharm
、CLion
等其它 IntelliJ 主流平台中如何自定义项目脚手架,参考本文的思路,开发其它平台 IDE 的脚手架也很容易,本文就不再逐一介绍,本文涉及到的完整代码已上传到GitHub。
最终效果
CLion
PyCharm
WebStorm
写在前面
由于在上一篇文章中已经介绍了项目脚手架中创建模板及使用的方式和 UI 布局相关的内容,本文就不再介绍相关内容,并且统一将其放到了工具类TemplateUtils
中,代码如下:
object TemplateUtils {
const val PLUGIN_NAME = "TEMPLATE"
// UI 界面
fun initUI(settings: TemplateSettings) = panel {
row("Name: ") {
textField().align(AlignX.FILL).onChanged {
settings.name = it.text
}
}.topGap(TopGap.MEDIUM)
row("Description: ") {
textField().align(AlignX.FILL).onChanged {
settings.description = it.text
}
}.topGap(TopGap.MEDIUM)
}
// 使用模板及生成文件
fun generateFile(project: Project, basePath: String, settings: TemplateSettings) {
val template = FileTemplateManager.getInstance(project).getJ2eeTemplate(TemplateFileFactory.PLUGIN_XML)
val properties = Properties()
properties.setProperty("name", settings.name)
properties.setProperty("description", settings.description)
val renderedText = template.getText(properties)
FileUtil.writeToFile(File("${basePath}${File.separator}demo.txt"), renderedText)
}
}
后续三个 IDE 创建脚手架均会调用该类中的两个方法分别用于设置 UI 布局及生成模板文件。
实现方式
不同于 IDEA 中使用ModuleBuilder
去创建自定义脚手架,其它平台则是需要实现DirectoryProjectGenerator
接口并在plugin.xml
中进行注册(参考下面的配置):
<directoryProjectGenerator
implementation="cn.butterfly.template2.module.WebTemplateGenerator"/>
不过在其它平台,并不是直接去实现DirectoryProjectGenerator
接口就可以一劳永逸,针对不同的 IDE 都会有自己特定的Generator
类,我们需要去实现这些特定的Generator
类才能顺利实现,例如引入了com.intellij.clion
插件后,查看DirectoryProjectGenerator
的实现类就会发现很多 C 相关的Generator
类。
本文中WebStorm
通过实现WebProjectTemplate
来完成,PyCharm
通过实现PythonProjectGenerator
来完成,CLion
则是通过实现CLionProjectGenerator
来完成。
经测试,直接实现
DirectoryProjectGenerator
接口,可以在WebStorm
中成功,实现WebProjectTemplate
类则可以在WebStorm
和PyCharm
中成功,同时针对WebStorm
还可以去实现NpmPackageProjectGenerator
类,可以参考Vue
插件的源码。总之,针对不同的插件,需要实现的类也可能有所不同,不过只需要记住在引入了相关语言插件后,去查看DirectoryProjectGenerator
接口的实现类,然后根据名字查找判断即可。
实现步骤
CLion
首先需要增加com.intellij.clion
语言插件,然后在plugin.xml
中增加如下配置:
<depends>com.intellij.clion</depends>
<directoryProjectGenerator implementation="cn.butterfly.template2.module.CTemplateGenerator"/>
之后实现CLionProjectGenerator
类即可:
class CTemplateGenerator : CLionProjectGenerator<Any>() {
// 1
private val settings = TemplateSettings()
// 2
override fun getDescription() = TemplateUtils.PLUGIN_NAME
// 3
override fun getName() = TemplateUtils.PLUGIN_NAME
// 4
override fun getLogo() = PluginIcons.TEMPLATE_ICON
// 5
override fun generateProject(project: Project, baseDir: VirtualFile, obj: Any, module: Module) =
TemplateUtils.generateFile(project, baseDir.path, settings)
// 6
override fun getSettingsPanel() = TemplateUtils.initUI(settings)
}
其中 1 用于保存配置字段值,234 则是脚手架的基本信息,56 则是调用了TemplateUtils
工具类中的两个方法分别用于生成模板文件和设置 UI 布局。
PyCharm
首先需要增加PythonCore:242.21829.3
语言插件,然后在plugin.xml
中增加如下配置:
<depends>com.intellij.modules.python</depends>
<directoryProjectGenerator implementation="cn.butterfly.template2.module.PyTemplateGenerator"/>
之后实现PythonProjectGenerator
类即可:
class PyTemplateGenerator : PythonProjectGenerator<PyNewProjectSettings>() {
// 1
private val settings = TemplateSettings()
// 2
private var basePath = ""
// 3
override fun getDescription() = TemplateUtils.PLUGIN_NAME
// 4
override fun getName() = TemplateUtils.PLUGIN_NAME
// 5
override fun getLogo() = PluginIcons.TEMPLATE_ICON
// 6
override fun getSettingsPanel(baseDir: File?): JComponent {
basePath = baseDir?.path ?: ""
return TemplateUtils.initUI(settings)
}
// 7
override fun configureProject(
project: Project,
baseDir: VirtualFile,
settings: PyNewProjectSettings,
module: Module,
synchronizer: PyProjectSynchronizer?
) {
super.configureProject(project, baseDir, settings, module, synchronizer)
basePath = baseDir.path
}
// 8
override fun afterProjectGenerated(project: Project) =
TemplateUtils.generateFile(project, basePath, settings)
其中 1 用于保存配置字段值,2用于保存项目路径,345 则是脚手架的基本信息,6 则是保存项目路径信息和设置 UI 布局,7 也用于保存项目路径信息,8 则是用于生成模板文件。
WebStorm
直接在plugin.xml
中增加以下配置:
<directoryProjectGenerator
implementation="cn.butterfly.template2.module.WebTemplateGenerator"/>
之后实现WebProjectTemplate
类即可:
class WebTemplateGenerator : WebProjectTemplate<TemplateSettings>() {
// 1
private val webSettings = TemplateSettings()
// 2
override fun getDescription() = TemplateUtils.PLUGIN_NAME
// 3
override fun getName() = TemplateUtils.PLUGIN_NAME
// 4
override fun getLogo() = PluginIcons.TEMPLATE_ICON
// 5
override fun createPeer(): ProjectGeneratorPeer<TemplateSettings> = object : ProjectGeneratorPeer<TemplateSettings> {
override fun getComponent() = TemplateUtils.initUI(webSettings)
override fun buildUI(step: SettingsStep) {
}
override fun getSettings() = webSettings
override fun validate() = null
override fun isBackgroundJobRunning() = true
}
// 6
override fun generateProject(project: Project, baseDir: VirtualFile, settings: TemplateSettings, module: Module) =
TemplateUtils.generateFile(project, baseDir.path, webSettings)
}
其中 1 用于保存配置字段值,234 则是脚手架的基本信息,56 则是调用了TemplateUtils
工具类中的两个方法分别用于生成模板文件和设置 UI 布局。
可以看到针对不同的 IDE 都有各自创建脚手架的方式,但总体差异不大,思路也一样,核心就是找到满足要求的Generator
类即可。
总结
本文简单介绍了如何在除 IDEA 外的 IntelliJ IDE 中创建自己的脚手架,参考本文的思路也很容易在除本文外的其它 IDE 中实现自定义脚手架,如果大家在实现的过程中遇到了什么问题,也欢迎一起交流讨论。