diff --git a/src/components/apply-view/ApplyViewRoot.tsx b/src/components/apply-view/ApplyViewRoot.tsx index 94c1bc2..e763bef 100644 --- a/src/components/apply-view/ApplyViewRoot.tsx +++ b/src/components/apply-view/ApplyViewRoot.tsx @@ -1,7 +1,7 @@ import { Change, diffLines } from 'diff' import { CheckIcon, X } from 'lucide-react' -import { getIcon } from 'obsidian' -import { useState } from 'react' +import { Platform, getIcon } from 'obsidian' +import { useEffect, useState } from 'react' import { ApplyViewState } from '../../ApplyView' import { useApp } from '../../contexts/AppContext' @@ -17,6 +17,14 @@ export default function ApplyViewRoot({ const rejectIcon = getIcon('x') const excludeIcon = getIcon('x') + const getShortcutText = (shortcut: 'accept' | 'reject') => { + const isMac = Platform.isMacOS + if (shortcut === 'accept') { + return isMac ? '(⌘⏎)' : '(Ctrl+⏎)' + } + return isMac ? '(⌘⌫)' : '(Ctrl+⌫)' + } + const app = useApp() const [diff, setDiff] = useState( @@ -64,6 +72,30 @@ export default function ApplyViewRoot({ }) } + const handleKeyDown = (event: KeyboardEvent) => { + const modifierKey = Platform.isMacOS ? event.metaKey : event.ctrlKey; + if (modifierKey) { + if (event.key === 'Enter') { + event.preventDefault(); + event.stopPropagation(); + handleAccept(); + } else if (event.key === 'Backspace') { + event.preventDefault(); + event.stopPropagation(); + handleReject(); + } + } + } + + // 在组件挂载时添加事件监听器,在卸载时移除 + useEffect(() => { + const handler = (e: KeyboardEvent) => handleKeyDown(e); + window.addEventListener('keydown', handler, true); + return () => { + window.removeEventListener('keydown', handler, true); + } + }, [handleAccept, handleReject]) // 添加handleAccept和handleReject作为依赖项 + return (
@@ -81,7 +113,7 @@ export default function ApplyViewRoot({ onClick={handleAccept} > {acceptIcon && } - Accept + Accept {getShortcutText('accept')}
diff --git a/src/components/inline-edit/InlineEdit.tsx b/src/components/inline-edit/InlineEdit.tsx index 69e38e8..1aa27b6 100644 --- a/src/components/inline-edit/InlineEdit.tsx +++ b/src/components/inline-edit/InlineEdit.tsx @@ -1,6 +1,6 @@ -import { MarkdownView, Plugin } from 'obsidian'; +import { MarkdownView, Plugin, Platform } from 'obsidian'; import React, { useEffect, useMemo, useRef, useState } from 'react'; - +import { CornerDownLeft } from 'lucide-react'; import { APPLY_VIEW_TYPE } from '../../constants'; import LLMManager from '../../core/llm/manager'; import { InfioSettings } from '../../types/settings'; @@ -20,24 +20,41 @@ type InlineEditProps = { type InputAreaProps = { value: string; onChange: (value: string) => void; + handleSubmit: () => void; + handleClose: () => void; } -const InputArea: React.FC = ({ value, onChange }) => { +const InputArea: React.FC = ({ value, onChange, handleSubmit, handleClose }) => { const textareaRef = useRef(null); useEffect(() => { - // 组件挂载后自动聚焦到 textarea textareaRef.current?.focus(); }, []); + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + if (e.shiftKey) { + // Shift + Enter: 允许换行,使用默认行为 + return; + } + // 普通 Enter: 阻止默认行为并触发提交 + e.preventDefault(); + handleSubmit(); + } else if (e.key === 'Escape') { + // 当按下 Esc 键时关闭编辑器 + handleClose(); + } + }; + return (