【工具使用】小白入门idea插件开发

文章目录

    • 开发流程
      • **一、开发环境准备**
      • **二、创建插件项目**
      • **三、插件核心配置(plugin.xml)**
      • **四、编写插件功能**
        • **1. 实现 Action(动作)**
        • **2. 使用扩展点(Extensions)**
        • **3. 界面开发**
      • **五、调试与运行**
      • **六、打包与发布**
        • **1. 生成 JAR 包**
        • **2. 发布到 JetBrains 插件市场**
        • **3. 本地安装**
      • **七、核心概念与 API**
      • **八、注意事项**
      • **九、常见问题**
    • 核心语法
      • **1. 动作(Action)**
        • **定义 Action**
        • **注册 Action(plugin.xml)**
      • **2. 扩展点(Extensions)**
        • **工具窗口(ToolWindow)**
      • **3. PSI(Program Structure Interface)**
        • **获取当前文件的 PSI**
        • **修改代码**
      • **4. 服务(Services)**
        • **定义服务**
        • **使用服务**
      • **5. 持久化状态(PersistentState)**
        • **定义状态类**
        • **使用配置**
      • **6. 界面开发**
        • **Swing 组件**
        • **Kotlin UI DSL(推荐)**
      • **7. 监听编辑器事件**
      • **8. 代码检查与快速修复**
        • **自定义检查器**
        • **快速修复(QuickFix)**
      • **9. 异步任务**
      • **10. 通知与对话框**
        • **显示通知**
        • **自定义对话框**
      • **总结**

开发流程

下面是一个完整的 IntelliJ IDEA 插件开发流程,从环境搭建到发布,逐步讲解:

一、开发环境准备

  1. 安装 IntelliJ IDEA

    • 推荐使用最新版本的 IntelliJ IDEA Ultimate(社区版也能开发插件,但某些功能受限)。
    • 下载地址:https://www.jetbrains.com/idea/
  2. 安装 JDK

    • 需要 JDK 11 或更高版本(推荐 JDK 17)。
    • 确保环境变量配置正确。
  3. 配置 IntelliJ Plugin SDK

    • 打开 IDEA,进入 File -> Project Structure -> SDKs
    • 添加 IntelliJ Platform Plugin SDK,选择 IDEA 安装目录(会自动检测所需依赖)。

二、创建插件项目

  1. 新建项目

    • 选择 File -> New -> Project
    • 项目类型选择 IntelliJ Platform Plugin
    • 模板可选 Gradle(推荐)或 DevKit(旧版)。
      • Gradle 更灵活,支持依赖管理,适合复杂插件。
      • DevKit 适合简单插件,但已逐渐被弃用。
  2. 配置项目基本信息

    • 填写 GroupId(如 com.yourcompany)、ArtifactId(插件名称)、版本号等。
    • 确保选择正确的 JDK 和 IntelliJ Platform SDK。
  3. 项目结构

    • 生成的项目包含以下关键文件:
      • src/main/java: Java/Kotlin 代码目录。
      • resources/META-INF/plugin.xml: 插件的核心配置文件。
      • build.gradle.kts(或 build.gradle): Gradle 构建脚本。

三、插件核心配置(plugin.xml)

plugin.xml 中定义插件元数据和功能扩展点:

<idea-plugin>
    <id>com.yourcompany.plugin-nameid>
    <name>Your Plugin Namename>
    <version>1.0.0version>
    <vendor email="[email protected]" url="https://yourcompany.com">Your Companyvendor>

    <description>description>

    
    <depends>com.intellij.modules.platformdepends>

    
    <extensions defaultExtensionNs="com.intellij">
        
        <toolWindow id="MyToolWindow" anchor="right" factoryClass="com.yourcompany.MyToolWindowFactory"/>
    extensions>

    
    <actions>
        <action id="YourAction" class="com.yourcompany.YourAction" text="Action Text" description="Action Description">
            <add-to-group group-id="ToolsMenu" anchor="first"/>
        action>
    actions>
idea-plugin>

四、编写插件功能

1. 实现 Action(动作)

Action 是插件的入口点,例如菜单项、工具栏按钮等。

public class MyAction extends AnAction {
    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        // 点击动作后的逻辑
        Project project = e.getProject();
        Messages.showMessageDialog(project, "Hello World!", "Greeting", Messages.getInformationIcon());
    }
}
2. 使用扩展点(Extensions)
  • 工具窗口(ToolWindow): 创建自定义界面。
  • 编辑器监听(EditorListener): 监听编辑器事件。
  • 代码分析(Inspection): 自定义代码检查规则。
  • 文件类型(FileType): 支持新文件类型。
3. 界面开发
  • 使用 SwingIntelliJ 的 UI Designer 创建界面。
  • 推荐使用 Kotlin UI DSL(JetBrains 官方推荐)构建现代化界面。

五、调试与运行

  1. 运行插件

    • 点击 Gradle 任务的 runIde,会启动一个沙盒 IDEA 实例,插件已自动加载。
    • 在沙盒中测试插件功能。
  2. 调试

    • 在代码中设置断点,直接以 Debug 模式运行 runIde
    • 支持热重载(修改代码后无需重启沙盒)。

六、打包与发布

1. 生成 JAR 包
  • 执行 Gradle 任务 buildPlugin,生成的 JAR 文件在 build/libs 目录。
  • 插件 JAR 包含所有依赖(如果配置了 shadowJar)。
2. 发布到 JetBrains 插件市场
  • 访问 JetBrains Plugins Repository。
  • 注册账号并上传 JAR 文件,填写插件描述、截图等信息。
  • 审核通过后,用户可通过 IDEA 内置插件市场安装。
3. 本地安装
  • 用户可将 JAR 文件拖入 IDEA 窗口,或通过 File -> Settings -> Plugins -> Install Plugin from Disk 安装。

七、核心概念与 API

  1. PSI(Program Structure Interface)

    • 用于操作代码的抽象语法树(AST),例如解析、修改 Java/Kotlin 代码。
  2. AnAction

    • 定义用户触发的动作(如菜单项、快捷键)。
  3. Services

    • 插件可以通过 Service 实现单例管理或全局状态。
  4. PersistentState

    • 使用 PersistentStateComponent 保存插件配置。

八、注意事项

  1. 兼容性

    • build.gradle 中指定兼容的 IDEA 版本:
      intellij {
          version = '2023.1' // 指定 IDEA 版本
          type = 'IC' // 社区版,'IU' 为 Ultimate 版
      }
      
  2. 依赖管理

    • 通过 Gradle 添加第三方库依赖:
      dependencies {
          implementation 'com.squareup.okhttp3:okhttp:4.9.3'
      }
      
  3. 性能优化

    • 避免阻塞 UI 线程,长时间任务需在后台线程执行。
  4. 文档与社区

    • 官方文档:IntelliJ Platform SDK
    • 示例项目:IntelliJ SDK Code Samples

九、常见问题

  • 插件无法加载: 检查 plugin.xml 配置和依赖。
  • API 过时: 使用最新版本的 IntelliJ SDK。
  • UI 卡顿: 确保耗时操作在后台线程执行。

按照这个流程,你可以从零开始开发一个功能完整的 IntelliJ 插件。如果有具体需求(如代码分析、自定义语言支持等),可以进一步深入相关 API!

核心语法

以下是 IntelliJ IDEA 插件开发的核心语法和关键 API 详解,结合代码示例和关键概念,帮助你快速上手:

1. 动作(Action)

Action 是用户触发操作的核心入口(如菜单项、快捷键、工具栏按钮)。

定义 Action
public class MyAction extends AnAction {
    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        // 获取当前项目
        Project project = e.getProject();
        // 显示对话框
        Messages.showMessageDialog(project, "Hello Plugin!", "Greeting", Messages.getInformationIcon());
    }

    @Override
    public void update(@NotNull AnActionEvent e) {
        // 动态控制 Action 是否可见/启用
        Project project = e.getProject();
        e.getPresentation().setEnabledAndVisible(project != null);
    }
}
注册 Action(plugin.xml)
<actions>
    <action 
        id="MyPlugin.MyAction" 
        class="com.example.MyAction" 
        text="Say Hello" 
        description="Show a greeting message">
        
        <add-to-group group-id="ToolsMenu" anchor="first"/>
        
        <keyboard-shortcut keymap="$default" first-keystroke="ctrl shift H"/>
    action>
actions>

2. 扩展点(Extensions)

通过 plugin.xml 扩展 IDEA 的核心功能(如工具窗口、编辑器监听等)。

工具窗口(ToolWindow)
public class MyToolWindowFactory implements ToolWindowFactory {
    @Override
    public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
        // 创建界面组件
        JPanel panel = new JPanel();
        panel.add(new JLabel("My Tool Window"));
        // 将组件添加到工具窗口
        ContentFactory contentFactory = ContentFactory.getInstance();
        Content content = contentFactory.createContent(panel, "", false);
        toolWindow.getContentManager().addContent(content);
    }
}

注册工具窗口(plugin.xml):

<extensions defaultExtensionNs="com.intellij">
    <toolWindow 
        id="MyToolWindow" 
        anchor="right" 
        factoryClass="com.example.MyToolWindowFactory"/>
extensions>

3. PSI(Program Structure Interface)

用于操作代码的抽象语法树(AST),支持代码解析和修改。

获取当前文件的 PSI
public void actionPerformed(@NotNull AnActionEvent e) {
    Editor editor = e.getData(CommonDataKeys.EDITOR);
    PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);
    if (editor == null || psiFile == null) return;

    // 获取当前光标位置元素
    int offset = editor.getCaretModel().getOffset();
    PsiElement element = psiFile.findElementAt(offset);
}
修改代码
// 在写操作中修改 PSI
WriteCommandAction.runWriteCommandAction(project, () -> {
    PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
    PsiMethod method = factory.createMethodFromText("public void test() {}", null);
    // 将方法添加到类中
    PsiClass psiClass = ...; // 获取目标类
    psiClass.add(method);
});

4. 服务(Services)

用于管理插件全局状态或单例服务。

定义服务
public interface MyService {
    void doSomething();
}

// 实现类
@Service
public final class MyServiceImpl implements MyService {
    @Override
    public void doSomething() {
        // 具体逻辑
    }
}
使用服务
MyService service = project.getService(MyService.class);
service.doSomething();

5. 持久化状态(PersistentState)

保存插件配置到 IDE 的配置文件。

定义状态类
@State(name = "MyPluginSettings", storages = @Storage("myplugin.xml"))
public class MySettings implements PersistentStateComponent<MySettings.State> {
    public static class State {
        public String username = "default";
        public boolean enabled = true;
    }

    private State state = new State();

    @Override
    public State getState() {
        return state;
    }

    @Override
    public void loadState(@NotNull State state) {
        this.state = state;
    }
}
使用配置
MySettings settings = ServiceManager.getService(MySettings.class);
String username = settings.getState().username;
settings.getState().enabled = false;

6. 界面开发

Swing 组件
JPanel panel = new JPanel(new BorderLayout());
JButton button = new JButton("Click Me");
button.addActionListener(e -> {
    // 按钮点击事件
});
panel.add(button, BorderLayout.CENTER);
Kotlin UI DSL(推荐)
// 在 Kotlin 中使用
panel {
    row {
        button("Click Me") {
            // 点击事件
        }
        checkBox("Enable Feature")
    }
}

7. 监听编辑器事件

public class MyEditorListener implements EditorFactoryListener {
    @Override
    public void editorCreated(@NotNull EditorFactoryEvent event) {
        Editor editor = event.getEditor();
        Document document = editor.getDocument();
        // 监听文档变化
        document.addDocumentListener(new DocumentListener() {
            @Override
            public void documentChanged(@NotNull DocumentEvent event) {
                // 处理变化
            }
        });
    }
}

注册监听器(plugin.xml):

<applicationListeners>
    <listener 
        class="com.example.MyEditorListener" 
        topic="com.intellij.openapi.editor.event.EditorFactoryListener"/>
applicationListeners>

8. 代码检查与快速修复

自定义检查器
public class MyInspection extends AbstractBaseJavaLocalInspectionTool {
    @Override
    public @NotNull PsiElementVisitor buildVisitor(
        @NotNull ProblemsHolder holder,
        boolean isOnTheFly
    ) {
        return new JavaElementVisitor() {
            @Override
            public void visitMethod(PsiMethod method) {
                if (method.getName().startsWith("test")) {
                    holder.registerProblem(
                        method.getNameIdentifier(),
                        "方法名不应以 'test' 开头",
                        ProblemHighlightType.WARNING
                    );
                }
            }
        };
    }
}
快速修复(QuickFix)
public class RenameMethodFix implements LocalQuickFix {
    @Override
    public @NotNull String getFamilyName() {
        return "重命名方法";
    }

    @Override
    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
        PsiMethod method = (PsiMethod) descriptor.getPsiElement();
        method.setName("newName");
    }
}

9. 异步任务

避免阻塞 UI 线程,使用 ApplicationManager.getApplication().executeOnPooledThread()AsyncTask

ApplicationManager.getApplication().executeOnPooledThread(() -> {
    // 后台任务
    String result = doHeavyWork();
    // 更新 UI(需切回 UI 线程)
    ApplicationManager.getApplication().invokeLater(() -> {
        Messages.showInfoMessage(result, "Result");
    });
});

10. 通知与对话框

显示通知
NotificationGroupManager.getInstance()
    .getNotificationGroup("MyPlugin")
    .createNotification("任务完成", NotificationType.INFORMATION)
    .notify(project);
自定义对话框
public class MyDialog extends DialogWrapper {
    private JTextField textField;

    protected MyDialog(Project project) {
        super(project);
        init();
        setTitle("输入对话框");
    }

    @Override
    protected JComponent createCenterPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        textField = new JTextField();
        panel.add(textField, BorderLayout.CENTER);
        return panel;
    }

    public String getInput() {
        return textField.getText();
    }
}

总结

  • 核心 APIAnAction, ToolWindow, PSI, Services, PersistentStateComponent
  • 线程安全:UI 操作必须在主线程,耗时操作需异步执行
  • 版本兼容:通过 build.gradle 指定兼容的 IDEA 版本
  • 官方文档:IntelliJ Platform SDK Docs

通过掌握这些核心语法和 API,你可以实现从简单的工具插件到复杂的代码分析功能。建议结合官方示例代码实践调试!

你可能感兴趣的:(开发工具知识,intellij-idea,java,ide)