mirror of
https://github.com/kdnk/obsidian-automatic-linker.git
synced 2026-07-22 12:00:30 +00:00
perf
This commit is contained in:
parent
46e43422d9
commit
7bb4e22125
2 changed files with 31 additions and 26 deletions
|
|
@ -136,15 +136,16 @@ const normalizeCanonicalPath = (linkPath: string, baseDir?: string): string => {
|
|||
const extractLinkParts = (
|
||||
canonicalPath: string,
|
||||
): { linkPath: string; alias: string; hasAlias: boolean } => {
|
||||
const hasAlias = canonicalPath.includes("|");
|
||||
let linkPath = canonicalPath;
|
||||
let alias = "";
|
||||
|
||||
const pipeIndex = canonicalPath.indexOf("|");
|
||||
const hasAlias = pipeIndex !== -1;
|
||||
|
||||
if (hasAlias) {
|
||||
[linkPath, alias] = canonicalPath.split("|");
|
||||
const linkPath = canonicalPath.slice(0, pipeIndex);
|
||||
const alias = canonicalPath.slice(pipeIndex + 1);
|
||||
return { linkPath, alias, hasAlias };
|
||||
}
|
||||
|
||||
return { linkPath, alias, hasAlias };
|
||||
return { linkPath: canonicalPath, alias: "", hasAlias };
|
||||
};
|
||||
|
||||
// Link Content Creation
|
||||
|
|
@ -281,11 +282,15 @@ const processFallbackSearch = (
|
|||
// Iterate through potential multi-word sequences starting from startIndex
|
||||
const maxSearchLength = Math.min(text.length - startIndex, 100); // Limit search length for performance
|
||||
|
||||
let potentialMatch = '';
|
||||
let searchWord = '';
|
||||
|
||||
for (let length = 1; length <= maxSearchLength; length++) {
|
||||
const endIndex = startIndex + length;
|
||||
const potentialMatch = text.substring(startIndex, endIndex);
|
||||
const searchWord = settings.ignoreCase
|
||||
? potentialMatch.toLowerCase()
|
||||
const currentChar = text[startIndex + length - 1];
|
||||
potentialMatch += currentChar;
|
||||
searchWord = settings.ignoreCase
|
||||
? searchWord + currentChar.toLowerCase()
|
||||
: potentialMatch;
|
||||
|
||||
// Check if this potential match exists in fallback index
|
||||
|
|
@ -495,16 +500,19 @@ const processStandardText = (
|
|||
let node = trie;
|
||||
let lastCandidate: { candidate: string; length: number } | null = null;
|
||||
let j = i;
|
||||
let candidateBuilder = '';
|
||||
|
||||
while (j < text.length) {
|
||||
const ch = settings.ignoreCase ? text[j].toLowerCase() : text[j];
|
||||
const child = node.children.get(ch);
|
||||
const ch = text[j];
|
||||
const chLower = settings.ignoreCase ? ch.toLowerCase() : ch;
|
||||
candidateBuilder += ch;
|
||||
|
||||
const child = node.children.get(chLower);
|
||||
if (!child) break;
|
||||
|
||||
node = child;
|
||||
if (node.candidate) {
|
||||
const candidate = text.substring(i, j + 1);
|
||||
const candidateIsCjk = isCjkCandidate(candidate);
|
||||
const candidateIsCjk = isCjkCandidate(candidateBuilder);
|
||||
|
||||
if (candidateIsCjk || isWordBoundary(text[j + 1])) {
|
||||
lastCandidate = {
|
||||
|
|
@ -517,7 +525,7 @@ const processStandardText = (
|
|||
}
|
||||
|
||||
if (lastCandidate) {
|
||||
const candidate = text.substring(i, i + lastCandidate.length);
|
||||
const candidate = candidateBuilder.slice(0, lastCandidate.length);
|
||||
|
||||
// Skip if it's a date format
|
||||
if (
|
||||
|
|
|
|||
21
src/trie.ts
21
src/trie.ts
|
|
@ -82,6 +82,9 @@ export const buildCandidateTrie = (
|
|||
// Effective namespace computed relative to baseDir.
|
||||
namespace: string;
|
||||
};
|
||||
const basePrefix = baseDir ? `${baseDir}/` : null;
|
||||
const basePrefixLength = basePrefix?.length || 0;
|
||||
|
||||
const candidates: Candidate[] = allFiles.map((f) => {
|
||||
const candidate: Candidate = {
|
||||
full: f.path,
|
||||
|
|
@ -89,11 +92,8 @@ export const buildCandidateTrie = (
|
|||
restrictNamespace: f.restrictNamespace,
|
||||
namespace: getEffectiveNamespace(f.path, baseDir),
|
||||
};
|
||||
if (baseDir) {
|
||||
const prefix = `${baseDir}/`;
|
||||
if (f.path.startsWith(prefix)) {
|
||||
candidate.short = f.path.slice(prefix.length);
|
||||
}
|
||||
if (basePrefix && f.path.startsWith(basePrefix)) {
|
||||
candidate.short = f.path.slice(basePrefixLength);
|
||||
}
|
||||
return candidate;
|
||||
});
|
||||
|
|
@ -152,11 +152,8 @@ export const buildCandidateTrie = (
|
|||
if (file.aliases) {
|
||||
// Determine shorthand candidate for the file if available.
|
||||
let short: string | null = null;
|
||||
if (baseDir) {
|
||||
const prefix = `${baseDir}/`;
|
||||
if (file.path.startsWith(prefix)) {
|
||||
short = file.path.slice(prefix.length);
|
||||
}
|
||||
if (basePrefix && file.path.startsWith(basePrefix)) {
|
||||
short = file.path.slice(basePrefixLength);
|
||||
}
|
||||
for (const alias of file.aliases) {
|
||||
// If alias equals the shorthand, use alias as canonical; otherwise use "full|alias".
|
||||
|
|
@ -178,8 +175,8 @@ export const buildCandidateTrie = (
|
|||
// When ignoreCase is enabled, we need to add both the original and lowercase versions
|
||||
const trieWords = ignoreCase
|
||||
? words.flatMap(word => {
|
||||
const segments = word.split('/');
|
||||
const lastSegment = segments[segments.length - 1];
|
||||
const lastSlashIndex = word.lastIndexOf('/');
|
||||
const lastSegment = lastSlashIndex === -1 ? word : word.slice(lastSlashIndex + 1);
|
||||
return [word, lastSegment.toLowerCase()];
|
||||
})
|
||||
: words;
|
||||
|
|
|
|||
Loading…
Reference in a new issue