groldsf_obsidian_check_plugin/src/SyncController.ts
2025-04-12 10:55:26 +03:00

94 lines
No EOL
2.9 KiB
TypeScript

import { Mutex } from "async-mutex";
import { Editor, EditorChange, MarkdownFileInfo, MarkdownView, TFile, Vault } from "obsidian";
import { CheckboxUtils } from "./checkboxUtils";
import FileStateHolder from "./FileStateHolder";
export default class SyncController {
// private plugin: CheckboxSyncPlugin;//delete
private vault: Vault;
private checkboxUtils: CheckboxUtils;
private fileStateHolder: FileStateHolder;
private mutex: Mutex;
constructor(vault: Vault, checkboxUtils: CheckboxUtils, fileStateHolder: FileStateHolder) {
// this.plugin = plugin;//delete
this.vault = vault;
this.checkboxUtils = checkboxUtils;
this.fileStateHolder = fileStateHolder;
this.mutex = new Mutex();
}
async syncEditor(editor: Editor, info: MarkdownView | MarkdownFileInfo) {
if (!info.file) {
return;
}
await this.mutex.runExclusive(() => {
const file = info.file!;
console.log(`sync editor "${file.basename}" start.`);
const text = editor.getValue();
const textBefore = this.fileStateHolder.get(file);
let newText = this.checkboxUtils.syncText(text, textBefore);
if (newText === text) {
this.fileStateHolder.set(file, newText);
console.log(`sync editor "${file.basename}" stop. new text equals old text.`);
return;
}
this.fileStateHolder.set(file, newText);
this.editEditor(editor, text, newText);
console.log(`syncEditor "${file.basename}" stop.`);
});
}
async syncFile(file: TFile | null) {
if (!(file instanceof TFile) || file.extension !== "md") {
return;
}
await this.mutex.runExclusive(async () => {
console.log(`sync file "${file.basename}" start.`);
const newText = await this.vault.process(file, (text) => {
let textBefore = this.fileStateHolder.get(file);
let newText = this.checkboxUtils.syncText(text, textBefore);
return newText;
});
this.fileStateHolder.set(file, newText);
console.log(`sync file "${file.basename}" stop.`);
});
}
private editEditor(editor: Editor, oldText: string, newText: string) {
const cursor = editor.getCursor();
const newLines = newText.split("\n");
const oldLines = oldText.split("\n");
const diffIndexes = this.checkboxUtils.findDifferentLineIndexes(oldLines, newLines);
const changes: EditorChange[] = [];
for (let ind of diffIndexes) {
changes.push({
from: { line: ind, ch: 0 },
to: { line: ind, ch: oldLines[ind].length },
text: newLines[ind]
});
}
editor.transaction({
changes: changes
});
editor.setCursor(cursor);
const lastDifferentLineIndex = diffIndexes.length > 0 ? diffIndexes[0] : -1;
if (lastDifferentLineIndex != -1) {
editor.scrollIntoView({
from: { line: lastDifferentLineIndex, ch: 0 },
to: { line: lastDifferentLineIndex, ch: 0 }
});
}
}
}