🎨 binding keymap and extension

This commit is contained in:
2025-06-25 21:09:21 +08:00
parent 650884cb85
commit 69957a16cf
9 changed files with 318 additions and 257 deletions

View File

@@ -1,20 +1,55 @@
import { Extension } from '@codemirror/state'
import { useKeybindingStore } from '@/stores/keybindingStore'
import { useExtensionStore } from '@/stores/extensionStore'
import { KeymapManager } from './keymapManager'
import { ExtensionID } from '@/../bindings/voidraft/internal/models/models'
/**
* 异步创建快捷键扩展
* 确保快捷键配置已加载
* 确保快捷键配置和扩展配置已加载
*/
export const createDynamicKeymapExtension = async (): Promise<Extension> => {
const keybindingStore = useKeybindingStore()
const extensionStore = useExtensionStore()
// 确保快捷键配置已加载
if (keybindingStore.keyBindings.length === 0) {
await keybindingStore.loadKeyBindings()
}
return KeymapManager.createKeymapExtension(keybindingStore.enabledKeyBindings)
// 确保扩展配置已加载
if (extensionStore.extensions.length === 0) {
await extensionStore.loadExtensions()
}
// 获取启用的扩展ID列表
const enabledExtensionIds = extensionStore.enabledExtensions.map(ext => ext.id)
return KeymapManager.createKeymapExtension(keybindingStore.keyBindings, enabledExtensionIds)
}
/**
* 更新快捷键映射
* @param view 编辑器视图
*/
export const updateKeymapExtension = (view: any): void => {
const keybindingStore = useKeybindingStore()
const extensionStore = useExtensionStore()
// 获取启用的扩展ID列表
const enabledExtensionIds = extensionStore.enabledExtensions.map(ext => ext.id)
KeymapManager.updateKeymap(view, keybindingStore.keyBindings, enabledExtensionIds)
}
/**
* 获取指定扩展的快捷键
* @param extensionId 扩展ID
* @returns 该扩展的快捷键列表
*/
export const getExtensionKeyBindings = (extensionId: ExtensionID) => {
const keybindingStore = useKeybindingStore()
return keybindingStore.getKeyBindingsByExtension(extensionId)
}
// 导出相关模块

View File

@@ -1,6 +1,6 @@
import {keymap} from '@codemirror/view'
import {Extension} from '@codemirror/state'
import {KeyBinding as KeyBindingConfig} from '@/../bindings/voidraft/internal/models/models'
import {Extension, Compartment} from '@codemirror/state'
import {KeyBinding as KeyBindingConfig, ExtensionID} from '@/../bindings/voidraft/internal/models/models'
import {KeyBinding, KeymapResult} from './types'
import {getCommandHandler, isCommandRegistered} from './commandRegistry'
@@ -9,12 +9,15 @@ import {getCommandHandler, isCommandRegistered} from './commandRegistry'
* 负责将后端配置转换为CodeMirror快捷键扩展
*/
export class KeymapManager {
private static compartment = new Compartment()
/**
* 将后端快捷键配置转换为CodeMirror快捷键绑定
* @param keyBindings 后端快捷键配置列表
* @param enabledExtensions 启用的扩展ID列表如果不提供则使用所有启用的快捷键
* @returns 转换结果
*/
static convertToKeyBindings(keyBindings: KeyBindingConfig[]): KeymapResult {
static convertToKeyBindings(keyBindings: KeyBindingConfig[], enabledExtensions?: ExtensionID[]): KeymapResult {
const result: KeyBinding[] = []
for (const binding of keyBindings) {
@@ -23,6 +26,11 @@ export class KeymapManager {
continue
}
// 如果提供了扩展列表,则只处理启用扩展的快捷键
if (enabledExtensions && !enabledExtensions.includes(binding.extension)) {
continue
}
// 检查命令是否已注册
if (!isCommandRegistered(binding.command)) {
continue
@@ -50,13 +58,47 @@ export class KeymapManager {
/**
* 创建CodeMirror快捷键扩展
* @param keyBindings 后端快捷键配置列表
* @param enabledExtensions 启用的扩展ID列表
* @returns CodeMirror扩展
*/
static createKeymapExtension(keyBindings: KeyBindingConfig[]): Extension {
static createKeymapExtension(keyBindings: KeyBindingConfig[], enabledExtensions?: ExtensionID[]): Extension {
const {keyBindings: cmKeyBindings} =
this.convertToKeyBindings(keyBindings)
this.convertToKeyBindings(keyBindings, enabledExtensions)
return keymap.of(cmKeyBindings)
return this.compartment.of(keymap.of(cmKeyBindings))
}
/**
* 动态更新快捷键扩展
* @param view 编辑器视图
* @param keyBindings 后端快捷键配置列表
* @param enabledExtensions 启用的扩展ID列表
*/
static updateKeymap(view: any, keyBindings: KeyBindingConfig[], enabledExtensions: ExtensionID[]): void {
const {keyBindings: cmKeyBindings} =
this.convertToKeyBindings(keyBindings, enabledExtensions)
view.dispatch({
effects: this.compartment.reconfigure(keymap.of(cmKeyBindings))
})
}
/**
* 按扩展分组快捷键
* @param keyBindings 快捷键配置列表
* @returns 按扩展分组的快捷键映射
*/
static groupByExtension(keyBindings: KeyBindingConfig[]): Map<ExtensionID, KeyBindingConfig[]> {
const groups = new Map<ExtensionID, KeyBindingConfig[]>()
for (const binding of keyBindings) {
if (!groups.has(binding.extension)) {
groups.set(binding.extension, [])
}
groups.get(binding.extension)!.push(binding)
}
return groups
}
/**

View File

@@ -3,23 +3,33 @@ import { useI18n } from 'vue-i18n';
import { onMounted, computed } from 'vue';
import SettingSection from '../components/SettingSection.vue';
import { useKeybindingStore } from '@/stores/keybindingStore';
import { useExtensionStore } from '@/stores/extensionStore';
import { useSystemStore } from '@/stores/systemStore';
import { getCommandDescription } from '@/views/editor/keymap/commandRegistry';
import {KeyBindingCommand} from "@/../bindings/voidraft/internal/models";
const { t } = useI18n();
const keybindingStore = useKeybindingStore();
const extensionStore = useExtensionStore();
const systemStore = useSystemStore();
// 加载数据
onMounted(async () => {
await keybindingStore.loadKeyBindings();
await extensionStore.loadExtensions();
});
// 从store中获取快捷键数据并转换为显示格式
const keyBindings = computed(() => {
// 只显示启用扩展的快捷键
const enabledExtensionIds = new Set(extensionStore.enabledExtensionIds);
return keybindingStore.keyBindings
.filter(kb => kb.enabled)
.filter(kb => kb.enabled && enabledExtensionIds.has(kb.extension))
.map(kb => ({
id: kb.command,
keys: parseKeyBinding(kb.key, kb.command),
category: kb.category,
category: kb.extension,
description: getCommandDescription(kb.command) || kb.command
}));
});