mirror of
https://github.com/kdnk/obsidian-automatic-linker.git
synced 2026-07-22 05:37:46 +00:00
feat: refresh Trie on frontmatter changes
This commit is contained in:
parent
d9e405224b
commit
d1afdd25db
2 changed files with 84 additions and 13 deletions
36
src/frontmatter-utils.ts
Normal file
36
src/frontmatter-utils.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* Check if the file has the "off" frontmatter property
|
||||
*/
|
||||
export const isLinkingOff = (
|
||||
frontmatter: Record<string, unknown> | undefined,
|
||||
): boolean => {
|
||||
return (
|
||||
frontmatter?.["automatic-linker-disabled"] === true ||
|
||||
frontmatter?.["automatic-linker-off"] === true
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the file has the "scoped" frontmatter property
|
||||
*/
|
||||
export const isNamespaceScoped = (
|
||||
frontmatter: Record<string, unknown> | undefined,
|
||||
): boolean => {
|
||||
return (
|
||||
frontmatter?.["automatic-linker-restrict-namespace"] === true ||
|
||||
frontmatter?.["automatic-linker-limited-namespace"] === true ||
|
||||
frontmatter?.["automatic-linker-scoped"] === true
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the file has the "exclude" frontmatter property
|
||||
*/
|
||||
export const isLinkingExcluded = (
|
||||
frontmatter: Record<string, unknown> | undefined,
|
||||
): boolean => {
|
||||
return (
|
||||
frontmatter?.["automatic-linker-prevent-linking"] === true ||
|
||||
frontmatter?.["automatic-linker-exclude"] === true
|
||||
);
|
||||
};
|
||||
61
src/main.ts
61
src/main.ts
|
|
@ -11,6 +11,11 @@ import {
|
|||
TFile,
|
||||
} from "obsidian";
|
||||
import { excludeLinks } from "./exclude-links";
|
||||
import {
|
||||
isLinkingOff,
|
||||
isLinkingExcluded,
|
||||
isNamespaceScoped,
|
||||
} from "./frontmatter-utils";
|
||||
import { PathAndAliases } from "./path-and-aliases.types";
|
||||
import { removeMinimalIndent } from "./remove-minimal-indent";
|
||||
import {
|
||||
|
|
@ -45,6 +50,8 @@ export default class AutomaticLinkerPlugin extends Plugin {
|
|||
// Preserved callback for the original save command
|
||||
private originalSaveCallback: (checking: boolean) => boolean | void;
|
||||
private urlTitleMap: Map<string, string> = new Map();
|
||||
// Cache of frontmatter values that affect the Trie
|
||||
private frontmatterCache: Map<string, string> = new Map();
|
||||
|
||||
constructor(app: App, pluginManifest: PluginManifest) {
|
||||
super(app, pluginManifest);
|
||||
|
|
@ -193,10 +200,7 @@ export default class AutomaticLinkerPlugin extends Plugin {
|
|||
|
||||
const metadata =
|
||||
this.app.metadataCache.getFileCache(activeFile)?.frontmatter;
|
||||
const off =
|
||||
metadata?.["automatic-linker-disabled"] === true ||
|
||||
metadata?.["automatic-linker-off"] === true;
|
||||
if (off) {
|
||||
if (isLinkingOff(metadata)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -326,16 +330,9 @@ export default class AutomaticLinkerPlugin extends Plugin {
|
|||
const path = file.path.replace(/\.md$/, "");
|
||||
const metadata =
|
||||
this.app.metadataCache.getFileCache(file)?.frontmatter;
|
||||
const scoped =
|
||||
metadata?.["automatic-linker-restrict-namespace"] ===
|
||||
true ||
|
||||
metadata?.["automatic-linker-limited-namespace"] === true ||
|
||||
metadata?.["automatic-linker-scoped"] === true;
|
||||
|
||||
const scoped = isNamespaceScoped(metadata);
|
||||
// if this property exists, prevent this file from being linked from other files
|
||||
const exclude =
|
||||
metadata?.["automatic-linker-prevent-linking"] === true ||
|
||||
metadata?.["automatic-linker-exclude"] === true;
|
||||
const exclude = isLinkingExcluded(metadata);
|
||||
|
||||
const aliases = (() => {
|
||||
if (this.settings.considerAliases) {
|
||||
|
|
@ -378,6 +375,9 @@ export default class AutomaticLinkerPlugin extends Plugin {
|
|||
this.candidateMap = candidateMap;
|
||||
this.trie = trie;
|
||||
|
||||
// Clear frontmatter cache when Trie is rebuilt
|
||||
this.frontmatterCache.clear();
|
||||
|
||||
if (this.settings.showNotice) {
|
||||
new Notice(
|
||||
`Automatic Linker: Loaded all markdown files. (${allFiles.length} files)`,
|
||||
|
|
@ -390,6 +390,36 @@ export default class AutomaticLinkerPlugin extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
private refreshFileDataAndTrieOnFrontmatterChange(file: TFile) {
|
||||
const metadata =
|
||||
this.app.metadataCache.getFileCache(file)?.frontmatter;
|
||||
|
||||
// Extract frontmatter fields that affect the Trie
|
||||
const relevantFields = {
|
||||
aliases: metadata?.aliases
|
||||
? JSON.stringify(metadata.aliases)
|
||||
: undefined,
|
||||
scoped: isNamespaceScoped(metadata),
|
||||
exclude: isLinkingExcluded(metadata),
|
||||
};
|
||||
|
||||
// Create a hash of the relevant fields
|
||||
const currentHash = JSON.stringify(relevantFields);
|
||||
const cachedHash = this.frontmatterCache.get(file.path);
|
||||
|
||||
// If the hash has changed, refresh the Trie
|
||||
if (currentHash !== cachedHash) {
|
||||
this.frontmatterCache.set(file.path, currentHash);
|
||||
this.refreshFileDataAndTrie();
|
||||
|
||||
if (this.settings.debug) {
|
||||
console.log(
|
||||
`Automatic Linker: Refreshing Trie due to frontmatter change in ${file.path}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async onload() {
|
||||
await this.loadSettings();
|
||||
this.addSettingTab(
|
||||
|
|
@ -415,6 +445,11 @@ export default class AutomaticLinkerPlugin extends Plugin {
|
|||
this.refreshFileDataAndTrie(),
|
||||
),
|
||||
);
|
||||
this.registerEvent(
|
||||
this.app.metadataCache.on("changed", (file) =>
|
||||
this.refreshFileDataAndTrieOnFrontmatterChange(file),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
// Command: Manually trigger link replacement for the current file.
|
||||
|
|
|
|||
Loading…
Reference in a new issue