@@ -129,69 +129,13 @@ export default class LinterPlugin extends Plugin {
129129 setLogLevel ( this . settings . logLevel ) ;
130130 await this . setOrUpdateMomentInstance ( ) ;
131131
132- let updateMade = false ;
133- if ( ! this . settings . settingsConvertedToConfigKeyValues ) {
134- updateMade = await this . moveConfigValuesToKeyBasedFormat ( ) ;
135- }
136-
137- if ( 'lintOnFileContentChangeDelay' in this . settings ) {
138- this . settings . ruleConfigs [ 'yaml-timestamp' ] [ 'update-on-file-contents-updated' ] = this . settings [ 'lintOnFileContentChangeDelay' ] ;
139-
140- delete this . settings [ 'lintOnFileContentChangeDelay' ] ;
141- updateMade = true ;
142- }
143-
144- // make sure to load the defaults of any missing rules to make sure they do not cause issues on the settings page
145- for ( const rule of rules ) {
146- if ( ! this . settings . ruleConfigs [ rule . alias ] ) {
147- this . settings . ruleConfigs [ rule . alias ] = rule . getDefaultOptions ( ) ;
148- }
149-
150- // remove this after a reasonable amount of time
151- if ( rule . alias == 'space-between-chinese-japanese-or-korean-and-english-or-numbers' ) {
152- const defaults = rule . getDefaultOptions ( ) ;
153- if ( ! ( 'english-symbols-punctuation-before' in this . settings . ruleConfigs [ rule . alias ] ) ) {
154- this . settings . ruleConfigs [ rule . alias ] [ 'english-symbols-punctuation-before' ] = defaults [ 'english-symbols-punctuation-before' ] ;
155- updateMade = true ;
156- }
157-
158- if ( ! ( 'english-symbols-punctuation-after' in this . settings . ruleConfigs [ rule . alias ] ) ) {
159- this . settings . ruleConfigs [ rule . alias ] [ 'english-symbols-punctuation-after' ] = defaults [ 'english-symbols-punctuation-after' ] ;
160- updateMade = true ;
161- }
162- } else if ( rule . alias == 'yaml-timestamp' ) {
163- const defaults = rule . getDefaultOptions ( ) ;
164- if ( 'force-retention-of-create-value' in this . settings . ruleConfigs [ rule . alias ] ) {
165- if ( ! ( 'date-created-source-of-truth' in this . settings . ruleConfigs [ rule . alias ] ) ) {
166- if ( this . settings . ruleConfigs [ rule . alias ] [ 'force-retention-of-create-value' ] ) {
167- this . settings . ruleConfigs [ rule . alias ] [ 'date-created-source-of-truth' ] = 'frontmatter' ;
168- } else {
169- this . settings . ruleConfigs [ rule . alias ] [ 'date-created-source-of-truth' ] = defaults [ 'date-created-source-of-truth' ] ;
170- }
171- }
172-
173- delete this . settings . ruleConfigs [ rule . alias ] [ 'force-retention-of-create-value' ] ;
174- updateMade = true ;
175- }
176-
177- if ( ! ( 'date-modified-source-of-truth' in this . settings . ruleConfigs [ rule . alias ] ) ) {
178- this . settings . ruleConfigs [ rule . alias ] [ 'date-modified-source-of-truth' ] = defaults [ 'date-modified-source-of-truth' ] ;
179- updateMade = true ;
180- }
181- }
182- }
183-
184132 this . updatePasteOverrideStatus ( ) ;
185133 this . updateHasCustomCommandStatus ( ) ;
186-
187- if ( updateMade ) {
188- await this . saveSettings ( ) ;
189- }
190134 }
191135
192136 async saveSettings ( ) {
193137 if ( ! this . hasLoadedMisspellingFiles ) {
194- await this . loadAutoCorrectFiles ( ) ;
138+ await this . loadAutoCorrectFiles ( false ) ;
195139 }
196140
197141 await this . saveData ( this . settings ) ;
@@ -328,7 +272,8 @@ export default class LinterPlugin extends Plugin {
328272 this . eventRefs . push ( eventRef ) ;
329273
330274 this . app . workspace . onLayoutReady ( async ( ) => {
331- await this . loadAutoCorrectFiles ( ) ;
275+ await this . makeSureSettingsFilledInAndCleanupSettings ( ) ;
276+ await this . loadAutoCorrectFiles ( true ) ;
332277 } ) ;
333278
334279 // Source for save setting
@@ -375,13 +320,17 @@ export default class LinterPlugin extends Plugin {
375320 }
376321 }
377322
378- async loadAutoCorrectFiles ( ) {
323+ async loadAutoCorrectFiles ( isOnload : boolean ) {
379324 const customAutoCorrectSettings = this . settings . ruleConfigs [ 'auto-correct-common-misspellings' ] ;
380325 if ( ! customAutoCorrectSettings || ! customAutoCorrectSettings . enabled ) {
381326 return ;
382327 }
383328
384329 await downloadMisspellings ( this , async ( message : string ) => {
330+ if ( isOnload ) {
331+ message = 'Obsidian Linter:\n' + message ;
332+ }
333+
385334 new Notice ( message ) ;
386335
387336 this . settings . ruleConfigs [ 'auto-correct-common-misspellings' ] . enabled = false ;
@@ -619,6 +568,109 @@ export default class LinterPlugin extends Plugin {
619568 moment . locale ( oldLocale ) ;
620569 }
621570
571+ private async makeSureSettingsFilledInAndCleanupSettings ( ) {
572+ let updateMade = false ;
573+
574+ // migrate settings over to the new format if they are using the now deprecated format that uses
575+ // actual settings names for the key in the json
576+ if ( ! this . settings . settingsConvertedToConfigKeyValues ) {
577+ updateMade = await this . moveConfigValuesToKeyBasedFormat ( ) ;
578+ }
579+
580+ // move a recently moved setting to its new location
581+ if ( 'lintOnFileContentChangeDelay' in this . settings ) {
582+ this . settings . ruleConfigs [ 'yaml-timestamp' ] [ 'update-on-file-contents-updated' ] = this . settings [ 'lintOnFileContentChangeDelay' ] ;
583+
584+ delete this . settings [ 'lintOnFileContentChangeDelay' ] ;
585+ updateMade = true ;
586+ }
587+
588+ // check for and fix invalid settings
589+ let noticeText = 'Obsidian Linter:' ;
590+ let conflictingRulePresent = false ;
591+ if ( this . settings . ruleConfigs [ 'header-increment' ] && this . settings . ruleConfigs [ 'header-increment' ] . enabled && this . settings . ruleConfigs [ 'header-increment' ] [ 'start-at-h2' ] &&
592+ this . settings . ruleConfigs [ 'file-name-heading' ] && this . settings . ruleConfigs [ 'file-name-heading' ] . enabled
593+ ) {
594+ this . settings . ruleConfigs [ 'header-increment' ] [ 'start-at-h2' ] = false ;
595+ updateMade = true ;
596+ conflictingRulePresent = true ;
597+
598+ noticeText += '\n' + getTextInLanguage ( 'disabled-conflicting-rule-notice' ) . replace ( '{NAME_1}' , getTextInLanguage ( 'rules.header-increment.start-at-h2.name' ) ) . replace ( '{NAME_2}' , getTextInLanguage ( 'rules.file-name-heading.name' ) ) ;
599+ }
600+
601+ if ( this . settings . ruleConfigs [ 'paragraph-blank-lines' ] && this . settings . ruleConfigs [ 'paragraph-blank-lines' ] . enabled &&
602+ this . settings . ruleConfigs [ 'two-spaces-between-lines-with-content' ] && this . settings . ruleConfigs [ 'two-spaces-between-lines-with-content' ] . enabled
603+ ) {
604+ this . settings . ruleConfigs [ 'paragraph-blank-lines' ] . enabled = false ;
605+ updateMade = true ;
606+
607+ if ( conflictingRulePresent ) {
608+ noticeText += '\n' ;
609+ }
610+ conflictingRulePresent = true ;
611+
612+ noticeText += '\n' + getTextInLanguage ( 'disabled-conflicting-rule-notice' ) . replace ( '{NAME_1}' , getTextInLanguage ( 'rules.paragraph-blank-lines.name' ) ) . replace ( '{NAME_2}' , getTextInLanguage ( 'rules.two-spaces-between-lines-with-content.name' ) ) ;
613+ }
614+
615+ if ( conflictingRulePresent ) {
616+ new Notice ( noticeText , userClickTimeout ) ;
617+ }
618+
619+ // make sure to load the defaults of any missing rules to make sure they do not cause issues on the settings page
620+ for ( const rule of rules ) {
621+ const ruleDefaults = rule . getDefaultOptions ( ) ;
622+ if ( ! this . settings . ruleConfigs [ rule . alias ] ) {
623+ this . settings . ruleConfigs [ rule . alias ] = ruleDefaults ;
624+ updateMade = true ;
625+ continue ;
626+ }
627+
628+ // remove this after a reasonable amount of time
629+ if ( rule . alias == 'space-between-chinese-japanese-or-korean-and-english-or-numbers' ) {
630+ if ( ! ( 'english-symbols-punctuation-before' in this . settings . ruleConfigs [ rule . alias ] ) ) {
631+ this . settings . ruleConfigs [ rule . alias ] [ 'english-symbols-punctuation-before' ] = ruleDefaults [ 'english-symbols-punctuation-before' ] ;
632+ updateMade = true ;
633+ }
634+
635+ if ( ! ( 'english-symbols-punctuation-after' in this . settings . ruleConfigs [ rule . alias ] ) ) {
636+ this . settings . ruleConfigs [ rule . alias ] [ 'english-symbols-punctuation-after' ] = ruleDefaults [ 'english-symbols-punctuation-after' ] ;
637+ updateMade = true ;
638+ }
639+ } else if ( rule . alias == 'yaml-timestamp' ) {
640+ const defaults = rule . getDefaultOptions ( ) ;
641+ if ( 'force-retention-of-create-value' in this . settings . ruleConfigs [ rule . alias ] ) {
642+ if ( ! ( 'date-created-source-of-truth' in this . settings . ruleConfigs [ rule . alias ] ) ) {
643+ if ( this . settings . ruleConfigs [ rule . alias ] [ 'force-retention-of-create-value' ] ) {
644+ this . settings . ruleConfigs [ rule . alias ] [ 'date-created-source-of-truth' ] = 'frontmatter' ;
645+ } else {
646+ this . settings . ruleConfigs [ rule . alias ] [ 'date-created-source-of-truth' ] = defaults [ 'date-created-source-of-truth' ] ;
647+ }
648+ }
649+
650+ delete this . settings . ruleConfigs [ rule . alias ] [ 'force-retention-of-create-value' ] ;
651+ updateMade = true ;
652+ }
653+
654+ if ( ! ( 'date-modified-source-of-truth' in this . settings . ruleConfigs [ rule . alias ] ) ) {
655+ this . settings . ruleConfigs [ rule . alias ] [ 'date-modified-source-of-truth' ] = defaults [ 'date-modified-source-of-truth' ] ;
656+ updateMade = true ;
657+ }
658+ }
659+
660+ // make sure new/empty settings on a rule that exists get filled in with their default value as well
661+ for ( const key of Object . keys ( ruleDefaults ) ) {
662+ if ( ! Object . hasOwn ( this . settings . ruleConfigs [ rule . alias ] , key ) ) {
663+ this . settings . ruleConfigs [ rule . alias ] [ key ] = ruleDefaults [ key ] ;
664+ updateMade = true ;
665+ }
666+ }
667+ }
668+
669+ if ( updateMade ) {
670+ await this . saveSettings ( ) ;
671+ }
672+ }
673+
622674 private createDebouncedFileUpdate ( ) : Debouncer < [ TFile , Editor ] , Promise < void > > {
623675 let delay = 5000 ;
624676 switch ( this . settings . ruleConfigs [ 'yaml-timestamp' ] [ 'update-on-file-contents-updated' ] ?? AfterFileChangeLintTimes . Never ) {
0 commit comments