diff --git a/src/core/NoteGraph.ts b/src/core/NoteGraph.ts index 7bd6cc5..f863aa0 100644 --- a/src/core/NoteGraph.ts +++ b/src/core/NoteGraph.ts @@ -1,11 +1,11 @@ import { Edge, Graph } from 'graphlib'; +import * as md5 from 'md5'; import { Uri } from 'vscode'; +import { Logger } from '../services'; + +import { Event, Emitter } from './common/event'; import { Note } from './Note'; import { Parser } from './Parser'; -import * as md5 from 'md5'; -import { Event, Emitter } from './common/event'; -import { notStrictEqual } from 'assert'; - export class GraphNote{ path: string; @@ -158,7 +158,9 @@ export class NoteGraph { if(!edges){ return []; } else { - return edges.map((edge) => this.graph.node(edge.w).path); + const forwardLinks: string[] = edges.map((edge) => this.graph.node(edge.w).path); + Logger.info(`Found ${forwardLinks.length} forward links for ${this.graph.node(sourceId).path}`); + return forwardLinks; } } @@ -169,7 +171,6 @@ export class NoteGraph { this.graph.setNode(newId, oldNode); - if(inEdges){ for(const inEdge of inEdges){ this.graph.setEdge(inEdge.v, newId); diff --git a/src/services/bootstrap.ts b/src/services/bootstrap.ts index 98ca871..4bc040b 100644 --- a/src/services/bootstrap.ts +++ b/src/services/bootstrap.ts @@ -7,7 +7,7 @@ import { CodekastenParser } from "../vscode"; import { FilesystemSyncher } from './filesystemSyncher'; export const bootstrap = async(): Promise => { - const watcher = vscode.workspace.createFileSystemWatcher("**/*.md"); + const watcher: vscode.FileSystemWatcher = vscode.workspace.createFileSystemWatcher("**/*.md"); const parser: CodekastenParser = new CodekastenParser(); const codekastenGraph: NoteGraph = new NoteGraph(); await codekastenGraph.populateGraph(vscode.workspace.findFiles('**/*.md', '{.codekasten, ./index.md}'), parser); @@ -16,20 +16,26 @@ export const bootstrap = async(): Promise => { const filesystemSyncher: FilesystemSyncher = new FilesystemSyncher(codekastenGraph); watcher.onDidCreate(async uri => { + Logger.info(`Created a file: ${uri.fsPath}`); codekastenGraph.setNote(await parser.parse(uri)); }); watcher.onDidChange(async uri => { + Logger.info(`Changed a file: ${uri.fsPath}`); codekastenGraph.setNote(await parser.parse(uri)); }); watcher.onDidDelete(uri => { + Logger.info(`Deleted a file: ${uri.fsPath}`); codekastenGraph.deleteNote(md5(uri.fsPath)); }); + vscode.workspace.onWillRenameFiles(async event => { + await filesystemSyncher.onWillRename(event); + }); + vscode.workspace.onDidRenameFiles(event => { - console.log('File Rename Event!'); - filesystemSyncher.onDidRename(event); + }); return codekastenGraph; diff --git a/src/services/filesystemSyncher.ts b/src/services/filesystemSyncher.ts index 772bae2..ff9843b 100644 --- a/src/services/filesystemSyncher.ts +++ b/src/services/filesystemSyncher.ts @@ -1,8 +1,11 @@ +import * as md5 from 'md5'; import * as vscode from 'vscode'; + import { NoteGraph } from '../core'; -import * as md5 from 'md5'; import { MarkdownLink } from '../core/Link'; -import { escapeRegex, replaceTextInFile } from '../vscode/NoteActions'; +import { replaceTextInFile } from '../vscode/NoteActions'; + +import { Logger } from './logger'; export class FilesystemSyncher{ @@ -12,43 +15,47 @@ export class FilesystemSyncher{ this.graph = graph; } - onDidRename(event: vscode.FileRenameEvent) { + /** + * Handels the renaming of forward- and backlinks in the markdown files + * The changes in the NoteGraph will be made by the respective onDidChange events. + */ + async onWillRename(event: vscode.FileRenameEvent) { for(const file of event.files){ + const oldId = md5(file.oldUri.fsPath); const newId = md5(file.newUri.fsPath); + Logger.info(`Renaming file from ${file.oldUri.fsPath} to ${file.newUri.fsPath}`); - this.graph.updateId(oldId, newId); - - for(const id of this.graph.graph.nodes()){ - const node = this.graph.getNote(id); - if (node.path.includes('python')){ - console.log(node.path); - } - console.log(node.path); - } - // Adjust forward links: They have a new source - const forwardLinkTargets: string[] = this.graph.getForwardLinksAsString(newId); + const forwardLinkTargets: string[] = this.graph.getForwardLinksAsString(oldId); for(const forwardLinkTarget of forwardLinkTargets){ const oldRelativePath: string = new MarkdownLink(file.oldUri.fsPath, forwardLinkTarget).relativePath; const newRelativePath: string = new MarkdownLink(file.newUri.fsPath, forwardLinkTarget).relativePath; if(oldRelativePath !== newRelativePath){ - replaceTextInFile(file.newUri.fsPath, oldRelativePath, newRelativePath); - replaceTextInFile(file.newUri.fsPath, oldRelativePath.replace(/\//g, '\\'), newRelativePath); // we might need to replace old links with backslashes + Logger.info(`Renaming file, need to adjust forward link from ${oldRelativePath} to ${newRelativePath}`); + if (!await replaceTextInFile(file.newUri.fsPath, oldRelativePath, newRelativePath)) { + if (!await replaceTextInFile(file.newUri.fsPath, oldRelativePath.replace(/\//g, '\\'), newRelativePath)) { + Logger.warn(`Could not find text to replace in ${file.newUri.fsPath}`); + } + } } - } // Adjust backlinks: They have a new target - const backLinkTargets: string[] = this.graph.getBacklinksAsString(newId); + const backLinkTargets: string[] = this.graph.getBacklinksAsString(oldId); for(const backLinkTarget of backLinkTargets){ const oldRelativePath: string = new MarkdownLink(backLinkTarget, file.oldUri.fsPath).relativePath; const newRelativePath: string = new MarkdownLink(backLinkTarget, file.newUri.fsPath).relativePath; if(oldRelativePath !== newRelativePath){ - replaceTextInFile(backLinkTarget, oldRelativePath, newRelativePath); - replaceTextInFile(backLinkTarget, oldRelativePath.replace(/\//g, '\\'), newRelativePath); // we might need to replace old links with backslashes + Logger.info(`Renaming file, need to adjust backlink from ${oldRelativePath} to ${newRelativePath}`); + if(!await replaceTextInFile(backLinkTarget, oldRelativePath, newRelativePath)) { + if(!await replaceTextInFile(backLinkTarget, oldRelativePath.replace(/\//g, '\\'), newRelativePath)){ + Logger.warn(`Could not find text to replace in ${backLinkTarget}`); + } + } } } + Logger.info(`---`); } } } diff --git a/src/vscode/NoteActions.ts b/src/vscode/NoteActions.ts index 1dbb240..a8bbb52 100644 --- a/src/vscode/NoteActions.ts +++ b/src/vscode/NoteActions.ts @@ -1,7 +1,9 @@ -import * as vscode from 'vscode'; import * as fs from 'fs'; import * as path from 'path'; +import * as vscode from 'vscode'; + import { MarkdownLink } from '../core/Link'; +import { Logger } from '../services'; export function insertTextInCurrentNote(text: string) { const editor = vscode.window.activeTextEditor; @@ -68,14 +70,20 @@ export async function loadFileAsString(fileIdentifier: string | vscode.Uri): Pro return readStr; } -export async function replaceTextInFile(filePath: string, oldText: string, newText: string) { +/** + * Read a file, replace some text, and write it back + * Returns true if changes have been made + */ +export async function replaceTextInFile(filePath: string, oldText: string, newText: string): Promise { const content: string = await loadFileAsString(filePath); const newContent: string = content.replace(oldText, newText); if(content !== newContent) { + Logger.info(`Replacing text in file ${filePath}. Old text: "${oldText}", new text: "${newText}"`); await createNote(filePath, newContent, true); - console.log(`Replaced text in file ${filePath}: oldText "${oldText}", newText "${newText}`); + return true; + } else { + return false; } - } export function escapeRegex(str: string) {