fix: unify wikilink resolution and disambiguate duplicate titles
- Create resolveEntry() in wikilink.ts: single case-insensitive resolution function that handles title, alias, filename stem, path suffix, and pipe syntax matching - Replace findEntryByTarget (case-sensitive) and entryMatchesTarget (hardcoded /Laputa/ path) with unified resolveEntry - Fix attachClickHandlers to insert path|title pipe syntax when multiple candidates share the same title (disambiguation) - Update ai-context.ts resolveTarget to use unified resolution - Add comprehensive tests for resolveEntry and disambiguation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import type { VaultEntry } from '../types'
|
||||
import type { FrontmatterValue } from '../components/Inspector'
|
||||
import { useTabManagement } from './useTabManagement'
|
||||
import { updateMockFrontmatter, deleteMockFrontmatterProperty } from './mockFrontmatterHelpers'
|
||||
import { resolveEntry } from '../utils/wikilink'
|
||||
|
||||
interface NewEntryParams {
|
||||
path: string
|
||||
@@ -123,14 +124,8 @@ export function generateUntitledName(entries: VaultEntry[], type: string, pendin
|
||||
return title
|
||||
}
|
||||
|
||||
export function entryMatchesTarget(e: VaultEntry, targetLower: string, targetAsWords: string): boolean {
|
||||
if (e.title.toLowerCase() === targetLower) return true
|
||||
if (e.aliases.some((a) => a.toLowerCase() === targetLower)) return true
|
||||
const pathStem = e.path.replace(/^.*\/Laputa\//, '').replace(/\.md$/, '')
|
||||
if (pathStem.toLowerCase() === targetLower) return true
|
||||
const fileStem = e.filename.replace(/\.md$/, '')
|
||||
if (fileStem.toLowerCase() === targetLower.split('/').pop()) return true
|
||||
return e.title.toLowerCase() === targetAsWords
|
||||
export function entryMatchesTarget(e: VaultEntry, target: string): boolean {
|
||||
return resolveEntry([e], target) === e
|
||||
}
|
||||
|
||||
async function invokeFrontmatter(command: string, args: Record<string, unknown>): Promise<string> {
|
||||
@@ -262,9 +257,7 @@ function openDailyNote(entries: VaultEntry[], selectNote: (e: VaultEntry) => voi
|
||||
}
|
||||
|
||||
function findWikilinkTarget(entries: VaultEntry[], target: string): VaultEntry | undefined {
|
||||
const targetLower = target.toLowerCase()
|
||||
const targetAsWords = target.split('/').pop()?.replace(/-/g, ' ').toLowerCase() ?? targetLower
|
||||
return entries.find((e) => entryMatchesTarget(e, targetLower, targetAsWords))
|
||||
return resolveEntry(entries, target)
|
||||
}
|
||||
|
||||
/** Navigate to a wikilink target, logging a warning if not found. */
|
||||
|
||||
Reference in New Issue
Block a user