跳转到主要内容
OpenIDEA 是一个 Tauri 2 桌面应用。UI 是运行在系统 webview 里的 React + CodeMirror 6 前端;凡是涉及磁盘、进程或网络的工作都在 Rust 里完成。Rust 端的设计让同一套后端既能跑在桌面应用里,也能在远程开发时以 openidea-server 的形式跑在另一台机器上。

全景图

分层

进程

  • 应用进程承载 webview 和整个 Rust 后端(Tokio 运行时加阻塞线程池)。所有窗口共用一个后端,每个项目窗口在 Host 里对应一个 Project。
  • 语言服务器和调试适配器是子进程,按 languages/<id>.toml 针对语言和工作区根目录懒启动。后端通过 ide-lsp、ide-dap(底层是 ide-jsonrpc)与它们通信。见代码智能。
  • 外部工具在能保证与命令行行为一致时直接调用其 CLI:写操作用 git(读操作用进程内的 gitoxide)、docker、adb、gh、Maven/Gradle、通过 ACP 驱动的编码 agent。
  • 插件以 WebAssembly 组件的形式在进程内运行,每个插件一个线程、一个独立的沙箱 store。见插件宿主。
  • openidea-server 是同一个 Host,只是前面换成 JSON-RPC 而不是 Tauri。桌面端通过 SSH、WSL 或 docker exec 启动它,并把远程窗口的命令转给它。见远程开发。
  • 本地服务供外部客户端使用:给 AI agent 的 MCP 服务(ide-mcp)和内置静态 Web 服务(ide-web),都只监听 127.0.0.1。

一次请求的路径

以 Find in Files 为例:
  1. 搜索功能分配一个 RequestId,创建一个 Channel,调用 src/bindings.ts 里的 commands.searchStart(request, query, channel)。
  2. invoke handler 检查完项目信任后,Tauri 分派到 src-tauri/src/commands/search.rs 的 search_start。
  3. 命令转发给 ide_host::ops::search::start,后者为该请求注册一个 CancellationToken,并在阻塞线程上运行 ide-search 引擎。
  4. 每找到一个文件的匹配就通过 channel 发出去;发送 Done 之后命令返回。
  5. 用户取消时,UI 调用 cancel_request(request),token 中止遍历。
远程窗口用的也是同一个 ops::search::start:前端的 invoke 被路由到 remote_invoke,服务端运行完全相同的函数,channel 的值带着 channel id 传回来。

继续阅读

Rust 还是 UI?

功能该放在哪一侧,附实例。

IPC

命令、错误、流式传输、取消和事件。

Crate 一览

每个后端 crate 及其职责。

前端

action、keymap、上下文键和扩展点。