diff --git a/packages/frontend/src/components/MonacoEditor.vue b/packages/frontend/src/components/MonacoEditor.vue index 6a2cb5f..eaf4236 100644 --- a/packages/frontend/src/components/MonacoEditor.vue +++ b/packages/frontend/src/components/MonacoEditor.vue @@ -7,6 +7,8 @@ import { ref, onMounted, onBeforeUnmount, watch } from 'vue'; import * as monaco from 'monaco-editor'; // Props for the component (will be expanded later) +const fontSize = ref(14); // 添加字体大小状态,默认 14 + const props = defineProps({ modelValue: { // Use modelValue for v-model support type: String, @@ -38,6 +40,7 @@ onMounted(() => { value: props.modelValue, language: props.language, theme: props.theme, + fontSize: fontSize.value, // 使用 ref 作为初始字体大小 automaticLayout: true, // Auto resize editor on container resize readOnly: props.readOnly, // Add more options as needed @@ -73,6 +76,56 @@ onMounted(() => { }, }); + // Listen for content changes and emit update event for v-model + editorInstance.onDidChangeModelContent(() => { + if (editorInstance) { + const currentValue = editorInstance.getValue(); + if (currentValue !== props.modelValue) { + emit('update:modelValue', currentValue); + } + } + }); + + // Add Ctrl+S / Cmd+S keybinding for saving + editorInstance.addAction({ + id: 'save-file', + label: 'Save File', + keybindings: [ + monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, + ], + precondition: undefined, // Fix: Use undefined instead of null + keybindingContext: undefined, // Fix: Use undefined instead of null + contextMenuGroupId: 'navigation', // Optional: where to show in context menu + contextMenuOrder: 1.5, // Optional: order in context menu + run: () => { + console.log('[MonacoEditor] Save action triggered (Ctrl+S / Cmd+S)'); + emit('request-save'); + }, + }); + + // 添加鼠标滚轮缩放功能 + editorContainer.value.addEventListener('wheel', (event: WheelEvent) => { + // 只在按下Ctrl键时才触发缩放 + if (event.ctrlKey) { + event.preventDefault(); // 阻止默认的滚动行为 + + // 根据滚轮方向调整字体大小 + if (event.deltaY < 0) { + // 向上滚动,增大字体 + fontSize.value = Math.min(fontSize.value + 1, 40); // 设置最大字体大小为40 + } else { + // 向下滚动,减小字体 + fontSize.value = Math.max(fontSize.value - 1, 8); // 设置最小字体大小为8 + } + + // 更新编辑器字体大小 + if (editorInstance) { + editorInstance.updateOptions({ fontSize: fontSize.value }); + console.log(`[MonacoEditor] Font size changed to: ${fontSize.value}`); // 添加日志 + } + } + }, { passive: false }); // 设置 passive: false 允许 preventDefault + } }); diff --git a/packages/frontend/src/components/Terminal.vue b/packages/frontend/src/components/Terminal.vue index 2c80f42..8b5c0bc 100644 --- a/packages/frontend/src/components/Terminal.vue +++ b/packages/frontend/src/components/Terminal.vue @@ -114,8 +114,8 @@ onMounted(() => { // console.log(`[Terminal ${props.sessionId}] ResizeObserver triggered. Height: ${height}, isActive: ${props.isActive}`); if (height > 0 && terminal) { // 仅在可见时调整 try { - fitAddon?.fit(); // 视觉上适应 - // 触发防抖的 resize 发送,主要应对窗口 resize + // fitAddon?.fit(); // 视觉上适应 <-- 移除此行,不再强制 fit 内部行数 + // 触发防抖的 resize 发送,通知后端潜在的尺寸变化 debouncedEmitResize(terminal); } catch (e) { console.warn("Fit addon resize failed (observer):", e); @@ -166,6 +166,15 @@ onMounted(() => { if (done) break; if (terminal && value) { terminal.write(value); // 将流数据写入终端 + // 尝试在写入数据后调用 fit,看是否能触发滚动条 + nextTick(() => { // 使用 nextTick 确保 DOM 更新后再 fit + try { + fitAddon?.fit(); + // 注意:这里可能不需要再 emit resize,因为 fit 主要是为了更新内部布局以适应外部滚动 + } catch (fitError) { + console.warn("Fit addon failed after writing stream data:", fitError); + } + }); } } } catch (error) { @@ -182,9 +191,29 @@ onMounted(() => { // 聚焦终端 terminal.focus(); - // 添加鼠标滚轮缩放功能 + // 重新添加鼠标滚轮缩放功能 if (terminalRef.value) { terminalRef.value.addEventListener('wheel', (event: WheelEvent) => { + // // 只在按下Ctrl键时才触发缩放 + // if (event.ctrlKey) { + // event.preventDefault(); // 阻止默认的滚动行为 + + // // 根据滚轮方向调整字体大小 + // if (event.deltaY < 0) { + // // 向上滚动,增大字体 + // fontSize.value = Math.min(fontSize.value + 1, 40); // 设置最大字体大小为40 + // } else { + // // 向下滚动,减小字体 + // fontSize.value = Math.max(fontSize.value - 1, 8); // 设置最小字体大小为8 + // } + + // // 更新终端字体大小 + // if (terminal) { + // terminal.options.fontSize = fontSize.value; + // // 调整终端大小以适应新的字体大小 + // fitAddon?.fit(); + // emit('resize', { cols: terminal.cols, rows: terminal.rows }); + // } // 只在按下Ctrl键时才触发缩放 if (event.ctrlKey) { event.preventDefault(); // 阻止默认的滚动行为 @@ -235,26 +264,11 @@ defineExpose({ write }); diff --git a/packages/frontend/src/views/WorkspaceView.vue b/packages/frontend/src/views/WorkspaceView.vue index 74dfb47..21e8eb0 100644 --- a/packages/frontend/src/views/WorkspaceView.vue +++ b/packages/frontend/src/views/WorkspaceView.vue @@ -189,8 +189,7 @@ onBeforeUnmount(() => { - - + { - - +
{ - - + @@ -274,8 +271,7 @@ onBeforeUnmount(() => { - - + { - - +
{ } /* 为 Pane 添加一些基本样式 */ -.pane-with-title { /* 给包含标题栏的 Pane 添加基础样式 */ - display: flex; - flex-direction: column; - overflow: hidden; -} +/* .pane-with-title 已移除 */ .pane-content { /* 让内容区域填充剩余空间 */ flex-grow: 1; overflow: auto; /* 或者 hidden,根据需要 */ @@ -362,7 +353,9 @@ onBeforeUnmount(() => { .file-manager-area-pane, /* 文件管理器区域 Pane */ .file-manager-pane, /* 内部文件管理器 Pane */ .status-monitor-pane { /* 状态监视器样式 */ - /* display: flex; flex-direction: column; overflow: hidden; 已被 pane-with-title 或 pane-content 处理 */ + display: flex; /* 确保 flex 布局 */ + flex-direction: column; /* 确保列方向 */ + overflow: hidden; /* 默认隐藏溢出 */ background-color: #f8f9fa; /* 默认背景色 */ } .middle-pane { @@ -396,7 +389,7 @@ onBeforeUnmount(() => { flex-grow: 1; display: flex; flex-direction: column; - overflow: hidden; + overflow: hidden; /* <-- 重新添加,隐藏外部滚动条 */ } .file-editor-pane { background-color: #f8f9fa; /* 外层 pane 背景 */ @@ -440,7 +433,7 @@ onBeforeUnmount(() => { flex-grow: 1; display: flex; flex-direction: column; - overflow: hidden; + overflow: hidden; /* <-- 重新添加,隐藏外部滚动条 */ } /* 文件管理器包装器 (内部组件应填充) */