- 思维导图:左侧 Tool Window 管理导图列表(新建/删除/刷新),双击在编辑区打开 JCEF 画布
- 节点记录代码位置:编辑器内右键 "Add to CodeMind"(
Ctrl+Alt+M),弹窗选导图 + 输入节点标题,新节点挂上当前光标代码位置 - 导航代码:
Cmd/Ctrl+点击挂了代码的节点,跳转到对应文件行(已开切 tab、未开新开、恢复选区、stale 阻断) - gutter 反向入口:同一代码位置只显示一个图标;单节点直接跳转,多节点点击后从可搜索列表选择并高亮目标节点
- 画布交互:
- 右键节点 → 加子节点 / 加兄弟节点 / 删除节点
- 双击节点编辑标题
- 拖拽:节点左半区=兄弟排序(插入线提示),右半区=换父节点(高亮提示),空白=无操作
+/-号展开收起子节点,状态持久化- 父节点自动垂直居中于子节点(自底向上布局)
- 代码位置持久化:学官方 Bookmark,
VirtualFile+RangeMarker扛行号漂移、URL 持久化、失效灰显 - 多节点引用:同一文件同一行可被不同导图、同一导图的不同节点共同引用;Gutter 只显示一个图标,点击后选择目标节点
- 导图文件:
<项目根>/.codemind/<导图名>.codemind,JSON 格式,一张导图一个文件,默认进 git 分享 - session 状态:
.codemind/session.json(上次激活导图,不进 git) - 版本兼容:
version字段,读取宽松(缺失默认、多余忽略),约定只增不改
- JDK 17+
- 目标 IntelliJ IDEA 2023.1+(依赖 JCEF)
./gradlew buildPlugin -x buildSearchableOptions产物:build/distributions/codemind-<version>.zip
./gradlew runIde -x buildSearchableOptions启动一个测试 IDE 实例(sandbox)。
- 构建:
./gradlew buildPlugin - IDE → Settings → Plugins → ⚙ → Install Plugin from Disk → 选
build/distributions/codemind-<version>.zip - 重启 IDE
src/main/kotlin/com/codemind/
├── CodeMindFileType.kt # .codemind 文件类型注册
├── action/
│ ├── AttachCodeRefAction.kt # 挂载代码位置入口(右键/快捷键)
│ └── AttachCodeRefDialog.kt # 挂载弹窗(选导图+输入标题)
├── code/
│ ├── CodeRefExtractor.kt # 从编辑器抓代码位置构造 CodeRef
│ ├── GutterIconManager.kt # gutter 图标生命周期(编辑器打开/切换时挂摘)
│ ├── CodeMindGutterIconRenderer.kt # gutter 图标渲染+点击打开导图
│ └── NavigationService.kt # 代码导航(智能打开+恢复选区+stale 阻断)
├── editor/
│ ├── MindMapFileEditorProvider.kt # .codemind 用 JCEF 画布打开
│ └── MindMapJcefEditor.kt # JCEF 编辑器+双向通信桥
├── icons/
│ └── CodeMindIcons.kt # 插件图标
├── model/
│ ├── CodeRef.kt # 代码位置数据结构
│ ├── MindMapDoc.kt # 导图文档
│ └── MindMapNode.kt # 节点(含冲突检测、级联删除)
├── store/
│ ├── CodeRefIndexService.kt # 反向索引(fileUrl+line → 节点引用)
│ ├── MindMapSerializer.kt # JSON 序列化(Gson)
│ ├── MindMapStoreService.kt # 持久化(debounce 落盘+损坏备份+VFS 写锁)
│ ├── CodeMindStartupActivity.kt # 启动重建索引
│ └── SessionService.kt # 上次激活导图状态
└── ui/
├── MindMapListPanel.kt # 导图列表+空状态引导
└── CodeMindToolWindowFactory.kt # Tool Window 工厂
src/main/resources/
├── frontend/mindmap.html # 自包含思维导图画布(右侧树+拖拽+展开收起)
├── icons/ # SVG 图标
└── META-INF/plugin.xml # 扩展点注册
JCEF 前端与 Java 后端双向通信:
- JS→Java:
CefMessageRouter,前端调window.cefQuery({request: JSON}) - Java→JS:
CefBrowser.executeJavaScript,调前端window.__mmInbound(JSON) - 消息格式:
{ type, payload },全量 JSON(不做 diff)
- JCEF 不可用时画布显示降级提示,列表/管理功能仍可用
- 写操作走
WriteAction+ VFS 写锁,和编辑器写互斥 - JSON 损坏时备份
.bak并加载空导图 - 项目级 Service 隔离,
Disposable绑 Project 生命周期
详见 DESIGN.md,记录了 15 个设计分支的决策与取舍。