diff --git a/packages/frontend/src/components/CodeMirrorMobileEditor.vue b/packages/frontend/src/components/CodeMirrorMobileEditor.vue index 225f831..46c9aaa 100644 --- a/packages/frontend/src/components/CodeMirrorMobileEditor.vue +++ b/packages/frontend/src/components/CodeMirrorMobileEditor.vue @@ -6,12 +6,12 @@ import { ref, onMounted, onBeforeUnmount, watch, shallowRef, computed } from 'vue'; import { EditorState, Compartment } from '@codemirror/state'; import { useAppearanceStore } from '../stores/appearance.store'; -import { EditorView, keymap, lineNumbers, highlightActiveLineGutter, highlightActiveLine, drawSelection, dropCursor } from '@codemirror/view'; -import { syntaxHighlighting, defaultHighlightStyle, indentOnInput, bracketMatching, foldGutter, foldKeymap } from '@codemirror/language'; +import { EditorView, keymap, lineNumbers, highlightActiveLineGutter, highlightActiveLine, drawSelection, dropCursor } from '@codemirror/view'; +import { syntaxHighlighting, defaultHighlightStyle, indentOnInput, bracketMatching, foldGutter, foldKeymap } from '@codemirror/language'; import { vscodeDark } from '@uiw/codemirror-theme-vscode'; -import { history, historyKeymap, defaultKeymap } from '@codemirror/commands'; +import { history, historyKeymap, defaultKeymap } from '@codemirror/commands'; import { autocompletion, closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete'; -import { highlightSelectionMatches } from '@codemirror/search'; +import { highlightSelectionMatches, searchKeymap, openSearchPanel } from '@codemirror/search'; // + Import search functionalities const props = defineProps({ modelValue: { @@ -121,11 +121,12 @@ const createEditorState = (doc: string, languageExtension: any) => { } }), keymap.of([ - ...closeBracketsKeymap, + ...closeBracketsKeymap, ...defaultKeymap, ...historyKeymap, - ...foldKeymap, - { key: "Mod-s", run: () => { emit('request-save'); return true; } } + ...foldKeymap, + ...searchKeymap, // + Add search keymap + { key: "Mod-s", run: () => { emit('request-save'); return true; } } ]), ], }); @@ -271,8 +272,15 @@ watch(() => appearanceStore.currentMobileEditorFontSize, (newSize) => { } }); +const openSearch = () => { + if (view.value) { + openSearchPanel(view.value); + } +}; + defineExpose({ focus: () => view.value?.focus(), + openSearch, // + Expose openSearch method }); diff --git a/packages/frontend/src/components/FileEditorOverlay.vue b/packages/frontend/src/components/FileEditorOverlay.vue index ebaf360..155fd02 100644 --- a/packages/frontend/src/components/FileEditorOverlay.vue +++ b/packages/frontend/src/components/FileEditorOverlay.vue @@ -94,6 +94,7 @@ const startHeightPx = ref(0); const minWidth = 400; // 最小宽度 const minHeight = 300; // 最小高度 const encodingSelectRef = ref(null); // +++ Ref for the select element +++ +const codeMirrorMobileEditorRef = ref | null>(null); // +++ Ref for CodeMirrorMobileEditor +++ // --- 计算属性,用于模板绑定 --- const popupStyle = computed(() => { @@ -422,6 +423,13 @@ const handleEditorScroll = ({ scrollTop, scrollLeft }: { scrollTop: number; scro const handleEditorFontSizeUpdate = (newSize: number) => { appearanceStore.setEditorFontSize(newSize); }; + +// +++ 打开搜索面板 +++ +const handleOpenSearch = () => { + if (codeMirrorMobileEditorRef.value) { + codeMirrorMobileEditorRef.value.openSearch(); + } +}; // 关闭弹窗 (保持不变) const handleCloseContainer = () => { @@ -561,6 +569,17 @@ onBeforeUnmount(() => { + + @@ -601,6 +620,7 @@ onBeforeUnmount(() => { :language="currentTabLanguage" class="editor-instance" @request-save="handleSaveRequest" + ref="codeMirrorMobileEditorRef" />
{{ t('fileManager.selectFileToEdit') }}
@@ -817,6 +837,27 @@ onBeforeUnmount(() => { background-color: #45a049; } +/* +++ 搜索按钮样式 +++ */ +.search-btn { + background-color: #555; /* 与其他按钮风格类似 */ + color: white; + border: none; + padding: 0.4rem 0.6rem; /* 调整内边距以适应图标 */ + cursor: pointer; + border-radius: 3px; + font-size: 0.9em; + display: inline-flex; /* 使图标居中 */ + align-items: center; + justify-content: center; +} +.search-btn:hover { + background-color: #666; +} +.search-btn svg { + pointer-events: none; /* 防止 SVG 捕获点击事件 */ +} + + .save-status { font-size: 0.9em; padding: 0.2rem 0.5rem;