diff --git a/src/GlobalVars.ts b/src/GlobalVars.ts new file mode 100644 index 0000000..21e8403 --- /dev/null +++ b/src/GlobalVars.ts @@ -0,0 +1,3 @@ +export class GlobalVars{ + static APP:any; +} \ No newline at end of file diff --git a/src/core/Regexp.ts b/src/core/Regexp.ts new file mode 100644 index 0000000..be9019e --- /dev/null +++ b/src/core/Regexp.ts @@ -0,0 +1,3 @@ +export const TEXT_REGEXP = /^(\s*)(.*)$/; +export const LIST_ITEM_REGEXP = /^(\s*)([*+-]|\d+\.)\s+(?!\[.?\])(.*)$/; +export const CHECKBOX_REGEXP = /^(\s*)([*+-]|\d+\.) \[(.)\]\s(.*)$/; \ No newline at end of file diff --git a/src/core/model/ContextFactory.ts b/src/core/model/ContextFactory.ts index 8221782..5d843c6 100644 --- a/src/core/model/ContextFactory.ts +++ b/src/core/model/ContextFactory.ts @@ -9,9 +9,6 @@ import { TextLine } from "./line/TextLine"; export class ContextFactory { - static readonly CHECKBOX_REGEXP = /^(\s*)([*+-]|\d+\.) \[(.)\]\s(.*)$/; - static readonly LIST_ITEM_REGEXP = /^(\s*)([*+-]|\d+\.)\s+(?!\[.?\])(.*)$/; - static readonly TEXT_REGEXP = /^(\s*)(.*)$/; private constructor() { } @@ -110,31 +107,18 @@ export class ContextFactory { } // создаёт объект из одного из классов, кто реализует Line в зависимости от строки. - static createLineFromTextLine(textLine: string, settings: Readonly): Line { - const checkboxMatch = textLine.match(this.CHECKBOX_REGEXP); - if (checkboxMatch) { - const indentString = checkboxMatch[1]; - const marker = checkboxMatch[2]; - const checkChar = checkboxMatch[3]; - - const listItemText = checkboxMatch[4].trimStart(); - - return new CheckboxLine(indentString, marker, checkChar, listItemText, settings); + static createLineFromTextLine(stringLine: string, settings: Readonly): Line { + const checkboxLine = CheckboxLine.createFromLine(stringLine, settings); + if (checkboxLine) { + return checkboxLine; } - const listItemMatch = textLine.match(this.LIST_ITEM_REGEXP); - if (listItemMatch) { - const indentString = listItemMatch[1]; - const marker = listItemMatch[2]; - const listItemText = listItemMatch[3].trimStart(); - - return new ListLine(indentString, marker, listItemText, settings.tabSize); + const listLine = ListLine.createFromLine(stringLine, settings); + if (listLine) { + return listLine; } - const textLineMatch = textLine.match(this.TEXT_REGEXP)!; - const indentString = textLineMatch[1]; - const itemText = textLineMatch[2]; - return new TextLine(indentString, itemText, settings.tabSize); - + const textLine = TextLine.createFromLine(stringLine, settings)!; + return textLine; } private static findSingleDiffLineIndex(lines1: string[], lines2: string[]): number | undefined { diff --git a/src/core/model/line/AbstractLine.ts b/src/core/model/line/AbstractLine.ts index 19a9bf3..3ad2150 100644 --- a/src/core/model/line/AbstractLine.ts +++ b/src/core/model/line/AbstractLine.ts @@ -1,4 +1,4 @@ -import { CheckboxState } from "src/types"; +import { CheckboxState, CheckboxSyncPluginSettings } from "src/types"; import { Line } from "../Line"; export abstract class AbstractLine implements Line { @@ -10,12 +10,12 @@ export abstract class AbstractLine implements Line { // текст после чекбокса protected listText: string; - constructor(indentString: string, lineText: string, tabSize: number) { + constructor(indentString: string, lineText: string, settings: Readonly) { this.indentString = indentString; this.listText = lineText; - this.tabSize = tabSize; + this.tabSize = settings.tabSize; - this.indent = this.getIndentFromString(indentString, tabSize); + this.indent = this.getIndentFromString(indentString, this.tabSize); } private getIndentFromString(indentString: string, tabSize: number): number { diff --git a/src/core/model/line/CheckboxLine.ts b/src/core/model/line/CheckboxLine.ts index 00b9e9e..e54fc5e 100644 --- a/src/core/model/line/CheckboxLine.ts +++ b/src/core/model/line/CheckboxLine.ts @@ -1,5 +1,7 @@ import { CheckboxState, CheckboxSyncPluginSettings } from "src/types"; import { AbstractLine } from "./AbstractLine"; +import { GlobalVars } from "src/GlobalVars"; +import { CHECKBOX_REGEXP } from "src/core/Regexp"; export class CheckboxLine extends AbstractLine { @@ -19,8 +21,8 @@ export class CheckboxLine extends AbstractLine { protected settings: Readonly; - constructor(indentString:string, marker: string, checkChar: string, listItemText: string, settings: Readonly) { - super(indentString, listItemText, settings.tabSize); + constructor(indentString: string, marker: string, checkChar: string, listItemText: string, settings: Readonly) { + super(indentString, listItemText, settings); this.marker = marker; this.checkChar = checkChar; this.settings = settings; @@ -29,6 +31,18 @@ export class CheckboxLine extends AbstractLine { this.checkboxState = this.getCheckboxState(checkChar); } + static createFromLine(textLine: string, settings: Readonly): CheckboxLine | null { + const checkboxMatch = textLine.match(CHECKBOX_REGEXP); + if (checkboxMatch) { + const indentString = checkboxMatch[1]; + const marker = checkboxMatch[2]; + const checkChar = checkboxMatch[3]; + const listItemText = checkboxMatch[4].trimStart(); + return new CheckboxLine(indentString, marker, checkChar, listItemText, settings); + } + return null; + } + isChange(): boolean { return this.hasChange; } @@ -38,7 +52,35 @@ export class CheckboxLine extends AbstractLine { } + private static getNewCheckboxLineFromTasksApi(api: any, checkboxLine: CheckboxLine, targetState: CheckboxState): CheckboxLine|null { + let line: CheckboxLine | null = checkboxLine; + const startChar = checkboxLine.checkChar; + while (true) { + const textLine = line.toResultText(); + const newTextLine = api.executeToggleTaskDoneCommand(textLine, null); + const newBox = CheckboxLine.createFromLine(newTextLine, line.settings); + if (!newBox) { + return null; + } + if (newBox.checkboxState === targetState){ + return newBox; + } + if (newBox.checkChar === startChar){ + return null; + } + line = newBox; + } + } + setState(state: CheckboxState): void { + const taskPlugin = GlobalVars.APP?.plugins.plugins['obsidian-tasks-plugin']; + if (taskPlugin) { + const api = taskPlugin.apiV1; + const res = CheckboxLine.getNewCheckboxLineFromTasksApi(api, this, state); + if (res !== null){ + this.listText = res.listText; + } + } // обновить checkboxState this.checkboxState = state; // обновить checkChar diff --git a/src/core/model/line/ListLine.ts b/src/core/model/line/ListLine.ts index 87b5c61..e1c2474 100644 --- a/src/core/model/line/ListLine.ts +++ b/src/core/model/line/ListLine.ts @@ -1,16 +1,28 @@ -import { CheckboxState } from "src/types"; +import { CheckboxState, CheckboxSyncPluginSettings } from "src/types"; import { AbstractLine } from "./AbstractLine"; +import { LIST_ITEM_REGEXP } from "src/core/Regexp"; export class ListLine extends AbstractLine { // символы перед текстом private marker: string; - constructor(indentString: string, marker: string, listText: string, tabSize: number) { - super(indentString, listText, tabSize); + constructor(indentString: string, marker: string, listText: string, settings: Readonly) { + super(indentString, listText, settings); this.marker = marker; } + static createFromLine(textLine: string, settings: Readonly): ListLine | null { + const listItemMatch = textLine.match(LIST_ITEM_REGEXP); + if (listItemMatch) { + const indentString = listItemMatch[1]; + const marker = listItemMatch[2]; + const listItemText = listItemMatch[3].trimStart(); + return new ListLine(indentString, marker, listItemText, settings); + } + return null; + } + getMarker(): string { return this.marker; } diff --git a/src/core/model/line/TextLine.ts b/src/core/model/line/TextLine.ts index e56ea53..2fe01cc 100644 --- a/src/core/model/line/TextLine.ts +++ b/src/core/model/line/TextLine.ts @@ -1,7 +1,19 @@ -import { CheckboxState } from "src/types"; +import { CheckboxState, CheckboxSyncPluginSettings } from "src/types"; import { AbstractLine } from "./AbstractLine"; +import { TEXT_REGEXP } from "src/core/Regexp"; export class TextLine extends AbstractLine { + + + static createFromLine(textLine: string, settings: Readonly): TextLine | null { + const textLineMatch = textLine.match(TEXT_REGEXP); + if (textLineMatch) { + const indentString = textLineMatch[1]; + const itemText = textLineMatch[2]; + return new TextLine(indentString, itemText, settings); + } + return null; + } toResultText(): string { // const spaces = ' '.repeat(this.indent); const resultText = this.indentString + this.listText; diff --git a/src/main.ts b/src/main.ts index c240324..ce2e31b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,6 +9,7 @@ import { FileFilter } from "./FileFilter"; import TextSyncPipeline from "./TextSyncPipeline"; import { ICheckboxUtils } from "./core/interface/ICheckboxUtils"; import { CheckboxUtils2 } from "./core/CheckboxUtils2"; +import { GlobalVars } from "./GlobalVars"; const DEBUG_FLAG_NAME = 'CHECKBOX_SYNC_DEBUG'; @@ -32,12 +33,13 @@ export default class CheckboxSyncPlugin extends Plugin { private textSyncPipeline: TextSyncPipeline; async onload() { + GlobalVars.APP = this.app; await this.loadSettings(); this.fileFilter = new FileFilter(this.settings); this.fileStateHolder = new FileStateHolder(this.app.vault); this.checkboxUtils = new CheckboxUtils2(this.settings); - this.textSyncPipeline = new TextSyncPipeline(this.checkboxUtils,this.fileStateHolder, this.fileFilter); + this.textSyncPipeline = new TextSyncPipeline(this.checkboxUtils, this.fileStateHolder, this.fileFilter); this.syncController = new SyncController(this.app.vault, this.textSyncPipeline); this.fileLoadEventHandler = new FileLoadEventHandler(this, this.app, this.syncController, this.fileStateHolder); this.fileChangeEventHandler = new FileChangeEventHandler(this, this.app, this.syncController, this.fileStateHolder); @@ -62,7 +64,7 @@ export default class CheckboxSyncPlugin extends Plugin { this.fileFilter.updateSettings(this.settings); await this.saveData(this.settings); - + if (this.settings.enableAutomaticFileSync) { //надо пересинхронизировать все файлы в кеше