IDEA 插件开发入门教程
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
IntelliJ IDEA 是目前最好用的 JAVA 開發(fā) IDE,它本身的功能已經(jīng)非常強(qiáng)大了,但是每個(gè)人的需求不一樣,有些需求 IDEA 本身無法滿足,于是我們就需要自己開發(fā)插件來解決。工欲善其事,必先利其器,想要提高開發(fā)效率,我們可以借助 IDEA 提供的插件功能來滿足我們的需求。如果沒有我需要的功能怎么辦?很簡單,我們自己造一個(gè)!
插件能做什么?
IDEA 的插件幾乎可以做任何事情,因?yàn)樗?IDE 本身的能力都封裝好開放出來了。主要的插件功能包含以下四種:
- 自定義語言支持:如果有 IDEA 暫時(shí)不支持的語言,你可以自己寫一個(gè)插件來支持,例如 Go 語言原來的支持就是通過插件做的,后來單獨(dú)做了一個(gè) Goland。官方有自定義語言插件支持的教程。
- 框架支持:例如Struts 2?的框架支持
- 工具集成:可以給 IDEA 的自帶功能進(jìn)行增強(qiáng),例如對(duì) Git 的操作增加 CodeReview 的功能。參考Gerrit
- 用戶界面:自定義的插件改變用戶界面。參考BackgroundImage
我為了減少重復(fù)代碼的編寫,寫了一個(gè)代碼生成的插件IDEA代碼生成插件CodeMaker,支持自定義代碼生成的模板。
Hello world 插件
依照慣例,我們從 Hello world 開始。
新建一個(gè) Gradle 的插件工程
有些教程推薦用 IDEA 默認(rèn)的插件工程來開始,但是我比較推薦用 Gradle 來管理整個(gè)插件工程,后面的依賴管理會(huì)很方便,否則都得靠手動(dòng)管理。
點(diǎn)擊新建工程,選擇 Gradle
接下來填寫項(xiàng)目屬性
配置 Gradle,用默認(rèn)配置就行
新建完工程之后,IDEA 會(huì)自動(dòng)開始解析項(xiàng)目依賴,因?yàn)樗螺d一個(gè)幾百兆的 SDK 依賴包,所以會(huì)比較久,打開科學(xué)上網(wǎng)能快一點(diǎn)。
Gradle 依賴解析完成之后,項(xiàng)目結(jié)構(gòu)如下圖,其中 plugin.xml 是插件的配置,build.gradle 是項(xiàng)目依賴的配置(類比 pom.xml)。
下面就是默認(rèn)生成的 plugin.xml
<idea-plugin><!--插件id--><id>com.xiaokai.test.demo</id><!--插件名稱--><name>Demo</name><!--開發(fā)者信息--><vendor email="support@yourcompany.com" url="http://www.yourcompany.com">YourCompany</vendor><!--插件說明--><description><![CDATA[Enter short description for your plugin here.<br><em>most HTML tags may be used</em>]]></description><!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.htmlon how to target different products --><!-- uncomment to enable plugin in all products<depends>com.intellij.modules.lang</depends>--><!--依賴的其他插件能力--><extensions defaultExtensionNs="com.intellij"><!-- Add your extensions here --></extensions><!--插件動(dòng)作--><actions><!-- Add your actions here --></actions> </idea-plugin>創(chuàng)建一個(gè) Action
Action 是 IDEA 中對(duì)事件響應(yīng)的處理器,它的 actionPerformed 就像是 JS 中的 onClick 方法??梢钥闯鰜?#xff0c;插件的開發(fā)本質(zhì)上跟 web、Android 的開發(fā)沒有什么不同,因?yàn)槎际鞘录?qū)動(dòng)的編程。
我們可以直接使用 IDEA 提供的 Action 生成器
點(diǎn)擊 OK 之后會(huì)在 src 生成類文件:
package com.xiaokai.test;import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent;public class HelloWorldAction extends AnAction {@Overridepublic void actionPerformed(AnActionEvent e) {// TODO: insert action logic here} }同時(shí),動(dòng)作的信息也會(huì)注冊(cè)到 plugin.xml 中
<!--插件動(dòng)作--><actions><!-- Add your actions here --><action id="demo.hello.world" class="com.xiaokai.test.HelloWorldAction" text="HelloWorld"description="Say Hello World"><add-to-group group-id="GenerateGroup" anchor="last"/></action></actions>彈出對(duì)話框
創(chuàng)建完 Action 之后我們就要開始往里面寫邏輯了,既然是 Hello World 教學(xué),那我們就來試一下最簡單的彈出對(duì)話框。
@Overridepublic void actionPerformed(AnActionEvent e) {//獲取當(dāng)前在操作的工程上下文Project project = e.getData(PlatformDataKeys.PROJECT);//獲取當(dāng)前操作的類文件PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);//獲取當(dāng)前類文件的路徑String classPath = psiFile.getVirtualFile().getPath();String title = "Hello World!";//顯示對(duì)話框Messages.showMessageDialog(project, classPath, title, Messages.getInformationIcon());}代碼寫完之后,打開 Gradle 的界面,點(diǎn)擊 runIde 就會(huì)啟動(dòng)一個(gè)安裝了插件的 IDEA,然后就可以進(jìn)行測(cè)試。你還可以右鍵啟動(dòng) Debug 模式,這樣還能進(jìn)行斷點(diǎn)。
運(yùn)行的效果如下圖:
可以看到,我們右鍵打開 Generate 菜單之后,里面最后一項(xiàng)就是我們添加的 Action,
進(jìn)階的教程
如果想學(xué)習(xí)更多的原理和設(shè)計(jì)理念可以看IntelliJ Platform SDK的官方文檔。不過老實(shí)說,它的文檔寫的挺差的,基本上就是簡單講了一下概念和原理,沒有深入的分析。所以如果要深入研究還得靠自己。最靠譜的學(xué)習(xí)方式就是看別人寫的插件,舉個(gè)例子,你想知道怎么樣實(shí)現(xiàn)自動(dòng)生成代碼,你就去找支持這個(gè)功能的插件,看他的源碼是怎么寫的。
我當(dāng)時(shí)寫CodeMaker的時(shí)候也是靠自己啃源碼之后寫出來的。下面我簡單介紹一下我用過的一些 API,這些 API 基本都沒有文檔說明,全靠代碼相傳。
判斷當(dāng)前光標(biāo)選擇的元素是什么
//獲取當(dāng)前事件觸發(fā)時(shí),光標(biāo)所在的元素PsiElement psiElement = anActionEvent.getData(LangDataKeys.PSI_ELEMENT);//如果光標(biāo)選擇的不是類,彈出對(duì)話框提醒if (psiElement == null || !(psiElement instanceof PsiClass)) {Messages.showMessageDialog(project, "Please focus on a class", "Generate Failed", null);return;}獲取當(dāng)前類文件的所有類對(duì)象
一個(gè)類文件中可能會(huì)有內(nèi)部類,所以讀取的時(shí)候返回的是一個(gè)列表
public static List<PsiClass> getClasses(PsiElement element) {List<PsiClass> elements = Lists.newArrayList();List<PsiClass> classElements = PsiTreeUtil.getChildrenOfTypeAsList(element, PsiClass.class);elements.addAll(classElements);for (PsiClass classElement : classElements) {//這里用了遞歸的方式獲取內(nèi)部類elements.addAll(getClasses(classElement));}return elements;}格式化代碼
public static void reformatJavaFile(PsiElement theElement) {CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(theElement.getProject());try {codeStyleManager.reformat(theElement);} catch (Exception e) {LOGGER.error("reformat code failed", e);}}使用粘貼板
CopyPasteManager.getInstance().setContents(new SimpleTransferable(table.toString(), DataFlavor.allHtmlFlavor));原文鏈接
轉(zhuǎn)載于:https://my.oschina.net/u/1464083/blog/3014373
總結(jié)
以上是生活随笔為你收集整理的IDEA 插件开发入门教程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 做梦梦到老太太拉屎啥意思
- 下一篇: 你认为已经过时的C语言,是如何影响500