当前位置: 首页 > news >正文

多语言编码Agent解决方案(5)-IntelliJ插件实现

IntelliJ插件实现:支持多语言的编码Agent集成

本部分包含IntelliJ插件的完整实现,包括多语言支持、动作注册、API调用和UI集成。插件使用Java开发,基于IntelliJ Platform Plugin SDK。

1. IntelliJ插件目录结构

intellij-plugin/
├── src/                           # 源代码
│   └── main
│       ├── java
│       │   └── com
│       │       └── codingagent
│       │           ├── AgentActions.java # 动作处理类
│       │           ├── ApiClient.java    # API调用工具
│       │           └── i18n
│       │               └── Messages.java # 国际化消息类
│       └── resources/                    # 资源文件
│           └── locales/                  # 语言文件
│               ├── messages.properties    # 英文(默认)
│               ├── messages_zh_CN.properties # 中文
│               └── messages_ja.properties # 日文
├── META-INF/                      # 元数据
│   └── plugin.xml                 # 插件配置
└── build.gradle                   # 构建脚本(可选,假设使用Gradle)

2. 国际化支持 (Messages.java)

// src/main/java/com/codingagent/i18n/Messages.java
package com.codingagent.i18n;import com.intellij.BundleBase;
import com.intellij.openapi.util.NotNullLazyValue;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.PropertyKey;import java.util.ResourceBundle;public class Messages {@NonNlsprivate static final String BUNDLE = "locales.messages";private static final NotNullLazyValue<ResourceBundle> LAZY_BUNDLE = NotNullLazyValue.createValue(() -> {String lang = System.getProperty("user.language");if ("zh".equals(lang)) {return ResourceBundle.getBundle(BUNDLE, new java.util.Locale("zh", "CN"));} else if ("ja".equals(lang)) {return ResourceBundle.getBundle(BUNDLE, java.util.Locale.JAPANESE);} else {return ResourceBundle.getBundle(BUNDLE, java.util.Locale.ENGLISH);}});private Messages() {}public static String message(@PropertyKey(resourceBundle = BUNDLE) String key, Object... params) {return BundleBase.message(LAZY_BUNDLE.getValue(), key, params);}
}

3. 语言文件 (locales)

messages.properties (英文,默认)

extension.activated=Coding Agent plugin activated
extension.ready=Agent Ready
extension.completing=Completing...
extension.generating=Generating...
extension.explaining=Explaining...
extension.refactoring=Refactoring...
extension.debugging=Debugging...
extension.generatingTests=Generating tests...
extension.error=Error
extension.disconnected=Disconnected
extension.connected=Coding Agent backend connected
extension.cannotConnect=Cannot connect to Coding Agent backend, please ensure the service is startedcommands.complete=Agent: Complete Code
commands.generate=Agent: Generate Code
commands.explain=Agent: Explain Code
commands.refactor=Agent: Refactor Code
commands.debug=Agent: Debug Code
commands.test=Agent: Generate Testsprompts.generateDescription=Describe the code you want to generate
prompts.generatePlaceholder=e.g., Create a REST API endpoint
prompts.selectCode=Please select code first
prompts.completeFailed=Completion failed: {0}
prompts.generateFailed=Generation failed: {0}
prompts.explainFailed=Explanation failed: {0}
prompts.refactorFailed=Refactoring failed: {0}
prompts.debugFailed=Debug failed: {0}
prompts.testFailed=Test generation failed: {0}
prompts.refactorComplete=Refactoring complete: {0}output.explanation=Code Explanation
output.debugAnalysis=Debug Analysis
output.aiGenerated=AI Generated
output.agentSuggestion=Coding Agent Suggestion

messages_zh_CN.properties (中文)

extension.activated=编码助手插件已激活
extension.ready=助手就绪
extension.completing=正在补全...
extension.generating=正在生成...
extension.explaining=正在解释...
extension.refactoring=正在重构...
extension.debugging=正在调试...
extension.generatingTests=正在生成测试...
extension.error=错误
extension.disconnected=未连接
extension.connected=编码助手后端已连接
extension.cannotConnect=无法连接到编码助手后端,请确保服务已启动commands.complete=助手: 补全代码
commands.generate=助手: 生成代码
commands.explain=助手: 解释代码
commands.refactor=助手: 重构代码
commands.debug=助手: 调试代码
commands.test=助手: 生成测试prompts.generateDescription=描述你想生成的代码
prompts.generatePlaceholder=例如:创建一个REST API端点
prompts.selectCode=请先选择代码
prompts.completeFailed=补全失败: {0}
prompts.generateFailed=生成失败: {0}
prompts.explainFailed=解释失败: {0}
prompts.refactorFailed=重构失败: {0}
prompts.debugFailed=调试失败: {0}
prompts.testFailed=测试生成失败: {0}
prompts.refactorComplete=重构完成: {0}output.explanation=代码解释
output.debugAnalysis=调试分析
output.aiGenerated=AI生成
output.agentSuggestion=编码助手建议

messages_ja.properties (日文)

extension.activated=コーディングエージェントプラグインが有効になりました
extension.ready=エージェント準備完了
extension.completing=補完中...
extension.generating=生成中...
extension.explaining=説明中...
extension.refactoring=リファクタリング中...
extension.debugging=デバッグ中...
extension.generatingTests=テスト生成中...
extension.error=エラー
extension.disconnected=切断
extension.connected=コーディングエージェントバックエンドに接続しました
extension.cannotConnect=コーディングエージェントバックエンドに接続できません。サービスが起動していることを確認してくださいcommands.complete=エージェント: コード補完
commands.generate=エージェント: コード生成
commands.explain=エージェント: コード説明
commands.refactor=エージェント: コードリファクタリング
commands.debug=エージェント: コードデバッグ
commands.test=エージェント: テスト生成prompts.generateDescription=生成したいコードを説明してください
prompts.generatePlaceholder=例:REST APIエンドポイントを作成
prompts.selectCode=最初にコードを選択してください
prompts.completeFailed=補完失敗: {0}
prompts.generateFailed=生成失敗: {0}
prompts.explainFailed=説明失敗: {0}
prompts.refactorFailed=リファクタリング失敗: {0}
prompts.debugFailed=デバッグ失敗: {0}
prompts.testFailed=テスト生成失敗: {0}
prompts.refactorComplete=リファクタリング完了: {0}output.explanation=コード説明
output.debugAnalysis=デバッグ分析
output.aiGenerated=AI生成
output.agentSuggestion=コーディングエージェントの提案

4. API调用工具 (ApiClient.java)

// src/main/java/com/codingagent/ApiClient.java
package com.codingagent;import com.intellij.openapi.util.text.StringUtil;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;import java.io.IOException;public class ApiClient {private static final String BASE_URL = "http://localhost:8000/api";private final OkHttpClient client = new OkHttpClient();private final String acceptLanguage;public ApiClient(String acceptLanguage) {this.acceptLanguage = acceptLanguage;}public JSONObject post(String endpoint, JSONObject requestBody) throws IOException {RequestBody body = RequestBody.create(requestBody.toString(),MediaType.get("application/json; charset=utf-8"));Request request = new Request.Builder().url(BASE_URL + endpoint).post(body).addHeader("Accept-Language", acceptLanguage).build();try (Response response = client.newCall(request).execute()) {if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);return new JSONObject(StringUtil.notNullize(response.body().string()));}}public JSONObject get(String endpoint) throws IOException {Request request = new Request.Builder().url(BASE_URL + endpoint).addHeader("Accept-Language", acceptLanguage).build();try (Response response = client.newCall(request).execute()) {if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);return new JSONObject(StringUtil.notNullize(response.body().string()));}}
}

5. 动作处理类 (AgentActions.java)

// src/main/java/com/codingagent/AgentActions.java
package com.codingagent;import com.codingagent.i18n.Messages;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.vfs.VirtualFile;
import org.json.JSONArray;
import org.json.JSONObject;public class AgentActions {private static final ApiClient apiClient = new ApiClient(System.getProperty("user.language"));public static class CompleteAction extends AnAction {@Overridepublic void actionPerformed(@NotNull AnActionEvent e) {Editor editor = e.getData(CommonDataKeys.EDITOR);if (editor == null) return;Document document = editor.getDocument();CaretModel caretModel = editor.getCaretModel();int offset = caretModel.getOffset();try {JSONObject request = new JSONObject();request.put("action", "complete");request.put("code", document.getText());request.put("cursor_position", offset);request.put("language", getLanguage(e.getData(CommonDataKeys.VIRTUAL_FILE)));JSONObject response = apiClient.post("/code", request);String result = response.getString("result");com.intellij.openapi.command.WriteCommandAction.runWriteCommandAction(e.getProject(), () -> {document.insertString(offset, result);});} catch (Exception ex) {Messages.showErrorDialog(Messages.message("prompts.completeFailed", ex.getMessage()), Messages.message("extension.error"));}}}public static class GenerateAction extends AnAction {@Overridepublic void actionPerformed(@NotNull AnActionEvent e) {Project project = e.getProject();String instruction = Messages.showInputDialog(project,Messages.message("prompts.generateDescription"),Messages.message("commands.generate"),null,Messages.message("prompts.generatePlaceholder"), null);if (instruction == null) return;Editor editor = e.getData(CommonDataKeys.EDITOR);if (editor == null) return;Document document = editor.getDocument();int offset = editor.getCaretModel().getOffset();try {JSONObject request = new JSONObject();request.put("action", "generate");request.put("instruction", instruction);request.put("language", getLanguage(e.getData(CommonDataKeys.VIRTUAL_FILE)));JSONObject response = apiClient.post("/code", request);String result = response.getString("result");com.intellij.openapi.command.WriteCommandAction.runWriteCommandAction(project, () -> {document.insertString(offset, result);});} catch (Exception ex) {Messages.showErrorDialog(Messages.message("prompts.generateFailed", ex.getMessage()), Messages.message("extension.error"));}}}public static class ExplainAction extends AnAction {@Overridepublic void actionPerformed(@NotNull AnActionEvent e) {Editor editor = e.getData(CommonDataKeys.EDITOR);if (editor == null) return;SelectionModel selectionModel = editor.getSelectionModel();String code = selectionModel.getSelectedText();if (code == null || code.isEmpty()) {Messages.showWarningDialog(Messages.message("prompts.selectCode"), "Warning");return;}try {JSONObject request = new JSONObject();request.put("action", "explain");request.put("code", code);JSONObject response = apiClient.post("/code", request);String result = response.getString("result");JBPopupFactory.getInstance().createMessage(result).showInFocusCenter();} catch (Exception ex) {Messages.showErrorDialog(Messages.message("prompts.explainFailed", ex.getMessage()), Messages.message("extension.error"));}}}public static class RefactorAction extends AnAction {@Overridepublic void actionPerformed(@NotNull AnActionEvent e) {Editor editor = e.getData(CommonDataKeys.EDITOR);if (editor == null) return;SelectionModel selectionModel = editor.getSelectionModel();String code = selectionModel.getSelectedText();if (code == null || code.isEmpty()) {Messages.showWarningDialog(Messages.message("prompts.selectCode"), "Warning");return;}int start = selectionModel.getSelectionStart();int end = selectionModel.getSelectionEnd();try {JSONObject request = new JSONObject();request.put("action", "refactor");request.put("code", code);JSONObject response = apiClient.post("/code", request);String result = response.getString("result");Document document = editor.getDocument();com.intellij.openapi.command.WriteCommandAction.runWriteCommandAction(e.getProject(), () -> {document.replaceString(start, end, result);});JSONArray suggestions = response.optJSONArray("suggestions");if (suggestions != null) {Messages.showInfoDialog(Messages.message("prompts.refactorComplete", suggestions.toString()), "Info");}} catch (Exception ex) {Messages.showErrorDialog(Messages.message("prompts.refactorFailed", ex.getMessage()), Messages.message("extension.error"));}}}public static class DebugAction extends AnAction {@Overridepublic void actionPerformed(@NotNull AnActionEvent e) {Editor editor = e.getData(CommonDataKeys.EDITOR);if (editor == null) return;String code = editor.getDocument().getText();try {JSONObject request = new JSONObject();request.put("action", "debug");request.put("code", code);JSONObject response = apiClient.post("/code", request);String result = response.getString("result");JBPopupFactory.getInstance().createMessage(result).showInFocusCenter();} catch (Exception ex) {Messages.showErrorDialog(Messages.message("prompts.debugFailed", ex.getMessage()), Messages.message("extension.error"));}}}public static class TestAction extends AnAction {@Overridepublic void actionPerformed(@NotNull AnActionEvent e) {Editor editor = e.getData(CommonDataKeys.EDITOR);if (editor == null) return;SelectionModel selectionModel = editor.getSelectionModel();String code = selectionModel.hasSelection() ? selectionModel.getSelectedText() : editor.getDocument().getText();try {JSONObject request = new JSONObject();request.put("action", "test");request.put("code", code);JSONObject response = apiClient.post("/code", request);String result = response.getString("result");// 创建新文件或显示在弹出窗口中JBPopupFactory.getInstance().createMessage(result).showInFocusCenter();} catch (Exception ex) {Messages.showErrorDialog(Messages.message("prompts.testFailed", ex.getMessage()), Messages.message("extension.error"));}}}private static String getLanguage(VirtualFile file) {if (file == null) return "java";String extension = file.getExtension();if (extension == null) return "java";switch (extension) {case "py": return "python";case "js": return "javascript";// 添加更多default: return "java";}}
}

6. 插件配置 (META-INF/plugin.xml)

<idea-plugin><id>com.codingagent.intellij</id><name>Coding Agent</name><vendor>Your Company</vendor><version>1.0.0</version><description>Local AI-powered coding assistant with multi-language support for IntelliJ</description><depends>com.intellij.modules.platform</depends><actions><group id="CodingAgent.Menu" text="Coding Agent" popup="true"><add-to-group group-id="EditorPopupMenu" anchor="last"/><action id="CodingAgent.Complete" class="com.codingagent.AgentActions$CompleteAction" text="%commands.complete%"/><action id="CodingAgent.Generate" class="com.codingagent.AgentActions$GenerateAction" text="%commands.generate%"/><action id="CodingAgent.Explain" class="com.codingagent.AgentActions$ExplainAction" text="%commands.explain%"/><action id="CodingAgent.Refactor" class="com.codingagent.AgentActions$RefactorAction" text="%commands.refactor%"/><action id="CodingAgent.Debug" class="com.codingagent.AgentActions$DebugAction" text="%commands.debug%"/><action id="CodingAgent.Test" class="com.codingagent.AgentActions$TestAction" text="%commands.test%"/></group></actions><extensions defaultExtensionNs="com.intellij"><!-- 如有需要,添加更多扩展 --></extensions>
</idea-plugin>

这个IntelliJ插件实现提供了完整的编码辅助功能,支持多语言界面,并与本地后端服务集成。注意:实际开发中需要添加OkHttp依赖到build.gradle,并处理更多边缘情况。


文章转载自:

http://c8sBchqV.wkmyt.cn
http://JCN8EFhG.wkmyt.cn
http://eZgeK5ET.wkmyt.cn
http://PITpr7GW.wkmyt.cn
http://QBR7yy8O.wkmyt.cn
http://vSnriltg.wkmyt.cn
http://udI9Mg4b.wkmyt.cn
http://h5cNKy0o.wkmyt.cn
http://FpEuAEGO.wkmyt.cn
http://AvAwXkF6.wkmyt.cn
http://hisXMYSc.wkmyt.cn
http://fz5VMGyl.wkmyt.cn
http://c1wCcEdy.wkmyt.cn
http://dUma9Csx.wkmyt.cn
http://ITe8H3ra.wkmyt.cn
http://80Jir26x.wkmyt.cn
http://h3nO78ao.wkmyt.cn
http://2tKmfCzT.wkmyt.cn
http://Jh94jW1i.wkmyt.cn
http://aJxplmSa.wkmyt.cn
http://mzaTFauP.wkmyt.cn
http://dEVxkQ6J.wkmyt.cn
http://I7SXFvsd.wkmyt.cn
http://NKHLqa91.wkmyt.cn
http://HHuT7Yx9.wkmyt.cn
http://xgNNB8OA.wkmyt.cn
http://P6X7Do6p.wkmyt.cn
http://sb7FkR7r.wkmyt.cn
http://ZjvfMKWC.wkmyt.cn
http://lw8tC1nS.wkmyt.cn
http://www.dtcms.com/a/383986.html

相关文章:

  • 光纤入户技术:原理、策略与市场博弈
  • DeerFlow实践: 日程管理智能体应用框架设计
  • spring、springboot、springCloud
  • Thymeleaf
  • 美团首款AI Agent产品“小美”公测,AI会带来什么?
  • 在 UE5 中配置 SVN 版本工具
  • Qwen3 模型结构解析
  • class_8:java继承
  • Django模型与数据库表映射的两种方式
  • 国产化监控方案:金仓数据库 + Nagios 从零搭建指南,核心指标实时掌握
  • 【Linux探索学习】第一篇Linux的基本指令(1)——开启Linux学习第一篇
  • 关于android.permission.CAPTURE_AUDIO_OUTPUT
  • Android安卓项目调试之Gradle 与 Gradle Wrapper的概念以及常用gradle命令深度详解-优雅草卓伊凡
  • Redis和数据库的一致性
  • 使用node-Express框架写一个学校宿舍管理系统练习项目-前后端分离
  • 上下文工程实践 - 工具管理(上篇)
  • Spring Boot 项目瘦身实战
  • 【git基础】关于新仓库创建的几种方式
  • Dify 中的上下文变量以及它们与 system、user 变量的关系和配合方式
  • 【Android】可折叠式标题栏
  • Open cascade中如何使用BRepAlgoAPI_Splitter分割一个Face
  • JAVA开发知识合集6
  • 深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)第十二章知识点问答(15题)
  • 条件表达式和逻辑表达式
  • 《数据密集型应用系统设计2》--数据复制与数据分片
  • 【C++】揭秘:虚函数与多态的实现原理
  • 项目交付后知识沉淀断档怎么办
  • Spring事务传播行为全解析
  • OpenCV一些进阶操作
  • Layer、LayUI