介绍 在过去几年中,JetBrains的IntelliJ很快成为Java开发人员的顶级IDE。使IntelliJ对Java开发人员如此有吸引力的一个特性是使用插件扩展和创建新功能的能力。在本教程中,我们将介绍如何编写IntelliJ插件来演示扩展IDE的几种方法。 虽然本文主要关注IntelliJ插件,但所有JetBrains IDE都共享公共代码。因此,这里使用的许多技术可以应用于JetBrain的其他IDE,如PyCharm、RubyMine等。插件功能 Intellij插件按照功能可分四类:自定义语言 :针对不同语言,能够编写、解释和编译 框架:支持第三方框架,如Spring工具:与外部工具(如Gradle)集成用户界面附加组件:新菜单项、工具窗口和按钮等创建一个插件项目 使用 Plugin DevKit(https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/using_dev_kit.html )来创建工程,DevKit提供了自定义SDK类型和一组用于在IDE中构建插件的操作创建工程 在Intellij的菜单栏,选择 File | New | Project,在New Project 框里选择 IntelliJ PLatform Plugin New Project 在project SDK选项框选择合适的Intellij SDK,然后下一步,填上project name,完成,就创建好一个Intellij plugin 工程了。实现一个自定义的Plugin 创建自定义Action 如果需要了解更多action 相关的东西,请访问官方文档 https://www.jetbrains.org/intellij/sdk/docs/basics/action_system.html 创建自定义的action,需要继承抽象类AnAction,并且需要重写方法AnAction.update() 和AnAction.actionPerformed() :update()方法里面实现开启和禁用事件逻辑actionPerformed()方法里面实现我们需要做的具体业务逻辑package com.test.plugin; import com.intellij.ide.BrowserUtil; import com.intellij.lang.Language; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; public class SearchBaiduAction extends AnAction { /** * Only make this action visible when text is selected. ** The update method below is only called periodically so need * to be careful to check for selected text * https://jetbrains.org/intellij/sdk/docs/basics/action_system.html#overriding-the-anactionupdate-method * * @param e */ @Override public void update(AnActionEvent e) { // Get required data keys final Project project = e.getProject(); final Editor editor = e.getData(CommonDataKeys.EDITOR); // Set visibility only in case of existing project and editor and if a selection exists e.getPresentation().setEnabledAndVisible(project != null && editor != null && editor.getSelectionModel().hasSelection()); } @Override public void actionPerformed(AnActionEvent e) { final String selectedCode = getSelectedCode(e); final String languageTag = getLanguageTag(e); String url = getUrl(languageTag, selectedCode); if (url != null) { BrowserUtil.browse(url); } } private String getSelectedCode(AnActionEvent e) { final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR); return editor.getSelectionModel().getSelectedText(); } private String getLanguageTag(AnActionEvent e) { String languageTag = ""; PsiFile file = e.getData(CommonDataKeys.PSI_FILE); if (file != null) { Language lang =file.getLanguage(); languageTag = lang != null ? lang.getDisplayName().toLowerCase() : null; } return languageTag; } private String getUrl(String languageTag, String selectedCode) { try { StringBuilder sb = new StringBuilder("https://www.baidu.com/s?wd="); if (languageTag != null) { sb.append(" " + URLEncoder.encode(languageTag, "UTF-8")); } sb.append(URLEncoder.encode(selectedCode, "UTF-8")); return sb.toString(); } catch (UnsupportedEncodingException unsupportedEncodingException) { unsupportedEncodingException.printStackTrace(); return null; } } } 如果action被禁用了,那么actionPerformed方法不会被执行 actionPerformed()方法 @Override public void actionPerformed(AnActionEvent e) { final String selectedCode = getSelectedCode(e); final String languageTag = getLanguageTag(e); String url = getUrl(languageTag, selectedCode); if (url != null) { BrowserUtil.browse(url); } } 在该方法中,我们通过getSelectedCode()方法拿到用户选择的文本,通过刚发getLanguageTag()获取当前文本语言,比如java,js,go等。然后通过getURL()方法组装url,最后通过BrowserUtil.browse(url) 打开浏览器,并访问给的url。在我们demo里面,我们将用选择的文本在baidu里面进行搜索。 获取Editor中选择的文本 你需要使用SelectionModel对象获取选择的文本private String getSelectedCode(AnActionEvent e) { final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR); return editor.getSelectionModel().getSelectedText(); } 获取当前文件的语言 从event中通过CommonDataKeys.PSI_FILE key获取到PsiFile对象,然后再从PsiFile中获取到Language。 private String getLanguageTag(AnActionEvent e) { String languageTag = ""; PsiFile file = e.getData(CommonDataKeys.PSI_FILE); if (file != null) { Language lang =file.getLanguage(); languageTag = lang != null ? lang.getDisplayName().toLowerCase() : null; } return languageTag; }注册事件 有两种方式可以注册我们自定义的事件:1. plugin.xml中配置,2.代码中注册 在plugin.xml文件中注册事件: 更多事件注册信息请查看官方文档 https://plugins.jetbrains.com/docs/intellij/basic-action-system.html?from=jetbrains.org#registering-actions-in-pluginxml运行插件 在Idea中运行或者debug插件是非常简单的一件事 配置 运行 结果