API 概览

插件可用的所有 API 模块与插件类型可用性。

插件通过 self 访问以下 API 模块。每个模块的可用性取决于插件类型(Ui / Service / Data)以及 plugin.toml 中声明的权限。

通用模块(所有插件类型)

模块说明UiServiceData
self.path插件/数据/缓存/临时目录路径
self.settingsIDE 设置读写
self.message消息通知
self.clipboard剪贴板
self.dialog文件夹选择对话框
self.resources插件资源(PluginResource
self.events事件总线订阅
self.commands命令注册与分派
self.configuration清单配置读写

Ui 与 Service 专用

模块说明UiServiceData
self.file本地文件操作
self.board设备文件操作
self.persistence键值持久化存储
self.documents文档查询与订阅
self.runtime运行时检查(MicroPython)
self.serial串口通信
self.env运行环境(平台/布局/主题模式)
self.theme主题贡献
self.i18n语言包贡献
self.stubs类型存根贡献

Ui 专用

模块说明UiServiceData
self.editor活动编辑器内容与光标操作
self.views原生视图模型与渲染器 facade
self.tabs将贡献视图打开为标签页

常用任务速查

不知道用哪个模块时,按"我想做什么"查找:

我想…用这个
给用户展示界面views(表单/树/表格/日志…)或 components
把视图开成标签页tabs
读写工作区文件file(本地) / board(设备)
读取/修改当前文档、获取符号editor / document
持久化少量键值persistence
串口收发数据serial
检查设备运行时与变量runtime
读 IDE 设置settings
声明/读写自己的配置项configuration
弹通知 / 选文件夹 / 写剪贴板message / dialog / clipboard
获取插件目录与资源path / resources
提供命令或菜单动作commands
订阅 IDE 事件events
了解运行环境environment
贡献主题 / 语言包 / 类型存根theme / i18n / stubs

回调模式

所有 API 方法采用统一的回调模式。回调签名固定为 **kwargs

# 有回调的方法
self.file.get_root_dir(
    lambda **cb: print(cb)
)

# 无回调的方法
self.editor.set_text("Hello")

一次 API 调用的完整往返如下。插件代码只负责发起调用和处理结果,其余步骤由 SDK 与宿主完成:

回调内容

IDE 的响应分为成功与失败两种,都通过同一个回调送达:

  • 成功:响应的 payload.data 是映射时,SDK 调用 callback(**data)。回调里直接读取各 API 的返回字段,例如 pathports
  • 失败:SDK 调用 callback(error=SdkApiError)。不要用整个回调字典是否为空来判断成功,因为成功响应本身可能没有业务字段;应显式读取 error
def on_connect(error=None, **result):
    if error is not None:
        print("连接失败:", error.code, error.message)
        return
    print("连接成功")

self.serial.connect("COM3", callback=on_connect)

请求失败(如权限不足)时,callback(error=...) 收到 SdkApiError 实例;未提供回调时,结果会被丢弃,错误只记录到 IDE 诊断面板。

底层有两种发送方式。Bridge.push() 只负责投递,不等待结果;Bridge.push_wait_response() 会按请求 ID 保存回调。宿主响应的 replyTo 指回原请求,SDK 取出并删除对应回调后执行它,因此一个请求只会完成一次。DataPlugin.stop_when_idle() 使用同一份挂起响应计数,所有已登记的请求完成或取消后,事件循环才会退出。

同步与异步

  • 回调在 Bridge 事件循环中执行,不在 Flutter UI isolate。不要在其中调用阻塞操作;刷新界面时应更新视图模型。
  • 普通 API 的 callback= 必须是同步可调用对象。Bridge 会直接调用它,不会 await 返回值。需要启动异步工作时,在同步回调中显式创建任务:
import asyncio

async def process_data(data):
    await asyncio.sleep(0.01)
    print("data:", data)

def on_data(error=None, **result):
    if error is not None:
        print("读取失败:", error)
        return
    asyncio.create_task(process_data(result.get("data")))

self.serial.read(timeout_ms=100, callback=on_data)

生命周期钩子、事件订阅处理器和命令处理器有各自的 awaitable 调度逻辑,可以使用普通函数或 async def。不要把这些处理器的规则套用到 API 请求回调。

  • self.bridge.push()(及所有 API 底层发送)是线程安全的,可从任意后台线程调用;但回调仍会回到事件循环线程执行。

错误体系

SDK 用两套错误机制区分"宿主拒绝的请求"与"本地协议/状态问题"。

SdkApiError(宿主返回的错误响应)

API 请求被宿主拒绝时,回调的 error= 收到 SdkApiError 子类实例。所有实例带 codemessagedetails 三字段:

异常触发场景
PermissionDeniedError权限不足;required_permission 属性给出缺失权限
UnknownCommandError当前 IDE 不提供该 SDK 命令(通常因插件类型不支持)
InvalidPluginContextError响应因会话不匹配被拒(跨代或跨会话复用过期句柄)
SdkApiError(基类)其他 IDE 返回的错误(如参数错误)
def on_result(error=None, **cb):
    if isinstance(error, PermissionDeniedError):
        print("需要权限:", error.required_permission)
    elif error is not None:
        print("失败:", error.code, error.message)

self.board.read_file("config.json", callback=on_result)

本地异常(SDK 侧直接抛出)

不经过宿主、直接在调用线程抛出的异常:

异常触发场景
ViewProtocolError视图已关闭、快照/补丁超过节点数或字节上限
StaleReferenceError运行时后端重启后,使用已经失效的 runtime 引用(runtime.*
RuntimeUnavailableError当前后端不支持运行时检查(capability unavailable)
PluginContextError宿主注入的插件上下文缺失或非法(启动时)
TransportClosedError传输层已关闭(插件已卸载/运行时重启)

本地异常在请求发送前同步抛出,可用 try/except 直接捕获;宿主错误则以 error= 关键字进入回调。两种路径的边界是:凡是需要宿主回答的,走回调 error=;凡是本地就能判断的,直接抛异常。

documents.symbols() 的修订冲突属于正常业务结果。回调会收到 SymbolResult,其 stale 属性表示请求期间文档已经变化;这一路径不会抛出 StaleRevisionError。收到 stale=True 后,应基于当前文档修订重新请求符号。

API 参考

On this page