[[contributes.commands]]
都会成为一个 IDE 动作,动作 id 固定为 plugin.<plugin-id>.<command-id>。它和内置动作一样,
会出现在 查找操作(⌘⇧A / Ctrl+Shift+A)和 随处搜索 中,可以在 设置 › 按键映射
里绑定快捷键,也可以放进菜单、工具栏和状态栏。
插件启用后,声明的命令立即可用,早于任何插件代码加载。代码在其中某个命令第一次执行时才实例化
(每个命令都隐含 on-command:<id> 激活事件),所以命令再多也不会拖慢启动。激活和空闲回收见
生命周期。
声明命令
when 子句
when 与内置动作使用同一套表达式:key、key == value、key != value、!、&&、||
以及括号。常用的键:
editorFocus:焦点在文本编辑器中。editorLangId == sql:当前编辑器的语言 id。workspaceContains:pom.xml:打开的项目包含这个精确路径(相对项目根目录,不支持通配符)。 在工作区中,任一项目包含即为真;文件变化时会重新计算。不认识这个键的 IDE 视其为假。plugin.<plugin-id>.<key>:插件自己用host::set_context设置的键(见下)。
执行命令
实现Plugin::run_command
(WIT 导出 commands.run)。ctx 代表发起调用的窗口:ctx.project()、ctx.editor()
和 ctx.selected_paths()。
[capabilities] 中声明 editor.read 和 editor.write
(见 权限)。完整示例可参考
String Tools,它有 26 个命令。
返回值的含义:
Ok(Some(text))会展示给用户;Ok(None)什么也不显示。- 返回错误时显示 “
<title>failed: …”,插件继续运行。"msg".into()即Error::Failed。 Error::Cancelled(用户放弃)和Error::Denied(缺少权限)不算插件出错。
参数与选中的文件
arg是可选字符串。从查找操作或快捷键执行时为None;其他功能带参数执行plugin.<plugin-id>.<command-id>,或通知按钮、代码透镜、行号槽动作传参时才有值。ctx.selected_paths()列出项目视图或编辑器标签页菜单所针对的文件和文件夹(此时参数是其中第一个), 其他情况下为空。- 从
problems.context和searchResults.context菜单执行时,selected_paths()是该问题或匹配项所在文件,arg是 JSON{"path": "…", "line": 0, "column": 0}(行从 0 开始,列为 UTF-16 单位)。
限制
每次命令调用有 5 秒墙钟时间和 CPU 燃料预算。较长的工作请用host::begin_task(title, cancellable)
开启任务:任务打开期间调用最多可运行 60 秒,每次 report 或 is_cancelled 都会续期。
对话框(host::pick、input、confirm 等)等待用户期间不计入预算。
快捷键
- 修饰键:
Meta、Ctrl、Alt、Shift。按键:A–Z、0–9、F1–F24、Enter、Escape、Tab、Space、Backspace、Delete、Insert、Home、End、PageUp、PageDown、Up、Down、Left、Right、Minus、Equal、Comma、Period、Slash、Semicolon、Quote。 - 组合键序列(chord)是用空格分隔的两次按键:
Meta+K Meta+C。 - 除功能键外,每次按键都必须包含
Ctrl、Alt或Meta,单独的字母键留给输入。 - 没有
mac时,macOS 原样使用key,Ctrl仍然是Ctrl。想用⌘就写mac并使用Meta。 - 插件快捷键只是默认值,优先级低于 IDE:按键映射预设或用户已经占用该按键、或该动作已有绑定时, 插件的快捷键会被丢弃。用户可以在 设置 › 按键映射 中重新绑定。
菜单
使用 1.0 之后加入的菜单,需要在
engines.openidea 中至少声明对应的 API 版本。每个条目都必须指向插件声明过的命令。
菜单的 when 与命令自身的 when 同时生效。
工具栏图标。 editor.title、mainToolbar 和 commit.message 的条目会显示图标:优先使用命令的 icon,
否则使用插件清单中的 icon。
子菜单(API 1.3)。在右键菜单(*.context)中,submenu 相同的条目会按声明顺序归到同一个子菜单下。
只有一个可见条目的子菜单会直接显示为普通条目。子菜单标题通过插件的文本目录翻译。
viewItem.context 需要 view,即插件自己声明、由代码渲染为 tree、list
或表格的视图 id(不能是网页视图)。每个命令都会收到条目的 key 作为参数。只有菜单的 when 能使用
viewItem(条目 key)和 viewItemKind(key 中第一个 : 之前的部分,例如 pod:default/nginx 对应 pod)。
表格行的 key 是十进制行号。详见 视图与装饰。
状态栏项
host::set_status_item(id, &StatusItem { text, tooltip, command })在所有窗口中显示或更新状态栏项 (每个插件最多 8 个;插件空闲时仍保留);remove_status_item(id)移除。host::set_window_status_item(id, item)(API 1.4)只在发起调用的窗口中覆盖它;remove_window_status_item(id)恢复为全局项。只能在窗口的命令或事件中调用。
在代码中设置上下文键
host::set_context(key, value) 设置 plugin.<plugin-id>.<key>,供 when 子句使用
(true、数字或最多 1024 字节的文本)。键名为 1–64 个 A-Za-z0-9_- 字符,每个插件最多 100 个。
在命令或事件中设置的键只作用于该窗口;在此之外设置的键作用于所有窗口,窗口级的值优先。
这些键在窗口重新加载和空闲回收后仍保留,插件停止时清除。
带按钮的通知
host::notify(level, title, body) 在命令或事件来源的窗口中显示通知气泡(没有来源窗口时显示在所有窗口)。
host::notify_with_actions 可以加最多三个按钮,每个按钮执行插件声明的一个命令:
Project::notify(level, title, body, actions):只在该项目的窗口中显示(项目在多个窗口打开时,
选最近获得焦点的那个),定时任务或后台工作中也能用。项目已关闭时返回 Error::NotFound。
按钮标题最多 256 字节,参数最多 64 KiB;引用未声明的命令会导致整条通知被拒绝。
执行其他命令
host::execute_command(id, arg)(API 1.4,WIT command-runner.execute)在发起调用的窗口中执行稳定的 IDE
动作 id 或 plugin.<plugin-id>.<command-id>。执行插件自己的命令无需权限;执行 IDE 动作和其他插件的命令需要
高风险权限 ide.commands。IDE 动作返回 None,插件命令返回其结果。最多嵌套 8 层,且只能在窗口的命令或事件中调用。
事件
命令是一种入口,工作台事件是另一种。在activate 中用 host::subscribe(EventKind::FileSaved) 订阅,
或声明 activation = ["on-event:file-saved"] 让第一个事件唤醒插件,然后在
Plugin::handle_events(events, ctx) 中批量处理(WIT events.wit,导出 event-handler)。
事件按窗口分批送达,旧的在前。空闲的插件会先攒 2 秒再被唤醒。
host::subscribe_paths(kind, &["config/*.yaml"])
(API 1.3)可以按项目相对通配符过滤 file-opened、file-saved 和 files-changed。比 SDK 新的事件类型以
Event::Other { kind, data } 送达;这个枚举标记了 #[non_exhaustive],匹配时要加 _ 分支。
可运行的示例见 Key Promoter
(action-performed)和 Git Toolbox
(on-schedule、vcs-changed)。
提交
插件可以参与用户正在准备的提交(API 1.3,commit.wit):
- 提交信息上方的按钮: 一条
commit.message菜单项。 - 读取草稿:
host::pending_commit()(vcs.read)返回提交此刻会包含的内容:每个文件的仓库、路径、状态, 以及只包含已勾选改动的git diff(总计 1 MiB,超出则标记truncated),外加提交信息、是否修订(Amend)和revision。会先保存这些文件未保存的编辑器内容,但不会暂存任何东西。 - 写入提交信息:
host::set_commit_message(revision, text)(vcs.write)只在草稿仍处于revision时替换信息,否则返回Error::Stale,保留用户输入的文字。
[[contributes.commitChecks]](id、title)都会列在 提交选项 中,默认开启。
用户提交时,在 IDE 自己的检查之后,IDE 调用 commit-checker 导出。用
register_plugin!(MyPlugin, commit_checks) 注册,并实现 openidea_plugin::commit::CommitChecks:
vcs.read 时,也会作为问题报告。