Files
MyNote/apps/desktop/src/renderer/features/keymap/keymap-service.ts
T

34 lines
1.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// KeymapService — 快捷键绑定管理 + 冲突检测(FR-K3/K4/K5)
export type Scope = 'global' | 'app' | 'editor';
export interface Binding { id: string; scope: Scope; combo: string; defaultCombo: string; }
export class KeymapService {
private bindings = new Map<string, Binding>();
register(b: Binding) { this.bindings.set(b.id, b); }
setCombo(id: string, combo: string) {
const b = this.bindings.get(id); if (b) this.bindings.set(id, { ...b, combo });
}
resetAll() { for (const [id, b] of this.bindings) this.bindings.set(id, { ...b, combo: b.defaultCombo }); }
getAll(): Binding[] { return [...this.bindings.values()]; }
// 冲突检测:同一 combo 绑定到多个 action(不同 id)即冲突
conflicts(): Record<string, string[]> {
const byCombo = new Map<string, string[]>();
for (const b of this.bindings.values()) {
const arr = byCombo.get(b.combo) ?? []; arr.push(b.id); byCombo.set(b.combo, arr);
}
const out: Record<string, string[]> = {};
for (const [combo, ids] of byCombo) if (ids.length > 1) out[combo] = ids;
return out;
}
conflictCount(): number { return Object.keys(this.conflicts()).length; }
// 作用域裁决:给定当前是否编辑器聚焦,返回某 combo 应触发哪个 binding(编辑器聚焦时 global 让位规则按需)
resolve(combo: string, editorFocused: boolean): Binding | null {
const matches = [...this.bindings.values()].filter(b => b.combo === combo);
if (matches.length === 0) return null;
// 优先 editor(编辑器聚焦时),再 app,再 global
if (editorFocused) { const e = matches.find(m => m.scope === 'editor'); if (e) return e; }
return matches.find(m => m.scope === 'global') ?? matches[0];
}
}