diff --git a/src/obsidian/settings/settingTab.ts b/src/obsidian/settings/settingTab.ts index 6138c33..913161f 100644 --- a/src/obsidian/settings/settingTab.ts +++ b/src/obsidian/settings/settingTab.ts @@ -2,6 +2,8 @@ import { debounce, Notice, PluginSettingTab, Setting } from "obsidian"; import { getLocale, LOCALE_CATEGORY } from "@src/lang/lang"; +import { FALLBACK_SETTINGS } from "./settingTypes"; + import type { App } from "obsidian"; import type FormattoPlugin from "@src/main"; @@ -27,6 +29,10 @@ export class FormattoSettingTab extends PluginSettingTab { return value !== "0" && value !== "1" && parseFloat(value) % 1 !== 0; } + private putDefaultIndicator(value: string): string { + return `${value} (Default)`; + } + display(): void { const { containerEl } = this; containerEl.empty(); @@ -69,7 +75,11 @@ export class FormattoSettingTab extends PluginSettingTab { ) .addText((text) => text - .setPlaceholder("3") + .setPlaceholder( + this.putDefaultIndicator( + FALLBACK_SETTINGS.headingGaps.beforeTopLevelHeadings + ) + ) .setValue( this.plugin.settings.headingGaps.beforeTopLevelHeadings ) @@ -96,7 +106,11 @@ export class FormattoSettingTab extends PluginSettingTab { ) .addText((text) => text - .setPlaceholder("1") + .setPlaceholder( + this.putDefaultIndicator( + FALLBACK_SETTINGS.headingGaps.beforeFirstSubHeading + ) + ) .setValue( this.plugin.settings.headingGaps.beforeFirstSubHeading ) @@ -120,7 +134,11 @@ export class FormattoSettingTab extends PluginSettingTab { ) .addText((text) => text - .setPlaceholder("2") + .setPlaceholder( + this.putDefaultIndicator( + FALLBACK_SETTINGS.headingGaps.beforeSubHeadings + ) + ) .setValue( this.plugin.settings.headingGaps.beforeSubHeadings ) @@ -147,7 +165,11 @@ export class FormattoSettingTab extends PluginSettingTab { ) .addText((text) => text - .setPlaceholder("2") + .setPlaceholder( + this.putDefaultIndicator( + FALLBACK_SETTINGS.otherGaps.afterProperties + ) + ) .setValue(this.plugin.settings.otherGaps.afterProperties) .onChange(async (value) => { debounceMsg(value); @@ -166,7 +188,11 @@ export class FormattoSettingTab extends PluginSettingTab { ) .addText((text) => text - .setPlaceholder("0") + .setPlaceholder( + this.putDefaultIndicator( + FALLBACK_SETTINGS.otherGaps.beforeContents + ) + ) .setValue(this.plugin.settings.otherGaps.beforeContents) .onChange(async (value) => { debounceMsg(value); @@ -190,7 +216,12 @@ export class FormattoSettingTab extends PluginSettingTab { ) .addText((text) => text - .setPlaceholder("1") + .setPlaceholder( + this.putDefaultIndicator( + FALLBACK_SETTINGS.otherGaps + .beforeContentsAfterCodeBlocks + ) + ) .setValue( this.plugin.settings.otherGaps .beforeContentsAfterCodeBlocks @@ -215,7 +246,11 @@ export class FormattoSettingTab extends PluginSettingTab { ) .addText((text) => text - .setPlaceholder("1") + .setPlaceholder( + this.putDefaultIndicator( + FALLBACK_SETTINGS.otherGaps.beforeCodeBlocks + ) + ) .setValue(this.plugin.settings.otherGaps.beforeCodeBlocks) .onChange(async (value) => { debounceMsg(value); @@ -239,7 +274,12 @@ export class FormattoSettingTab extends PluginSettingTab { ) .addText((text) => text - .setPlaceholder("0") + .setPlaceholder( + this.putDefaultIndicator( + FALLBACK_SETTINGS.otherGaps + .beforeCodeBlocksAfterHeadings + ) + ) .setValue( this.plugin.settings.otherGaps .beforeCodeBlocksAfterHeadings diff --git a/src/obsidian/settings/settingTypes.ts b/src/obsidian/settings/settingTypes.ts index 6d9f6ac..33340ea 100644 --- a/src/obsidian/settings/settingTypes.ts +++ b/src/obsidian/settings/settingTypes.ts @@ -1,3 +1,7 @@ +/* + Type Declarations +*/ + export interface HeadingGaps { /** Decides gaps before top level of headings. */ beforeTopLevelHeadings: string; @@ -39,17 +43,17 @@ export interface FormattoPluginSettings { otherOptions: Partial; } -// `Partial` is a TypeScript utility that returns a type with all properties of Type set to optional. -// It enables type checking while letting you only define the properties you want to provide defaults for. -// Source : https://docs.obsidian.md/Plugins/User+interface/Settings#Provide+default+values +/* + Fallback Option Values +*/ -export const DEFAULT_HEADING_GAPS: Partial = { +export const FALLBACK_HEADING_GAPS: Partial = { beforeTopLevelHeadings: "3", beforeFirstSubHeading: "1", beforeSubHeadings: "2", }; -export const DEFAULT_OTHER_GAPS: Partial = { +export const FALLBACK_OTHER_GAPS: Partial = { afterProperties: "2", beforeContents: "0", beforeContentsAfterCodeBlocks: "1", @@ -57,18 +61,43 @@ export const DEFAULT_OTHER_GAPS: Partial = { beforeCodeBlocksAfterHeadings: "0", }; -export const DEFAULT_FORMAT_OPTIONS: Partial = { +export const FALLBACK_FORMAT_OPTIONS: Partial = { insertNewline: true, }; -export const DEFAULT_OTHER_OPTIONS: Partial = { +export const FALLBACK_OTHER_OPTIONS: Partial = { notifyWhenUnchanged: true, showMoreDetailedErrorMessages: false, }; +export const FALLBACK_SETTINGS: FormattoPluginSettings = { + headingGaps: FALLBACK_HEADING_GAPS, + otherGaps: FALLBACK_OTHER_GAPS, + formatOptions: FALLBACK_FORMAT_OPTIONS, + otherOptions: FALLBACK_OTHER_OPTIONS, +}; + +/* + Default Option Values +*/ + +export const EMPTY_HEADING_GAPS: Partial = { + beforeTopLevelHeadings: "", + beforeFirstSubHeading: "", + beforeSubHeadings: "", +}; + +export const EMPTY_OTHER_GAPS: Partial = { + afterProperties: "", + beforeContents: "", + beforeContentsAfterCodeBlocks: "", + beforeCodeBlocks: "", + beforeCodeBlocksAfterHeadings: "", +}; + export const DEFAULT_SETTINGS: FormattoPluginSettings = { - headingGaps: DEFAULT_HEADING_GAPS, - otherGaps: DEFAULT_OTHER_GAPS, - formatOptions: DEFAULT_FORMAT_OPTIONS, - otherOptions: DEFAULT_OTHER_OPTIONS, + headingGaps: EMPTY_HEADING_GAPS, + otherGaps: EMPTY_OTHER_GAPS, + formatOptions: FALLBACK_FORMAT_OPTIONS, + otherOptions: FALLBACK_OTHER_OPTIONS, }; diff --git a/src/obsidian/utils.ts b/src/obsidian/utils.ts index 2588244..437cede 100644 --- a/src/obsidian/utils.ts +++ b/src/obsidian/utils.ts @@ -1,41 +1,56 @@ -import { Editor, Notice } from "obsidian"; +import { Editor, EditorPosition, Notice } from "obsidian"; import { getLocale, getWasmLocale, LOCALE_CATEGORY } from "@src/lang/lang"; import FormattoPlugin from "@src/main"; import { format_document } from "../../wasm/pkg/formatto_wasm"; +import { + FALLBACK_SETTINGS, + FormattoPluginSettings, +} from "./settings/settingTypes"; export class FormattoUtils { private plugin: FormattoPlugin; + private cursorPosition: EditorPosition; + private originalDocument: string; + private formattedDocument: string; constructor(plugin: FormattoPlugin) { this.plugin = plugin; } formatDocument(editor: Editor) { - const cursorPosition = editor.getCursor(); - const originalDocument = editor.getValue(); + const copiedSettings = JSON.parse(JSON.stringify(this.plugin.settings)); + this.handleEmptyOptions(copiedSettings); + + this.cursorPosition = editor.getCursor(); + this.originalDocument = editor.getValue(); - let formattedDocument: string; try { - formattedDocument = format_document( - originalDocument, - this.plugin.settings, + this.formattedDocument = format_document( + this.originalDocument, + copiedSettings, JSON.stringify(getWasmLocale()) ); } catch (error) { new Notice(error); } - if (!formattedDocument) return; - if (formattedDocument !== originalDocument) { - editor.setValue(formattedDocument); - editor.setSelection(cursorPosition, cursorPosition); + this.displayMessage(); + + if (!this.formattedDocument) return; + if (this.formattedDocument !== this.originalDocument) { + editor.setValue(this.formattedDocument); + editor.setSelection(this.cursorPosition, this.cursorPosition); } + this.clearVariables(); + } + + private displayMessage() { if ( this.plugin.settings.otherOptions.notifyWhenUnchanged && - formattedDocument === originalDocument + this.formattedDocument === this.originalDocument ) { new Notice( getLocale( @@ -52,4 +67,23 @@ export class FormattoUtils { ); } } + + private handleEmptyOptions(copiedSettings: FormattoPluginSettings) { + for (const optionSection of Object.keys(copiedSettings)) { + for (const optionKey of Object.keys( + copiedSettings[optionSection] + )) { + if (copiedSettings[optionSection][optionKey] === "") { + copiedSettings[optionSection][optionKey] = + FALLBACK_SETTINGS[optionSection][optionKey]; + } + } + } + } + + private clearVariables() { + this.cursorPosition = undefined; + this.originalDocument = undefined; + this.formattedDocument = undefined; + } }