diff --git a/src/BaseFileView.tsx b/src/BaseFileView.tsx index 79fafe0..cc1f03f 100644 --- a/src/BaseFileView.tsx +++ b/src/BaseFileView.tsx @@ -11,6 +11,7 @@ export default abstract class BaseView extends TextFileView { protected state: { filePath?: string } | null = null; protected isEditorLoaded: boolean = false; protected currentFilePath: string | null = null; + protected isClosing: boolean = false; protected constructor(leaf: WorkspaceLeaf, plugin: InfioPlugin) { super(leaf); @@ -79,7 +80,7 @@ export default abstract class BaseView extends TextFileView { async onLoadFile(file: TFile): Promise { try { - const content = await this.app.vault.read(file); + const content = await this.app.vault.cachedRead(file); this.setViewData(content, true); } catch (error) { console.error('Failed to load file content:', error); @@ -103,8 +104,20 @@ export default abstract class BaseView extends TextFileView { } async save(clear?: boolean): Promise { + // Prevent saving if the view is closing + if (this.isClosing) { + console.log("save() called during close, skipping to prevent data loss"); + return; + } + const content = this.getViewData(); + // Additional safety check: don't save if content is empty and we had content before + if (!content.trim() && this.currentFilePath) { + console.log("Refusing to save empty content, potential data loss prevented"); + return; + } + if (this.file) { // Regular file in vault await this.app.vault.modify(this.file, content); @@ -133,6 +146,7 @@ export default abstract class BaseView extends TextFileView { } onClose(): Promise { + this.isClosing = true; return super.onClose(); } @@ -145,7 +159,7 @@ export default abstract class BaseView extends TextFileView { } protected onEditorUpdate(update: ViewUpdate): void { - if (update.docChanged) { + if (update.docChanged && !this.isClosing) { this.requestSave(); } } diff --git a/src/core/mcp/McpHub.ts b/src/core/mcp/McpHub.ts index 089021c..2b66ce2 100644 --- a/src/core/mcp/McpHub.ts +++ b/src/core/mcp/McpHub.ts @@ -150,6 +150,7 @@ export class McpHub { private mcpSettingsFilePath: string | null = null // private globalMcpFilePath: string | null = null private fileWatchers: Map = new Map() + private configFileChangeTimeout: NodeJS.Timeout | null = null private isDisposed: boolean = false connections: McpConnection[] = [] // 添加内置服务器连接 @@ -177,7 +178,7 @@ export class McpHub { // Ensure the MCP configuration directory exists await this.ensureMcpFileExists() await this.watchMcpSettingsFile(); - this.setupWorkspaceWatcher(); + // this.setupWorkspaceWatcher(); await this.initializeGlobalMcpServers(); // 初始化内置服务器 await this.initializeBuiltInServer(); @@ -287,7 +288,6 @@ export class McpHub { this.eventRefs.push(this.app.vault.on('modify', async (file) => { // Adjusted to use the new config file name and path logic const configFilePath = await this.getMcpSettingsFilePath(); - console.log("configFilePath", configFilePath) if (file instanceof TFile && file.path === configFilePath) { await this.handleConfigFileChange(file.path); } @@ -295,7 +295,6 @@ export class McpHub { } private async handleConfigFileChange(filePath: string): Promise { - console.log("handleConfigFileChange", filePath) try { const content = await this.app.vault.adapter.read(filePath); const config = JSON.parse(content) @@ -347,7 +346,6 @@ export class McpHub { } async ensureMcpFileExists(): Promise { - console.log("ensureMcpFileExists") // 新的配置目录和文件路径 const newMcpFolderPath = ROOT_DIR const newMcpSettingsFilePath = normalizePath(path.join(newMcpFolderPath, "mcp_settings.json"))