IDEA插件开发实战

1. 背景

插件体系是IDEA的精髓,插件市场里拥有无数开发者提交的插件,这让IDEA拥有了成长的能力。下面我通过一个例子,介绍插件创建、调试和发布的完整过程。

2. 开发步骤

2.1 创建工程
官方推荐2种方式来创建插件工程,一种是基于Github的模板代码,一种是基于Gradle手动配置。我推荐使用Github模板的方式,插件工程clone下来就可以直接执行,对新人比较友好。

2.2.1 模板代码

  1. 打开模板的Github地址:https://github.com/JetBrains/intellij-platform-plugin-template
  2. 点击“Use this template”,将项目fork到自己的仓库里,或者直接下载模板代码。


2.2.2 Gradle方式

在new project的时候,选择Gradle->IntelliJ Platform Plugin

2.2 开发插件

IDEA里有一个Intention action(代码推测)功能,快捷键是shift+enter。我们尝试新增一种代码推测,在输入类名后,通过推测自动生成new语句。例如,输入“User”,生成“User user = new User();”。

2.2.1 编写代码(Kotlin)
要新增Intention action功能,就要实现IntentionAction接口,实际代码里是用PsiElementBaseIntentionAction这个抽象类,它已经继承了IntentionAction。功能代码如下,IntentionAction接口里的核心方法是isAvailable()和invoke()方法。isAvailable()是在敲下shift+enter时,判断当前action是否满足执行条件;invoke()是选择aciton后,需要执行的逻辑。

class NewObjectGenerator : PsiElementBaseIntentionAction() {
 
    override fun isAvailable(project: Project, editor: Editor, element: PsiElement): Boolean {
        // 格式User
        return element is PsiIdentifier && element.parent is PsiJavaCodeReferenceElement
    }
 
    @Throws(IncorrectOperationException::class)
    override fun invoke(project: Project, editor: Editor, element: PsiElement) {
        val typeName = element.text
        // 变量名第一个字母改成小写
        val varName = typeName.replaceRange(0, 1, ""+typeName.get(0).toLowerCase())
 
        val containingFile = element.containingFile
        val psiDocumentManager = PsiDocumentManager.getInstance(project)
        val document = psiDocumentManager.getDocument(containingFile)
        val statement = " $varName = new ${typeName}();"
        val offset = element.endOffset
        // 在当前元素的后面,插入文本
        document!!.insertString(offset, statement)
    }
 
    override fun getFamilyName(): @IntentionFamilyName String {
        return "new对象"
    }
 
    override fun getText(): @IntentionFamilyName String {
        // 提示的名称
        return "new对象"
    }
}

2.2.2 注册Aciton
resource/META-INF/plugin.xml是插件的配置文件,将自定义的action类注册到配置文件里去。

<extensions defaultExtensionNs="com.intellij">
    <intentionAction>
        <className>com.github.commongenerator.actions.NewObjectGenerator</className>
    </intentionAction>
</extensions>

2.2.3 启动插件
执行:gradle->intellij->runide
会在沙箱里启动ide实例,这个实例能访问到最新的插件代码,也可以通过Debug模式启动。


image.png

2.2.4 测试插件
在User类名上,通过shift+enter触发Intention action,弹出了“new对象”提示。


image.png

image.png

2.3 发布插件(插件市场)

2.3.1 手工发布

先在插件市场创建插件,需要上传jar包。在执行过runide后,会在build/libs下生成jar包。


image.png

如果是正式的版本,就插件就会进入审核状态。


image.png

2.3.2 自动发布

通过publishPlugin脚本,可以在idea上直接发布插件到市场。build.gradle.kts里配置了publishPlugin相关的参数,配置里提示我们需要在系统环境变量里提供PUBLISH_TOKEN。


image.png

申请PUBLISH_TOKEN

PUBLISH_TOKEN通过插件超市的个人页面上申请。

设置PUBLISH_TOKEN

我用的是zsh,所以在~/.zshrc文件里添加了环境变量

export PUBLISH_TOKEN="perm:xxxxx"

发布插件

执行publishPlugin脚本


image.png

3. 总结

至此,插件的开发和发布流程就结束了。可以看出,jetbrain通过模板代码、发布脚本等方式,大大简化了插件的开发成本,让普通开发者也可以快速的开发出插件。IDEA作为我们最重要的开发工具,每个开发者都应该体验一下插件开发的乐趣。

4. 相关文献

IntelliJ Platform SDK官方文档:https://plugins.jetbrains.com/docs/intellij/getting-started.html
IntelliJ Platform SDK中文文档:IntelliJ Platform SDK / IntelliJ Platform SDK DevGuide

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容