graphif / create-keybind
Install for your project team
Run this command in your project directory to install the skill for your entire team:
mkdir -p .claude/skills/create-keybind && curl -L -o skill.zip "https://fastmcp.me/Skills/Download/3766" && unzip -o skill.zip -d .claude/skills/create-keybind && rm skill.zip
Project Skills
This skill will be saved in .claude/skills/create-keybind/ and checked into git. All team members will have access to it automatically.
Important: Please verify the skill by reviewing its instructions before using it.
指导如何在 Project Graph 项目中创建新的快捷键。当用户需要添加新的快捷键、修改快捷键绑定或需要了解快捷键系统的实现方式时使用此技能。
0 views
0 installs
Skill Content
---
name: create-keybind
description: 指导如何在 Project Graph 项目中创建新的快捷键。当用户需要添加新的快捷键、修改快捷键绑定或需要了解快捷键系统的实现方式时使用此技能。
---
# 创建新的快捷键功能
本技能指导如何在 Project Graph 项目中创建新的快捷键。
## 创建快捷键的步骤
创建新快捷键需要完成以下 4 个步骤:
### 1. 在 shortcutKeysRegister.tsx 中注册快捷键
在 `app/src/core/service/controlService/shortcutKeysEngine/shortcutKeysRegister.tsx` 文件的 `allKeyBinds` 数组中添加新的快捷键定义。
**快捷键定义结构:**
```typescript
{
id: "uniqueKeybindId", // 唯一标识符,使用驼峰命名
defaultKey: "A-S-m", // 默认快捷键组合
onPress: (project?: Project) => void, // 按下时的回调函数
onRelease?: (project?: Project) => void, // 松开时的回调函数(可选)
isGlobal?: boolean, // 是否为全局快捷键(可选,默认 false)
isUI?: boolean, // 是否为 UI 级别快捷键(可选,默认 false)
defaultEnabled?: boolean, // 默认是否启用(可选,默认 true)
}
```
**快捷键键位格式:**
- `C-` = Ctrl (Windows/Linux) 或 Command (macOS)
- `A-` = Alt (Windows/Linux) 或 Option (macOS)
- `S-` = Shift
- `M-` = Meta (macOS 上等同于 Command)
- `F11`, `F12` 等 = 功能键
- `arrowup`, `arrowdown`, `arrowleft`, `arrowright` = 方向键
- `home`, `end`, `pageup`, `pagedown` = 导航键
- `space`, `enter`, `escape` = 特殊键
- 普通字母直接写,如 `m`, `t`, `k` 等
- 多个按键用空格分隔,如 `"t t t"` 表示连续按三次 t
**注意:** Mac 系统会自动将 `C-` 和 `M-` 互换,所以不需要手动处理平台差异。
**示例:**
```typescript
{
id: "setWindowToMiniSize",
defaultKey: "A-S-m", // Alt+Shift+M
onPress: async () => {
const window = getCurrentWindow();
// 执行操作
await window.setSize(new LogicalSize(width, height));
},
isUI: true, // UI 级别快捷键,不需要项目上下文
},
```
**快捷键类型说明:**
- **项目级快捷键(默认)**:需要项目上下文,`onPress` 会接收 `project` 参数
- **UI 级别快捷键(`isUI: true`)**:不需要项目上下文,可以在没有打开项目时使用
- **全局快捷键(`isGlobal: true`)**:使用 Tauri 全局快捷键系统,即使应用不在焦点也能触发
**使用 Tauri API 时的类型处理:**
如果快捷键需要使用 Tauri 窗口 API(如 `setSize`),需要导入正确的类型:
```typescript
import { getCurrentWindow } from "@tauri-apps/api/window";
import { LogicalSize } from "@tauri-apps/api/dpi"; // 或 PhysicalSize
// 使用 LogicalSize(推荐,会自动处理 DPI 缩放)
await window.setSize(new LogicalSize(width, height));
// 或使用 PhysicalSize(物理像素)
await window.setSize(new PhysicalSize(width, height));
```
### 2. 将快捷键添加到分组中
在 `app/src/sub/SettingsWindow/keybinds.tsx` 文件的 `shortcutKeysGroups` 数组中,将新快捷键的 `id` 添加到相应的分组数组中。
**分组结构:**
```typescript
export const shortcutKeysGroups: ShortcutKeysGroup[] = [
{
title: "basic", // 分组标识符(对应翻译文件中的 key)
icon: <Keyboard />, // 分组图标
keys: [ // 该分组包含的快捷键 ID 列表
"saveFile",
"openFile",
"undo",
"redo",
// ...
],
},
{
title: "ui", // UI 控制分组
icon: <AppWindow />,
keys: [
"closeAllSubWindows",
"toggleFullscreen",
"setWindowToMiniSize", // 添加新快捷键
// ...
],
},
// ... 其他分组
];
```
**可用分组:**
- `basic` - 基础快捷键(撤销、重做、保存、打开等)
- `camera` - 摄像机控制(移动、缩放、重置视野等)
- `app` - 应用控制(切换项目、切换模式等)
- `ui` - UI 控制(关闭窗口、全屏、窗口大小等)
- `draw` - 涂鸦相关
- `select` - 切换选择
- `moveEntity` - 移动实体
- `generateTextNodeInTree` - 生长节点
- `generateTextNodeRoundedSelectedNode` - 在选中节点周围生成节点
- `aboutTextNode` - 关于文本节点(分割、合并、创建等)
- `section` - Section 框相关
- `edge` - 连线相关
- `color` - 颜色相关
- `node` - 节点相关
**分组选择指南:**
- **UI 控制(`ui`)**:窗口管理、界面切换、全屏、窗口大小等
- **基础快捷键(`basic`)**:文件操作、编辑操作(撤销、重做、复制、粘贴等)
- **摄像机控制(`camera`)**:视野移动、缩放、重置等
- **应用控制(`app`)**:项目切换、模式切换等
- **文本节点相关(`aboutTextNode`)**:节点创建、分割、合并、编辑等
- **其他**:根据功能特性选择最合适的分组
**注意:** 如果快捷键不属于任何现有分组,可以:
1. 添加到最接近的现有分组
2. 创建新的分组(需要同时更新翻译文件)
### 3. 添加翻译文本
在所有语言文件中添加翻译:
- `app/src/locales/zh_CN.yml` - 简体中文
- `app/src/locales/zh_TW.yml` - 繁体中文
- `app/src/locales/en.yml` - 英文
- `app/src/locales/zh_TWC.yml` - 繁体中文(台湾)
- `app/src/locales/id.yml` - 印度尼西亚语
**翻译结构:**
在 `keyBinds` 部分添加:
```yaml
keyBinds:
keybindId:
title: "快捷键标题"
description: |
快捷键的详细描述
可以多行
说明快捷键的功能和使用场景
```
**示例:**
```yaml
keyBinds:
setWindowToMiniSize:
title: 设置窗口为迷你大小
description: |
将窗口大小设置为设置中配置的迷你窗口宽度和高度。
```
**翻译文件位置:**
- 简体中文:`app/src/locales/zh_CN.yml`
- 繁体中文:`app/src/locales/zh_TW.yml`
- 繁体中文(台湾):`app/src/locales/zh_TWC.yml`
- 英文:`app/src/locales/en.yml`
- 印度尼西亚语:`app/src/locales/id.yml`
**注意:**
- 翻译键名(`keybindId`)必须与快捷键定义中的 `id` 完全一致
- 所有语言文件都需要添加翻译,否则会显示默认值或键名
### 4. 更新分组翻译(如果需要创建新分组)
如果创建了新的快捷键分组,需要在所有语言文件的 `keyBindsGroup` 部分添加分组翻译:
```yaml
keyBindsGroup:
newGroupName:
title: "新分组标题"
description: |
分组的详细描述
说明该分组包含哪些类型的快捷键
```
**示例:**
```yaml
keyBindsGroup:
ui:
title: UI控制
description: |
用于控制UI的一些功能
```
## 快捷键类型详解
### 项目级快捷键(默认)
项目级快捷键需要项目上下文,`onPress` 函数会接收 `project` 参数:
```typescript
{
id: "myKeybind",
defaultKey: "C-k",
onPress: (project) => {
if (!project) {
toast.warning("请先打开工程文件");
return;
}
// 使用 project 进行操作
project.stageManager.doSomething();
},
}
```
### UI 级别快捷键
UI 级别快捷键不需要项目上下文,可以在没有打开项目时使用:
```typescript
{
id: "myUIKeybind",
defaultKey: "A-S-m",
onPress: async () => {
// 不需要 project 参数
const window = getCurrentWindow();
await window.setSize(new LogicalSize(300, 300));
},
isUI: true, // 标记为 UI 级别
}
```
### 全局快捷键
全局快捷键使用 Tauri 全局快捷键系统,即使应用不在焦点也能触发:
```typescript
{
id: "myGlobalKeybind",
defaultKey: "CommandOrControl+Shift+G",
onPress: () => {
// 全局快捷键逻辑
},
isGlobal: true, // 标记为全局快捷键
}
```
**注意:** 全局快捷键的键位格式与普通快捷键不同,使用 `CommandOrControl+Shift+G` 格式。
## 访问快捷键配置
在代码中访问快捷键配置:
```typescript
import { KeyBindsUI } from "@/core/service/controlService/shortcutKeysEngine/KeyBindsUI";
// 获取快捷键配置
const config = await KeyBindsUI.get("keybindId");
// 修改快捷键
await KeyBindsUI.changeOneUIKeyBind("keybindId", "new-key-combination");
// 重置所有快捷键
await KeyBindsUI.resetAllKeyBinds();
```
## 注意事项
1. **快捷键 ID 命名规范:** 使用驼峰命名法(camelCase),如 `setWindowToMiniSize`
2. **唯一性:** 快捷键 ID 必须唯一,不能与现有快捷键重复
3. **默认键位:** 选择不冲突的默认键位组合
4. **类型安全:** TypeScript 会自动推断类型,确保类型一致性
5. **翻译键名:** 翻译文件中的键名必须与快捷键的 `id` 完全一致
6. **分组必须:** 所有快捷键都必须添加到 `shortcutKeysGroups` 中的相应分组,否则不会在设置页面中显示
7. **分组选择:** 根据快捷键的功能特性选择合适的分组,保持设置页面的逻辑清晰
8. **Tauri API 类型:** 使用窗口 API 时,需要使用 `LogicalSize` 或 `PhysicalSize` 类型,不能直接使用普通对象
9. **Mac 兼容性:** Mac 系统会自动将 `C-` 和 `M-` 互换,无需手动处理
10. **UI vs 项目级:** 根据快捷键是否需要项目上下文选择合适的类型
## 完整示例
假设要添加一个"设置窗口为迷你大小"的快捷键:
**1. shortcutKeysRegister.tsx - 注册快捷键:**
```typescript
import { getCurrentWindow } from "@tauri-apps/api/window";
import { LogicalSize } from "@tauri-apps/api/dpi";
import { Settings } from "@/core/service/Settings";
export const allKeyBinds: KeyBindItem[] = [
// ... 其他快捷键
{
id: "setWindowToMiniSize",
defaultKey: "A-S-m",
onPress: async () => {
const window = getCurrentWindow();
// 如果当前是最大化状态,先取消最大化
if (await window.isMaximized()) {
await window.unmaximize();
store.set(isWindowMaxsizedAtom, false);
}
// 如果当前是全屏状态,先退出全屏
if (await window.isFullscreen()) {
await window.setFullscreen(false);
}
// 设置窗口大小为设置中的迷你窗口大小
const width = Settings.windowCollapsingWidth;
const height = Settings.windowCollapsingHeight;
await window.setSize(new LogicalSize(width, height));
},
isUI: true,
},
// ... 其他快捷键
];
```
**2. keybinds.tsx - 添加到分组:**
```typescript
export const shortcutKeysGroups: ShortcutKeysGroup[] = [
// ... 其他分组
{
title: "ui",
icon: <AppWindow />,
keys: [
"closeAllSubWindows",
"toggleFullscreen",
"setWindowToMiniSize", // 添加到 UI 控制分组
// ...
],
},
// ... 其他分组
];
```
**3. zh_CN.yml - 添加翻译:**
```yaml
keyBinds:
setWindowToMiniSize:
title: 设置窗口为迷你大小
description: |
将窗口大小设置为设置中配置的迷你窗口宽度和高度。
```
**4. 其他语言文件也需要添加相应翻译**
## 快捷键键位格式参考
**修饰键:**
- `C-` = Ctrl/Command
- `A-` = Alt/Option
- `S-` = Shift
- `M-` = Meta (macOS)
**特殊键:**
- `F1` - `F12` = 功能键
- `arrowup`, `arrowdown`, `arrowleft`, `arrowright` = 方向键
- `home`, `end`, `pageup`, `pagedown` = 导航键
- `space`, `enter`, `escape`, `tab`, `backspace`, `delete` = 特殊键
**组合示例:**
- `"C-s"` = Ctrl+S
- `"A-S-m"` = Alt+Shift+M
- `"C-A-S-t"` = Ctrl+Alt+Shift+T
- `"F11"` = F11
- `"C-F11"` = Ctrl+F11
- `"t t t"` = 连续按三次 T
- `"arrowup"` = 上方向键
- `"S-arrowup"` = Shift+上方向键
## 快捷键设置页面
快捷键添加到分组后,会在设置页面的"快捷键绑定"标签页中自动显示:
1. 用户可以在设置页面查看所有快捷键
2. 用户可以自定义快捷键键位
3. 用户可以启用/禁用快捷键
4. 用户可以重置快捷键为默认值
快捷键会自动保存到 `keybinds2.json` 文件中,并在应用重启后恢复。