diff --git a/manifest.json b/manifest.json index f385cf6..882586e 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "checkbox-sync", "name": "Checkbox Sync", - "version": "1.0.5", + "version": "1.0.6", "minAppVersion": "0.12.0", "description": "Automatically checks the parent checkbox if all child checkboxes are completed, and unchecks it otherwise.", "author": "Grol", diff --git a/src/CheckboxManager.ts b/src/CheckboxManager.ts new file mode 100644 index 0000000..71a9027 --- /dev/null +++ b/src/CheckboxManager.ts @@ -0,0 +1,54 @@ +import { Editor, TFile } from "obsidian"; +import CheckboxSyncPlugin from "./main"; + +export default class CheckboxManager { + private plugin: CheckboxSyncPlugin; + private isProcessingFile = false; + constructor(plugin: CheckboxSyncPlugin) { + this.plugin = plugin; + } + + async syncEditor(editor: Editor) { + await this.syncEditorCheckboxes(editor); + } + + async syncFile(file: any) { + if (this.isProcessingFile || !(file instanceof TFile) || file.extension !== "md") return; + this.isProcessingFile = true; + try { + await this.syncFileCheckboxes(file); + } finally { + this.isProcessingFile = false; + } + } + + private async syncEditorCheckboxes(editor: Editor) { + const updates = this.plugin.checkboxUtils.syncCheckboxes(editor.getValue()); + if (updates.length === 0) return; + + const firstUpdateLine = updates[0].line; + editor.setCursor({ line: firstUpdateLine, ch: editor.getLine(firstUpdateLine).length }); + editor.blur(); + + updates.forEach(({ line, ch, value }) => { + editor.replaceRange(value, { line, ch }, { line, ch: ch + 1 }); + }); + } + + private async syncFileCheckboxes(file: TFile) { + let text = await this.plugin.app.vault.read(file); + let updates = this.plugin.checkboxUtils.syncCheckboxes(text); + if (updates.length === 0) return; + + while (true) { + const lines = text.split("\n"); + updates.forEach(({ line, ch, value }) => { + lines[line] = lines[line].substring(0, ch) + value + lines[line].substring(ch + 1); + }); + text = lines.join("\n"); + updates = this.plugin.checkboxUtils.syncCheckboxes(text); + if (updates.length === 0) break; + } + await this.plugin.app.vault.modify(file, text); + } +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index bd3dad1..b56981f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,6 +2,7 @@ import { Plugin, TFile } from "obsidian"; import { CheckboxUtils } from "./checkboxUtils"; import { CheckboxSyncPluginSettingTab } from "./CheckboxSyncPluginSettingTab"; import { CheckboxSyncPluginSettings } from "./types"; +import CheckboxManager from "./CheckboxManager"; const DEFAULT_SETTINGS: CheckboxSyncPluginSettings = { xOnlyMode: true, @@ -10,67 +11,30 @@ const DEFAULT_SETTINGS: CheckboxSyncPluginSettings = { export default class CheckboxSyncPlugin extends Plugin { settings: CheckboxSyncPluginSettings; - private isProcessing = false; + checkboxManager: CheckboxManager; checkboxUtils: CheckboxUtils; async onload() { await this.loadSettings(); + this.checkboxUtils = new CheckboxUtils(this.settings); + this.checkboxManager = new CheckboxManager(this); + this.addSettingTab(new CheckboxSyncPluginSettingTab(this.app, this)); + //запуск плагина при открытии файла this.registerEvent( - this.app.workspace.on("file-open", async (file) => { - if (this.isProcessing || !(file instanceof TFile) || file.extension !== "md") return; - - this.isProcessing = true; - try { - await this.syncFileCheckboxes(file); - } finally { - this.isProcessing = false; - } - }) + this.app.workspace.on("file-open", async (file) => await this.checkboxManager.syncFile(file)) + ); + //запуск плагина при модификации файла(для обработки в режиме просмотра) + this.registerEvent( + this.app.vault.on("modify", async (file) => await this.checkboxManager.syncFile(file)) + ); + //запуск плагина при изменении в режиме редактора + this.registerEvent( + this.app.workspace.on("editor-change", async (editor) => await this.checkboxManager.syncEditor(editor)) ); - this.registerEvent( - this.app.workspace.on("editor-change", (editor) => { - const updates = this.checkboxUtils.syncCheckboxes(editor.getValue()); - if (updates.length === 0) return; - - const firstUpdateLine = updates[0].line; - editor.setCursor({ line: firstUpdateLine, ch: editor.getLine(firstUpdateLine).length }); - editor.blur(); - - updates.forEach(({ line, ch, value }) => { - editor.replaceRange(value, { line, ch }, { line, ch: ch + 1 }); - }); - }) - ); - this.registerEvent( - this.app.vault.on("modify", async (file) => { - if (this.isProcessing || !(file instanceof TFile) || file.extension !== "md") return; - - this.isProcessing = true; - try { - await this.syncFileCheckboxes(file); - } finally { - this.isProcessing = false; - } - }) - ); - } - - async syncFileCheckboxes(file: TFile) { - const text = await this.app.vault.read(file); - const updates = this.checkboxUtils.syncCheckboxes(text); - if (updates.length === 0) return; - - const lines = text.split("\n"); - updates.forEach(({ line, ch, value }) => { - lines[line] = lines[line].substring(0, ch) + value + lines[line].substring(ch + 1); - }); - - const updatedText = lines.join("\n"); - await this.app.vault.modify(file, updatedText); } async loadSettings() { @@ -80,10 +44,7 @@ export default class CheckboxSyncPlugin extends Plugin { async saveSettings() { await this.saveData(this.settings); this.checkboxUtils.updateSettings(this.settings); - const activeFile = this.app.workspace.getActiveFile(); - if (activeFile instanceof TFile && activeFile.extension === "md") { - await this.syncFileCheckboxes(activeFile); - } + await this.checkboxManager.syncFile(activeFile); } } \ No newline at end of file