diff --git a/frontend/bindings/voidraft/internal/models/models.ts b/frontend/bindings/voidraft/internal/models/models.ts index 4aa14dc..2d76900 100644 --- a/frontend/bindings/voidraft/internal/models/models.ts +++ b/frontend/bindings/voidraft/internal/models/models.ts @@ -461,6 +461,11 @@ export class GeneralConfig { */ "enableTabs": boolean; + /** + * 是否启用内存监视器 + */ + "enableMemoryMonitor": boolean; + /** Creates a new GeneralConfig instance. */ constructor($$source: Partial = {}) { if (!("alwaysOnTop" in $$source)) { @@ -490,6 +495,9 @@ export class GeneralConfig { if (!("enableTabs" in $$source)) { this["enableTabs"] = false; } + if (!("enableMemoryMonitor" in $$source)) { + this["enableMemoryMonitor"] = false; + } Object.assign(this, $$source); } diff --git a/frontend/bindings/voidraft/internal/services/keybindingservice.ts b/frontend/bindings/voidraft/internal/services/keybindingservice.ts index c73ee8c..89b3e90 100644 --- a/frontend/bindings/voidraft/internal/services/keybindingservice.ts +++ b/frontend/bindings/voidraft/internal/services/keybindingservice.ts @@ -89,13 +89,21 @@ export function UpdateKeyBindingEnabled(id: number, enabled: boolean): Promise & { cancel(): void } { let $resultPromise = $Call.ByID(3432755175, id, key) as any; return $resultPromise; } +/** + * UpdateKeyBindingPreventDefault 更新快捷键 PreventDefault 状态 + */ +export function UpdateKeyBindingPreventDefault(id: number, preventDefault: boolean): Promise & { cancel(): void } { + let $resultPromise = $Call.ByID(202386744, id, preventDefault) as any; + return $resultPromise; +} + // Private type creation functions const $$createType0 = models$0.KeyBinding.createFrom; const $$createType1 = $Create.Array($$createType0); diff --git a/frontend/components.d.ts b/frontend/components.d.ts index 09cefb3..8b2a0b4 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -11,6 +11,8 @@ export {} /* prettier-ignore */ declare module 'vue' { export interface GlobalComponents { + AccordionContainer: typeof import('./src/components/accordion/AccordionContainer.vue')['default'] + AccordionItem: typeof import('./src/components/accordion/AccordionItem.vue')['default'] BlockLanguageSelector: typeof import('./src/components/toolbar/BlockLanguageSelector.vue')['default'] DocumentSelector: typeof import('./src/components/toolbar/DocumentSelector.vue')['default'] LinuxTitleBar: typeof import('./src/components/titlebar/LinuxTitleBar.vue')['default'] diff --git a/frontend/public/images/blockImage.svg b/frontend/public/images/blockImage.svg new file mode 100644 index 0000000..0e7675a --- /dev/null +++ b/frontend/public/images/blockImage.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/images/colorSelector.svg b/frontend/public/images/colorSelector.svg new file mode 100644 index 0000000..311ce13 --- /dev/null +++ b/frontend/public/images/colorSelector.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/images/contextMenu.svg b/frontend/public/images/contextMenu.svg new file mode 100644 index 0000000..f099e52 --- /dev/null +++ b/frontend/public/images/contextMenu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/images/fold.svg b/frontend/public/images/fold.svg new file mode 100644 index 0000000..eb764f8 --- /dev/null +++ b/frontend/public/images/fold.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/images/highlightTrailingWhitespace.svg b/frontend/public/images/highlightTrailingWhitespace.svg new file mode 100644 index 0000000..25c90d8 --- /dev/null +++ b/frontend/public/images/highlightTrailingWhitespace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/images/highlightWhitespace.svg b/frontend/public/images/highlightWhitespace.svg new file mode 100644 index 0000000..c3229c3 --- /dev/null +++ b/frontend/public/images/highlightWhitespace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/images/httpClient.svg b/frontend/public/images/httpClient.svg new file mode 100644 index 0000000..641302b --- /dev/null +++ b/frontend/public/images/httpClient.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/images/hyperlink.svg b/frontend/public/images/hyperlink.svg new file mode 100644 index 0000000..e84e57b --- /dev/null +++ b/frontend/public/images/hyperlink.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/images/lineNumbers.svg b/frontend/public/images/lineNumbers.svg new file mode 100644 index 0000000..e473bbb --- /dev/null +++ b/frontend/public/images/lineNumbers.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/images/markdown.svg b/frontend/public/images/markdown.svg new file mode 100644 index 0000000..fc2e331 --- /dev/null +++ b/frontend/public/images/markdown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/images/minimap.svg b/frontend/public/images/minimap.svg new file mode 100644 index 0000000..4fd7e4c --- /dev/null +++ b/frontend/public/images/minimap.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/images/rainbowBrackets.svg b/frontend/public/images/rainbowBrackets.svg new file mode 100644 index 0000000..040de39 --- /dev/null +++ b/frontend/public/images/rainbowBrackets.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/images/search.svg b/frontend/public/images/search.svg new file mode 100644 index 0000000..c58e8b2 --- /dev/null +++ b/frontend/public/images/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/images/translator.svg b/frontend/public/images/translator.svg new file mode 100644 index 0000000..f728a3a --- /dev/null +++ b/frontend/public/images/translator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/assets/images/translator.svg b/frontend/src/assets/images/translator.svg new file mode 100644 index 0000000..2c84e25 --- /dev/null +++ b/frontend/src/assets/images/translator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/common/constant/config.ts b/frontend/src/common/constant/config.ts index 6d9aba3..67ef212 100644 --- a/frontend/src/common/constant/config.ts +++ b/frontend/src/common/constant/config.ts @@ -24,6 +24,7 @@ export const CONFIG_KEY_MAP = { enableWindowSnap: 'general.enableWindowSnap', enableLoadingAnimation: 'general.enableLoadingAnimation', enableTabs: 'general.enableTabs', + enableMemoryMonitor: 'general.enableMemoryMonitor', // editing fontSize: 'editing.fontSize', fontFamily: 'editing.fontFamily', @@ -88,6 +89,7 @@ export const DEFAULT_CONFIG: AppConfig = { enableWindowSnap: true, enableLoadingAnimation: true, enableTabs: false, + enableMemoryMonitor: true, }, editing: { fontSize: CONFIG_LIMITS.fontSize.default, diff --git a/frontend/src/components/accordion/AccordionContainer.vue b/frontend/src/components/accordion/AccordionContainer.vue new file mode 100644 index 0000000..24dd01b --- /dev/null +++ b/frontend/src/components/accordion/AccordionContainer.vue @@ -0,0 +1,105 @@ + + + + + + diff --git a/frontend/src/components/accordion/AccordionItem.vue b/frontend/src/components/accordion/AccordionItem.vue new file mode 100644 index 0000000..2903f07 --- /dev/null +++ b/frontend/src/components/accordion/AccordionItem.vue @@ -0,0 +1,187 @@ + + + + + + diff --git a/frontend/src/components/accordion/index.ts b/frontend/src/components/accordion/index.ts new file mode 100644 index 0000000..1664d35 --- /dev/null +++ b/frontend/src/components/accordion/index.ts @@ -0,0 +1,3 @@ +export { default as AccordionContainer } from './AccordionContainer.vue'; +export { default as AccordionItem } from './AccordionItem.vue'; + diff --git a/frontend/src/i18n/locales/en-US.ts b/frontend/src/i18n/locales/en-US.ts index b79feac..5607cc1 100644 --- a/frontend/src/i18n/locales/en-US.ts +++ b/frontend/src/i18n/locales/en-US.ts @@ -1,5 +1,14 @@ export default { locale: 'en-US', + common: { + ok: 'OK', + cancel: 'Cancel', + edit: 'Edit', + delete: 'Delete', + confirm: 'Confirm', + save: 'Save', + reset: 'Reset' + }, titlebar: { minimize: 'Minimize', maximize: 'Maximize', @@ -56,6 +65,19 @@ export default { }, resetToDefault: 'Reset to Default', confirmReset: 'Confirm Reset?', + noKeybinding: 'Not Set', + waitingForKey: 'Waiting...', + clickToSet: 'Click to set keybinding', + editKeybinding: 'Edit keybinding', + config: { + enabled: 'Enabled', + preventDefault: 'Prevent Default', + keybinding: 'Keybinding' + }, + keyPlaceholder: 'Enter key, press Enter to add', + invalidFormat: 'Invalid format', + conflict: 'Conflict: {command}', + maxKeysReached: 'Maximum 4 keys allowed', commands: { showSearch: 'Show search panel', hideSearch: 'Hide search panel', @@ -178,6 +200,7 @@ export default { enableWindowSnap: 'Enable Window Snapping', enableLoadingAnimation: 'Enable Loading Animation', enableTabs: 'Enable Tabs', + enableMemoryMonitor: 'Enable Memory Monitor', startup: 'Startup Settings', startAtLogin: 'Start at Login', dataStorage: 'Data Storage', @@ -223,6 +246,7 @@ export default { categoryEditing: 'Editing Enhancement', categoryUI: 'UI Enhancement', categoryTools: 'Tools', + enabled: 'Enabled', configuration: 'Configuration', resetToDefault: 'Reset to Default Configuration', }, diff --git a/frontend/src/i18n/locales/zh-CN.ts b/frontend/src/i18n/locales/zh-CN.ts index a91e23a..b8fe43f 100644 --- a/frontend/src/i18n/locales/zh-CN.ts +++ b/frontend/src/i18n/locales/zh-CN.ts @@ -1,5 +1,14 @@ export default { locale: 'zh-CN', + common: { + ok: '确定', + cancel: '取消', + edit: '编辑', + delete: '删除', + confirm: '确认', + save: '保存', + reset: '重置' + }, titlebar: { minimize: '最小化', maximize: '最大化', @@ -56,6 +65,19 @@ export default { }, resetToDefault: '重置为默认', confirmReset: '确认重置?', + noKeybinding: '未设置', + waitingForKey: '等待输入...', + clickToSet: '点击设置快捷键', + editKeybinding: '编辑快捷键', + config: { + enabled: '启用', + preventDefault: '阻止默认', + keybinding: '快捷键' + }, + keyPlaceholder: '输入键名, 回车添加', + invalidFormat: '格式错误', + conflict: '冲突: {command}', + maxKeysReached: '最多只能添加4个键', commands: { showSearch: '显示搜索面板', hideSearch: '隐藏搜索面板', @@ -179,6 +201,7 @@ export default { enableWindowSnap: '启用窗口吸附', enableLoadingAnimation: '启用加载动画', enableTabs: '启用标签页', + enableMemoryMonitor: '启用内存监视器', startup: '启动设置', startAtLogin: '开机自启动', dataStorage: '数据存储', @@ -226,6 +249,7 @@ export default { categoryEditing: '编辑增强', categoryUI: '界面增强', categoryTools: '工具扩展', + enabled: '启用', configuration: '配置', resetToDefault: '重置为默认配置', }, diff --git a/frontend/src/stores/configStore.ts b/frontend/src/stores/configStore.ts index 9962061..259ebd3 100644 --- a/frontend/src/stores/configStore.ts +++ b/frontend/src/stores/configStore.ts @@ -233,6 +233,9 @@ export const useConfigStore = defineStore('config', () => { // 标签页配置相关方法 setEnableTabs: (value: boolean) => updateConfig('enableTabs', value), + // 内存监视器配置相关方法 + setEnableMemoryMonitor: (value: boolean) => updateConfig('enableMemoryMonitor', value), + // 快捷键模式配置相关方法 setKeymapMode: (value: any) => updateConfig('keymapMode', value), diff --git a/frontend/src/views/editor/extensions/codeblock/index.ts b/frontend/src/views/editor/extensions/codeblock/index.ts index 97a8b4c..a2e5acb 100644 --- a/frontend/src/views/editor/extensions/codeblock/index.ts +++ b/frontend/src/views/editor/extensions/codeblock/index.ts @@ -39,6 +39,9 @@ export interface CodeBlockOptions { /** 新建块时的默认语言 */ defaultLanguage?: SupportedLanguage; + + /** 分隔符高度(像素) */ + separatorHeight?: number; } /** @@ -86,6 +89,7 @@ export function createCodeBlockExtension(options: CodeBlockOptions = {}): Extens showBackground = true, enableAutoDetection = true, defaultLanguage = 'text', + separatorHeight = 12, } = options; return [ @@ -104,7 +108,8 @@ export function createCodeBlockExtension(options: CodeBlockOptions = {}): Extens // 视觉装饰系统 ...getBlockDecorationExtensions({ - showBackground + showBackground, + separatorHeight }), // 光标保护(防止方向键移动到分隔符上) diff --git a/frontend/src/views/settings/Settings.vue b/frontend/src/views/settings/Settings.vue index ef461c9..640f1a4 100644 --- a/frontend/src/views/settings/Settings.vue +++ b/frontend/src/views/settings/Settings.vue @@ -1,12 +1,17 @@ -
-
-
{{ t('keybindings.headers.shortcut') }}
-
{{ t('keybindings.headers.extension') }}
-
{{ t('keybindings.headers.description') }}
-
- -
+ - -
- - + + +
+ +
+ {{ t('keybindings.config.enabled') }} + +
+ + +
+ {{ t('keybindings.config.preventDefault') }} + +
+ + +
+ {{ t('keybindings.config.keybinding') }} +
+
+ + + + + + + + +
+
+
- -
{{ binding.extension }}
-
{{ binding.description }}
-
-
+ +
@@ -375,167 +448,275 @@ const confirmKeybinding = async () => { } } -.key-bindings-container { +.binding-title { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + gap: 16px; - .key-bindings-header { - display: flex; - padding: 0 0 8px 0; - border-bottom: 1px solid var(--settings-border); - color: var(--text-muted); - font-size: 12px; - font-weight: 500; - } - - .key-binding-row { - display: flex; - padding: 10px 0; - border-bottom: 1px solid var(--settings-border); - align-items: center; - transition: background-color 0.2s ease; - - &:hover { - background-color: var(--settings-hover); - } - } - - .keybinding-col { - width: 150px; - display: flex; - gap: 4px; - padding: 0 10px 0 0; - color: var(--settings-text); - align-items: center; - cursor: pointer; - transition: all 0.2s ease; - - &:hover:not(.editing) .key-badge { - border-color: #4a9eff; - } - - &.editing { - cursor: default; - } - - .key-badge { - background-color: var(--settings-input-bg); - padding: 2px 6px; - border-radius: 3px; - font-size: 11px; - border: 1px solid var(--settings-input-border); - color: var(--settings-text); - transition: border-color 0.2s ease; - white-space: nowrap; - - &.waiting { - border: none; - background-color: transparent; - padding: 0; - color: #4a9eff; - font-style: italic; - animation: colorPulse 1.5s ease-in-out infinite; - } - - &.captured { - background-color: #4a9eff; - color: white; - border-color: #4a9eff; - - &.conflict { - background-color: #dc3545; - border-color: #dc3545; - animation: shake 0.6s ease-in-out; - } - } - } - } - - .btn-mini { - width: 16px; - height: 16px; - min-width: 16px; - border: none; - border-radius: 2px; - cursor: pointer; - font-size: 10px; - transition: opacity 0.2s ease; - display: flex; - align-items: center; - justify-content: center; - padding: 0; - line-height: 1; - margin-left: auto; - - &.btn-confirm { - background-color: #28a745; - color: white; - - &:hover:not(:disabled) { - opacity: 0.85; - } - - &:disabled { - background-color: var(--settings-input-border); - cursor: not-allowed; - opacity: 0.5; - } - } - - &.btn-cancel { - background-color: #dc3545; - color: white; - margin-left: 2px; - - &:hover { - opacity: 0.85; - } - } - } - - .extension-col { - width: 80px; - padding: 0 10px 0 0; - font-size: 13px; - color: var(--settings-text); - text-transform: capitalize; - } - - .description-col { - flex: 1; - font-size: 13px; - color: var(--settings-text); + &.disabled { + opacity: 0.5; } } -@keyframes colorPulse { - 0%, 100% { - color: #4a9eff; +.binding-name { + flex: 1; + display: flex; + flex-direction: column; + gap: 4px; +} + +.binding-description { + font-size: 13px; + font-weight: 500; + color: var(--settings-text); +} + +.binding-extension { + font-size: 11px; + color: var(--text-muted); + text-transform: capitalize; +} + +.binding-keys { + display: flex; + gap: 4px; + align-items: center; +} + +.key-badge { + background-color: var(--settings-input-bg); + padding: 2px 6px; + border-radius: 3px; + font-size: 11px; + border: 1px solid var(--settings-input-border); + color: var(--settings-text); + white-space: nowrap; +} + +.key-badge-empty { + font-size: 11px; + color: var(--text-muted); + font-style: italic; +} + +.binding-config { + display: flex; + flex-direction: column; + gap: 16px; +} + +.config-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; +} + +.config-label { + font-size: 13px; + color: var(--settings-text); + font-weight: 500; +} + +// Switch 开关样式 +.switch { + position: relative; + display: inline-block; + width: 36px; + height: 20px; + flex-shrink: 0; + + input { + opacity: 0; + width: 0; + height: 0; + + &:checked + .slider { + background-color: #4a9eff; + + &:before { + transform: translateX(16px); + } + } + + &:focus + .slider { + box-shadow: 0 0 1px #4a9eff; + } + } +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: var(--settings-input-border); + transition: 0.3s; + border-radius: 20px; + + &:before { + position: absolute; + content: ""; + height: 14px; + width: 14px; + left: 3px; + bottom: 3px; + background-color: white; + transition: 0.3s; + border-radius: 50%; + } +} + +.key-input-wrapper { + flex: 1; + display: flex; + align-items: center; + gap: 8px; +} + +.key-tags { + display: flex; + gap: 6px; + align-items: center; + flex-wrap: wrap; + flex: 1; + min-height: 28px; +} + +.key-tag { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 4px 8px; + height: 28px; + background-color: var(--settings-input-bg); + border: 1px solid var(--settings-input-border); + border-radius: 4px; + font-size: 12px; + font-weight: 500; + color: var(--settings-text); + transition: all 0.2s ease; + box-sizing: border-box; + + &:hover { + border-color: #4a9eff; + + .key-tag-remove { + opacity: 1; + } + } +} + +.key-tag-text { + user-select: none; +} + +.key-tag-remove { + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + width: 16px; + height: 16px; + border: none; + background: none; + color: var(--text-muted); + cursor: pointer; + font-size: 18px; + line-height: 1; + padding: 0; + margin: 0; + opacity: 0.6; + transition: all 0.2s ease; + + &:hover { + color: #e74c3c; opacity: 1; } - 50% { - color: #2080ff; - opacity: 0.6; - } } -@keyframes shake { - 0%, 100% { - transform: translateX(0); - } - 10%, 30%, 50%, 70%, 90% { - transform: translateX(-4px); - } - 20%, 40%, 60%, 80% { - transform: translateX(4px); - } -} - -.coming-soon-placeholder { - padding: 20px; - background-color: var(--settings-card-bg); - border-radius: 6px; +.key-tag-add { + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + flex-shrink: 0; + border: 1px dashed var(--settings-input-border); + border-radius: 4px; + background-color: transparent; color: var(--text-muted); - text-align: center; - font-style: italic; - font-size: 13px; + cursor: pointer; + transition: all 0.2s ease; + box-sizing: border-box; + + &:hover { + border-color: #4a9eff; + background-color: var(--settings-input-bg); + color: #4a9eff; + } } - \ No newline at end of file + +.key-input { + padding: 4px 8px; + height: 28px; + border: 1px solid #4a9eff; + border-radius: 4px; + background-color: var(--settings-input-bg); + color: var(--settings-text); + font-size: 12px; + width: 60px; + outline: none; + box-sizing: border-box; + + &::placeholder { + color: var(--text-muted); + font-size: 11px; + } +} + +.btn-mini { + width: 24px; + height: 24px; + min-width: 24px; + border: none; + border-radius: 3px; + cursor: pointer; + font-size: 12px; + transition: opacity 0.2s ease; + display: flex; + align-items: center; + justify-content: center; + padding: 0; + line-height: 1; + flex-shrink: 0; + + &.btn-confirm { + background-color: #28a745; + color: white; + + &:hover:not(:disabled) { + opacity: 0.85; + } + + &:disabled { + background-color: var(--settings-input-border); + cursor: not-allowed; + opacity: 0.5; + } + } + + &.btn-cancel { + background-color: #dc3545; + color: white; + + &:hover { + opacity: 0.85; + } + } +} + diff --git a/internal/models/config.go b/internal/models/config.go index 42e6852..1f5a2f9 100644 --- a/internal/models/config.go +++ b/internal/models/config.go @@ -79,6 +79,7 @@ type GeneralConfig struct { // 界面设置 EnableLoadingAnimation bool `json:"enableLoadingAnimation"` // 是否启用加载动画 EnableTabs bool `json:"enableTabs"` // 是否启用标签页模式 + EnableMemoryMonitor bool `json:"enableMemoryMonitor"` // 是否启用内存监视器 } // HotkeyCombo 热键组合定义 @@ -188,6 +189,7 @@ func NewDefaultAppConfig() *AppConfig { EnableGlobalHotkey: false, EnableLoadingAnimation: true, // 默认启用加载动画 EnableTabs: false, // 默认不启用标签页模式 + EnableMemoryMonitor: true, // 默认启用内存监视器 GlobalHotkey: HotkeyCombo{ Ctrl: false, Shift: false, diff --git a/internal/models/key_binding.go b/internal/models/key_binding.go index 48f956c..304c450 100644 --- a/internal/models/key_binding.go +++ b/internal/models/key_binding.go @@ -106,7 +106,7 @@ const ( CopyBlockImage KeyBindingName = "copyBlockImage" // 复制块为图片 ) -const defaultExtension = "editor" +const DefaultExtension = "editor" // NewDefaultKeyBindings 创建默认快捷键配置 func NewDefaultKeyBindings() []KeyBinding { @@ -135,7 +135,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockSelectAll, Type: Standard, Key: "Mod-a", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -143,7 +143,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockAddAfterCurrent, Type: Standard, Key: "Mod-Enter", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -151,7 +151,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockAddAfterLast, Type: Standard, Key: "Mod-Shift-Enter", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -159,7 +159,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockAddBeforeCurrent, Type: Standard, Key: "Alt-Enter", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -167,7 +167,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockGotoPrevious, Type: Standard, Key: "Mod-ArrowUp", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -175,7 +175,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockGotoNext, Type: Standard, Key: "Mod-ArrowDown", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -183,7 +183,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockSelectPrevious, Type: Standard, Key: "Mod-Shift-ArrowUp", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -191,7 +191,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockSelectNext, Type: Standard, Key: "Mod-Shift-ArrowDown", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -199,7 +199,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockDelete, Type: Standard, Key: "Mod-Shift-d", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -207,7 +207,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockMoveUp, Type: Standard, Key: "Shift-Mod-ArrowUp", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -215,7 +215,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockMoveDown, Type: Standard, Key: "Shift-Mod-ArrowDown", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -223,7 +223,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockDeleteLine, Type: Standard, Key: "Mod-Shift-k", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -231,7 +231,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockMoveLineUp, Type: Standard, Key: "Alt-ArrowUp", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -239,7 +239,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockMoveLineDown, Type: Standard, Key: "Alt-ArrowDown", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -247,7 +247,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockTransposeChars, Type: Standard, Key: "Mod-t", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -255,7 +255,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockFormat, Type: Standard, Key: "Mod-Shift-f", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -263,7 +263,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockCopy, Type: Standard, Key: "Mod-c", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -271,7 +271,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockCut, Type: Standard, Key: "Mod-x", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -279,7 +279,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockPaste, Type: Standard, Key: "Mod-v", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -335,7 +335,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: HistoryUndo, Type: Standard, Key: "Mod-z", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -344,7 +344,7 @@ func NewDefaultKeyBindings() []KeyBinding { Type: Standard, Key: "Mod-Shift-z", Windows: "Ctrl-y", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -352,7 +352,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: HistoryUndoSelection, Type: Standard, Key: "Mod-u", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -361,7 +361,7 @@ func NewDefaultKeyBindings() []KeyBinding { Type: Standard, Key: "Mod-Shift-u", Windows: "Alt-u", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -373,7 +373,7 @@ func NewDefaultKeyBindings() []KeyBinding { Macos: "Ctrl-ArrowLeft", Windows: "Alt-ArrowLeft", Linux: "Alt-ArrowLeft", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -383,7 +383,7 @@ func NewDefaultKeyBindings() []KeyBinding { Macos: "Ctrl-ArrowRight", Windows: "Alt-ArrowRight", Linux: "Alt-ArrowRight", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -391,7 +391,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectSyntaxLeft, Type: Standard, Key: "Shift-Alt-ArrowLeft", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -399,7 +399,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectSyntaxRight, Type: Standard, Key: "Shift-Alt-ArrowRight", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -407,7 +407,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CopyLineUp, Type: Standard, Key: "Shift-Alt-ArrowUp", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -415,7 +415,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CopyLineDown, Type: Standard, Key: "Shift-Alt-ArrowDown", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -423,9 +423,9 @@ func NewDefaultKeyBindings() []KeyBinding { Name: InsertBlankLine, Type: Standard, Key: "Mod-Enter", - Extension: defaultExtension, - Enabled: true, - PreventDefault: true, + Extension: DefaultExtension, + Enabled: false, + PreventDefault: false, }, { Name: SelectLine, @@ -433,7 +433,7 @@ func NewDefaultKeyBindings() []KeyBinding { Macos: "Ctrl-l", Windows: "Alt-l", Linux: "Alt-l", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -441,7 +441,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectParentSyntax, Type: Standard, Key: "Mod-i", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -449,7 +449,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SimplifySelection, Type: Standard, Key: "Escape", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: false, }, @@ -459,7 +459,7 @@ func NewDefaultKeyBindings() []KeyBinding { Macos: "Cmd-Alt-ArrowUp", Windows: "Ctrl-Alt-ArrowUp", Linux: "Ctrl-Alt-ArrowUp", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -469,7 +469,7 @@ func NewDefaultKeyBindings() []KeyBinding { Macos: "Cmd-Alt-ArrowDown", Windows: "Ctrl-Alt-ArrowDown", Linux: "Ctrl-Alt-ArrowDown", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -479,7 +479,7 @@ func NewDefaultKeyBindings() []KeyBinding { Windows: "Ctrl-ArrowLeft", Linux: "Ctrl-ArrowLeft", Macos: "Alt-ArrowLeft", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -489,7 +489,7 @@ func NewDefaultKeyBindings() []KeyBinding { Windows: "Ctrl-ArrowRight", Linux: "Ctrl-ArrowRight", Macos: "Alt-ArrowRight", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -499,7 +499,7 @@ func NewDefaultKeyBindings() []KeyBinding { Windows: "Ctrl-Shift-ArrowLeft", Linux: "Ctrl-Shift-ArrowLeft", Macos: "Alt-Shift-ArrowLeft", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -509,7 +509,7 @@ func NewDefaultKeyBindings() []KeyBinding { Windows: "Ctrl-Shift-ArrowRight", Linux: "Ctrl-Shift-ArrowRight", Macos: "Alt-Shift-ArrowRight", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -519,7 +519,7 @@ func NewDefaultKeyBindings() []KeyBinding { Macos: "Ctrl-k", Windows: "Ctrl-k", Linux: "Ctrl-k", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -527,7 +527,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: DeleteToLineStart, Type: Standard, Key: "Mod-Shift-Backspace", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -535,7 +535,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CursorLineStart, Type: Standard, Key: "Home", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: false, }, @@ -543,7 +543,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CursorLineEnd, Type: Standard, Key: "End", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: false, }, @@ -551,7 +551,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectLineStart, Type: Standard, Key: "Shift-Home", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: false, }, @@ -559,7 +559,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectLineEnd, Type: Standard, Key: "Shift-End", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: false, }, @@ -567,7 +567,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CursorDocStart, Type: Standard, Key: "Mod-Home", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -575,7 +575,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CursorDocEnd, Type: Standard, Key: "Mod-End", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -583,7 +583,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectDocStart, Type: Standard, Key: "Mod-Shift-Home", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -591,7 +591,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectDocEnd, Type: Standard, Key: "Mod-Shift-End", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -599,7 +599,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectMatchingBracket, Type: Standard, Key: "Mod-Shift-p", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -609,7 +609,7 @@ func NewDefaultKeyBindings() []KeyBinding { Macos: "Ctrl-o", Windows: "Ctrl-o", Linux: "Ctrl-o", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -618,7 +618,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: IndentLess, Type: Standard, Key: "Mod-[", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -626,7 +626,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: IndentMore, Type: Standard, Key: "Mod-]", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -634,7 +634,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: IndentSelection, Type: Standard, Key: "Mod-Alt-\\", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -642,7 +642,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CursorMatchingBracket, Type: Standard, Key: "Shift-Mod-\\", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -650,7 +650,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: ToggleComment, Type: Standard, Key: "Mod-/", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -658,7 +658,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: ToggleBlockComment, Type: Standard, Key: "Shift-Alt-a", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -667,7 +667,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: InsertNewlineAndIndent, Type: Standard, Key: "Enter", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: false, }, @@ -675,7 +675,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: DeleteCharBackward, Type: Standard, Key: "Backspace", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: false, }, @@ -683,7 +683,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: DeleteCharForward, Type: Standard, Key: "Delete", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: false, }, @@ -691,7 +691,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: DeleteGroupBackward, Type: Standard, Key: "Mod-Backspace", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -699,7 +699,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: DeleteGroupForward, Type: Standard, Key: "Mod-Delete", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -712,7 +712,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CursorCharLeft, Type: Emacs, Key: "Ctrl-b", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -720,7 +720,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectCharLeft, Type: Emacs, Key: "Shift-Ctrl-b", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -728,7 +728,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CursorCharRight, Type: Emacs, Key: "Ctrl-f", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -736,7 +736,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectCharRight, Type: Emacs, Key: "Shift-Ctrl-f", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -746,7 +746,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CursorLineUp, Type: Emacs, Key: "Ctrl-p", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -754,7 +754,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectLineUp, Type: Emacs, Key: "Shift-Ctrl-p", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -762,7 +762,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CursorLineDown, Type: Emacs, Key: "Ctrl-n", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -770,7 +770,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectLineDown, Type: Emacs, Key: "Shift-Ctrl-n", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -780,7 +780,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CursorLineStart, Type: Emacs, Key: "Ctrl-a", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -788,7 +788,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectLineStart, Type: Emacs, Key: "Shift-Ctrl-a", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -796,7 +796,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CursorLineEnd, Type: Emacs, Key: "Ctrl-e", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -804,7 +804,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SelectLineEnd, Type: Emacs, Key: "Shift-Ctrl-e", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -814,7 +814,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CursorPageDown, Type: Emacs, Key: "Ctrl-v", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -822,7 +822,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: CursorPageUp, Type: Emacs, Key: "Alt-v", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -832,7 +832,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: DeleteCharForward, Type: Emacs, Key: "Ctrl-d", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -840,7 +840,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: DeleteCharBackward, Type: Emacs, Key: "Ctrl-h", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -848,7 +848,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: DeleteToLineEnd, Type: Emacs, Key: "Ctrl-k", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -856,7 +856,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: DeleteGroupBackward, Type: Emacs, Key: "Ctrl-Alt-h", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -864,7 +864,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: SplitLine, Type: Emacs, Key: "Ctrl-o", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -872,7 +872,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockTransposeChars, Type: Emacs, Key: "Ctrl-t", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -882,7 +882,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockSelectAll, Type: Emacs, Key: "Mod-Shift-a", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, @@ -890,7 +890,7 @@ func NewDefaultKeyBindings() []KeyBinding { Name: BlockPaste, Type: Emacs, Key: "Mod-Shift-v", - Extension: defaultExtension, + Extension: DefaultExtension, Enabled: true, PreventDefault: true, }, diff --git a/internal/services/keybinding_service.go b/internal/services/keybinding_service.go index 6230cbe..4acf995 100644 --- a/internal/services/keybinding_service.go +++ b/internal/services/keybinding_service.go @@ -6,6 +6,7 @@ import ( "voidraft/internal/models" "voidraft/internal/models/ent" + "voidraft/internal/models/ent/extension" "voidraft/internal/models/ent/keybinding" "voidraft/internal/models/schema/mixin" @@ -112,45 +113,74 @@ func (s *KeyBindingService) SyncKeyBindings(ctx context.Context) error { // GetKeyBindings 根据类型获取快捷键 func (s *KeyBindingService) GetKeyBindings(ctx context.Context, kbType models.KeyBindingType) ([]*ent.KeyBinding, error) { - if kbType == models.Standard { - // Standard 模式:只返回 type=standard 且 enabled=true - return s.db.Client.KeyBinding.Query(). - Where( - keybinding.Type(string(kbType)), - keybinding.Enabled(true), - ). - All(ctx) - } - - // Emacs 模式:获取所有 enabled=true 的快捷键 - allEnabled, err := s.db.Client.KeyBinding.Query(). - Where(keybinding.Enabled(true)). + // 获取启用的扩展名称集合 + enabledExts, err := s.db.Client.Extension.Query(). + Where(extension.Enabled(true)). All(ctx) if err != nil { - return nil, fmt.Errorf("query enabled key bindings error: %w", err) + return nil, fmt.Errorf("query enabled extensions error: %w", err) + } + enabledExtMap := make(map[string]bool, len(enabledExts)) + for _, ext := range enabledExts { + enabledExtMap[ext.Name] = true + } + + if kbType == models.Standard { + // Standard 模式:返回扩展已启用的快捷键 + bindings, err := s.db.Client.KeyBinding.Query(). + Where(keybinding.Type(string(kbType))). + Order(ent.Asc(keybinding.FieldID)). + All(ctx) + if err != nil { + return nil, err + } + return filterByExtension(bindings, enabledExtMap), nil + } + + // Emacs 模式:获取所有快捷键 + allBindings, err := s.db.Client.KeyBinding.Query(). + Order(ent.Asc(keybinding.FieldID)). + All(ctx) + if err != nil { + return nil, fmt.Errorf("query key bindings error: %w", err) } // 构建 emacs 快捷键的 name 集合 emacsNames := make(map[string]bool) - for _, kb := range allEnabled { + for _, kb := range allBindings { if kb.Type == string(models.Emacs) { emacsNames[kb.Name] = true } } - // 过滤:去掉与 emacs 冲突的 standard 快捷键 + // 过滤:去掉与 emacs 冲突的 standard 快捷键,并过滤扩展未启用的 var result []*ent.KeyBinding - for _, kb := range allEnabled { - // 如果是 standard 类型,且与 emacs 有 name 冲突,则跳过 + for _, kb := range allBindings { if kb.Type == string(models.Standard) && emacsNames[kb.Name] { continue } + // editor 扩展始终包含,不检查启用状态 + if kb.Extension != models.DefaultExtension && !enabledExtMap[kb.Extension] { + continue + } result = append(result, kb) } return result, nil } +// filterByExtension 过滤出扩展已启用的快捷键 +func filterByExtension(bindings []*ent.KeyBinding, enabledExtMap map[string]bool) []*ent.KeyBinding { + result := make([]*ent.KeyBinding, 0, len(bindings)) + for _, kb := range bindings { + // editor 扩展始终包含,不检查启用状态 + if kb.Extension == models.DefaultExtension || enabledExtMap[kb.Extension] { + result = append(result, kb) + } + } + return result +} + // GetKeyBindingByID 根据ID获取快捷键 func (s *KeyBindingService) GetKeyBindingByID(ctx context.Context, id int) (*ent.KeyBinding, error) { kb, err := s.db.Client.KeyBinding.Get(ctx, id) @@ -163,7 +193,7 @@ func (s *KeyBindingService) GetKeyBindingByID(ctx context.Context, id int) (*ent return kb, nil } -// UpdateKeyBindingKeys 更新快捷键绑定(根据操作系统自动判断更新哪个字段) +// UpdateKeyBindingKeys 更新快捷键绑定 func (s *KeyBindingService) UpdateKeyBindingKeys(ctx context.Context, id int, key string) error { kb, err := s.GetKeyBindingByID(ctx, id) if err != nil { @@ -204,6 +234,20 @@ func (s *KeyBindingService) UpdateKeyBindingEnabled(ctx context.Context, id int, Exec(ctx) } +// UpdateKeyBindingPreventDefault 更新快捷键 PreventDefault 状态 +func (s *KeyBindingService) UpdateKeyBindingPreventDefault(ctx context.Context, id int, preventDefault bool) error { + kb, err := s.GetKeyBindingByID(ctx, id) + if err != nil { + return err + } + if kb == nil { + return fmt.Errorf("key binding not found: id=%d", id) + } + return s.db.Client.KeyBinding.UpdateOneID(kb.ID). + SetPreventDefault(preventDefault). + Exec(ctx) +} + // GetDefaultKeyBindings 获取默认快捷键配置 func (s *KeyBindingService) GetDefaultKeyBindings() []models.KeyBinding { return models.NewDefaultKeyBindings()