diff --git a/src/workbench/writerActions.ts b/src/workbench/writerActions.ts index 15b6e7b..316cfec 100644 --- a/src/workbench/writerActions.ts +++ b/src/workbench/writerActions.ts @@ -86,15 +86,22 @@ export async function insertEdgeForward( await insertEdgeInZone(app, editor, file, "note_links", edgeType, targetLink, settings); // Automatically create inverse edge in target note/section - await createInverseEdge( - app, - edgeType, - todo, - vocabulary, - edgeVocabulary, - settings, - debugLogging - ); + console.log("[insertEdgeForward] About to create inverse edge (note_links), edgeType:", edgeType); + try { + await createInverseEdge( + app, + edgeType, + todo, + vocabulary, + edgeVocabulary, + settings, + debugLogging + ); + console.log("[insertEdgeForward] createInverseEdge call completed (note_links)"); + } catch (error) { + console.error("[insertEdgeForward] Error calling createInverseEdge (note_links):", error); + // Don't throw - inverse edge creation is optional + } } else if (targetZone === "candidates") { // Insert in Kandidaten zone if (debugLogging) { @@ -103,15 +110,22 @@ export async function insertEdgeForward( await insertEdgeInZone(app, editor, file, "candidates", edgeType, targetLink, settings); // Automatically create inverse edge in target note/section - await createInverseEdge( - app, - edgeType, - todo, - vocabulary, - edgeVocabulary, - settings, - debugLogging - ); + console.log("[insertEdgeForward] About to create inverse edge (candidates), edgeType:", edgeType); + try { + await createInverseEdge( + app, + edgeType, + todo, + vocabulary, + edgeVocabulary, + settings, + debugLogging + ); + console.log("[insertEdgeForward] createInverseEdge call completed (candidates)"); + } catch (error) { + console.error("[insertEdgeForward] Error calling createInverseEdge (candidates):", error); + // Don't throw - inverse edge creation is optional + } } else { // Insert in source section - need to select section if multiple exist // IMPORTANT: Use source note (fromNodeRef.file), not current note! @@ -242,15 +256,22 @@ export async function insertEdgeForward( } // Automatically create inverse edge in target note/section - await createInverseEdge( - app, - edgeType, - todo, - vocabulary, - edgeVocabulary, - settings, - debugLogging - ); + console.log("[insertEdgeForward] About to create inverse edge, edgeType:", edgeType); + try { + await createInverseEdge( + app, + edgeType, + todo, + vocabulary, + edgeVocabulary, + settings, + debugLogging + ); + console.log("[insertEdgeForward] createInverseEdge call completed"); + } catch (error) { + console.error("[insertEdgeForward] Error calling createInverseEdge:", error); + // Don't throw - inverse edge creation is optional + } } } @@ -267,113 +288,117 @@ async function createInverseEdge( debugLogging?: boolean ): Promise { try { - console.log("[createInverseEdge] Starting inverse edge creation for:", forwardEdgeType); + console.log("[createInverseEdge] ===== STARTING INVERSE EDGE CREATION ====="); + console.log("[createInverseEdge] Forward edge type:", forwardEdgeType); // Get canonical type and inverse const canonical = vocabulary.getCanonical(forwardEdgeType); + console.log("[createInverseEdge] Canonical type:", canonical); if (!canonical) { console.log("[createInverseEdge] No canonical type found for:", forwardEdgeType); return; // Can't create inverse without canonical type } const inverseCanonical = vocabulary.getInverse(canonical); + console.log("[createInverseEdge] Inverse canonical:", inverseCanonical); if (!inverseCanonical) { console.log("[createInverseEdge] No inverse defined for:", canonical); return; // No inverse defined, skip } - // Get the raw inverse type (use canonical or find an alias) - const inverseEntry = edgeVocabulary.byCanonical.get(inverseCanonical); - const inverseEdgeType = inverseEntry?.aliases?.[0] || inverseCanonical; + // Use canonical type for inverse edge (consistent and unambiguous) + // The inverseCanonical is already the canonical type from vocabulary + const inverseEdgeType = inverseCanonical; - console.log("[createInverseEdge] Forward:", forwardEdgeType, "-> Canonical:", canonical, "-> Inverse:", inverseEdgeType); + console.log("[createInverseEdge] Forward:", forwardEdgeType, "-> Canonical:", canonical, "-> Inverse canonical:", inverseCanonical, "-> Using:", inverseEdgeType); - // Find target file - const targetFileRef = todo.toNodeRef.file; - let targetFile: TFile | null = null; - - const possiblePaths = [ - targetFileRef, - targetFileRef + ".md", - targetFileRef.replace(/\.md$/, ""), - targetFileRef.replace(/\.md$/, "") + ".md", - ]; - - for (const path of possiblePaths) { - const found = app.vault.getAbstractFileByPath(path); - if (found && found instanceof TFile) { - targetFile = found; - break; + // Find target file + const targetFileRef = todo.toNodeRef.file; + let targetFile: TFile | null = null; + + const possiblePaths = [ + targetFileRef, + targetFileRef + ".md", + targetFileRef.replace(/\.md$/, ""), + targetFileRef.replace(/\.md$/, "") + ".md", + ]; + + for (const path of possiblePaths) { + const found = app.vault.getAbstractFileByPath(path); + if (found && found instanceof TFile) { + targetFile = found; + break; + } } - } - - if (!targetFile) { - const basename = targetFileRef.replace(/\.md$/, "").split("/").pop() || targetFileRef; - const resolved = app.metadataCache.getFirstLinkpathDest(basename, todo.fromNodeRef.file); - if (resolved) { - targetFile = resolved; + + if (!targetFile) { + const basename = targetFileRef.replace(/\.md$/, "").split("/").pop() || targetFileRef; + const resolved = app.metadataCache.getFirstLinkpathDest(basename, todo.fromNodeRef.file); + if (resolved) { + targetFile = resolved; + } } - } - - if (!targetFile) { - console.log("[createInverseEdge] Target file not found:", targetFileRef); - return; - } - - // Build source link (for inverse edge, source is the original target) - const sourceBasename = todo.fromNodeRef.file.replace(/\.md$/, "").split("/").pop() || todo.fromNodeRef.file; - const sourceLink = todo.fromNodeRef.heading - ? `${sourceBasename}#${todo.fromNodeRef.heading}` - : sourceBasename; - - // Always ask user to select target section (or whole note) - // Open target file in editor first - console.log("[createInverseEdge] Opening target file:", targetFile.path); - await app.workspace.openLinkText(targetFile.path, "", false); - - // Wait a bit for the editor to be ready - await new Promise(resolve => setTimeout(resolve, 100)); - - const targetEditor = app.workspace.activeEditor?.editor; - if (!targetEditor) { - console.error("[createInverseEdge] Could not get editor for target file:", targetFile.path); - return; - } - - // Load sections from target file - const { splitIntoSections } = await import("../mapping/sectionParser"); - const targetContent = await app.vault.read(targetFile); - const sections = splitIntoSections(targetContent); - - // Filter out special zones - const contentSections = sections.filter( - (s) => s.heading !== "Kandidaten" && s.heading !== "Note-Verbindungen" - ); - - // Show selection modal: user can choose a section or "whole note" - const selectedTarget = await selectTargetForInverseEdge( - app, - targetFile, - contentSections, - todo.toNodeRef.heading, - debugLogging - ); - - if (!selectedTarget) { - console.log("[createInverseEdge] User cancelled target selection"); - return; // User cancelled - } - - console.log("[createInverseEdge] Selected target:", selectedTarget.type, selectedTarget.heading || "(whole note)"); - console.log("[createInverseEdge] Inverse edge type:", inverseEdgeType, "source link:", sourceLink); - - try { + + if (!targetFile) { + console.log("[createInverseEdge] Target file not found:", targetFileRef); + return; + } + + // Build source link (for inverse edge, source is the original target) + const sourceBasename = todo.fromNodeRef.file.replace(/\.md$/, "").split("/").pop() || todo.fromNodeRef.file; + const sourceLink = todo.fromNodeRef.heading + ? `${sourceBasename}#${todo.fromNodeRef.heading}` + : sourceBasename; + + // Always ask user to select target section (or whole note) + // Open target file in editor first + console.log("[createInverseEdge] Opening target file:", targetFile.path); + await app.workspace.openLinkText(targetFile.path, "", false); + + // Wait a bit for the editor to be ready + await new Promise(resolve => setTimeout(resolve, 100)); + + const targetEditor = app.workspace.activeEditor?.editor; + if (!targetEditor) { + console.error("[createInverseEdge] Could not get editor for target file:", targetFile.path); + return; + } + + // Load sections from target file + const { splitIntoSections } = await import("../mapping/sectionParser"); + const targetContent = await app.vault.read(targetFile); + const sections = splitIntoSections(targetContent); + + // Filter out special zones + const contentSections = sections.filter( + (s) => s.heading !== "Kandidaten" && s.heading !== "Note-Verbindungen" + ); + + // Show selection modal: user can choose a section or "whole note" + console.log("[createInverseEdge] Showing target selection modal, sections:", contentSections.length); + const selectedTarget = await selectTargetForInverseEdge( + app, + targetFile, + contentSections, + todo.toNodeRef.heading, + debugLogging + ); + + if (!selectedTarget) { + console.log("[createInverseEdge] User cancelled target selection"); + return; // User cancelled + } + + console.log("[createInverseEdge] Selected target:", selectedTarget.type, selectedTarget.heading || "(whole note)"); + console.log("[createInverseEdge] Inverse edge type:", inverseEdgeType, "source link:", sourceLink); + if (selectedTarget.type === "note_links") { console.log("[createInverseEdge] Calling insertEdgeInZone with note_links"); await insertEdgeInZone(app, targetEditor, targetFile, "note_links", inverseEdgeType, sourceLink, settings); console.log("[createInverseEdge] insertEdgeInZone completed"); } else { // Use selected section + console.log("[createInverseEdge] Looking for section:", selectedTarget.heading); const targetSection = await findSection(app, targetFile, selectedTarget.heading); if (targetSection) { console.log("[createInverseEdge] Found target section:", targetSection.heading || "(root)"); @@ -395,14 +420,12 @@ async function createInverseEdge( } } - console.log("[createInverseEdge] Inverse edge creation completed successfully"); + console.log("[createInverseEdge] ===== INVERSE EDGE CREATION COMPLETED SUCCESSFULLY ====="); } catch (error) { - console.error("[createInverseEdge] Error during edge insertion:", error); - throw error; // Re-throw to see the error - } - } catch (error) { - console.error("[createInverseEdge] Error creating inverse edge:", error); - // Don't throw - inverse edge creation is optional + console.error("[createInverseEdge] ===== ERROR IN INVERSE EDGE CREATION ====="); + console.error("[createInverseEdge] Error:", error); + console.error("[createInverseEdge] Error stack:", error instanceof Error ? error.stack : String(error)); + // Don't throw - inverse edge creation is optional, but log the error } }