fix: stop wiki links extending after autocomplete

This commit is contained in:
Yuri Karamian
2026-08-23 15:38:57 +02:00
parent 221625aabd
commit ce48d77cd8
2 changed files with 39 additions and 28 deletions
+17 -28
View File
@@ -54,6 +54,7 @@
import { convertListNode, type MixedListName } from '$lib/editor/mixedLists'; import { convertListNode, type MixedListName } from '$lib/editor/mixedLists';
import { clearFormatting } from '$lib/editor/clearFormatting'; import { clearFormatting } from '$lib/editor/clearFormatting';
import { serializeInlineMarkdown } from '$lib/editor/markdown'; import { serializeInlineMarkdown } from '$lib/editor/markdown';
import { replaceWithWikiLink } from '$lib/editor/wikiLinks';
import { assetSourceToMarkdown, assetUrlToLocalPath, normalizeLocalAssetPath, resolveVaultFilePath } from '$lib/utils/paths'; import { assetSourceToMarkdown, assetUrlToLocalPath, normalizeLocalAssetPath, resolveVaultFilePath } from '$lib/utils/paths';
import GraphView from './GraphView.svelte'; import GraphView from './GraphView.svelte';
import TagSuggestInput from './TagSuggestInput.svelte'; import TagSuggestInput from './TagSuggestInput.svelte';
@@ -2547,10 +2548,7 @@
function insertWikiLink(entry: NoteTitleEntry, originalRef?: string) { function insertWikiLink(entry: NoteTitleEntry, originalRef?: string) {
if (!editor || !wikiLinkMenu) return; if (!editor || !wikiLinkMenu) return;
const { from } = wikiLinkMenu; const { from } = wikiLinkMenu;
// Delete the [[ trigger and query text
const to = editor.state.selection.from; const to = editor.state.selection.from;
editor.chain().focus().deleteRange({ from, to }).run();
// Insert the wiki-link mark
// For ambiguous titles, use vault-relative path as the ref so it survives source-mode roundtrips // For ambiguous titles, use vault-relative path as the ref so it survives source-mode roundtrips
const displayText = entry.title; const displayText = entry.title;
let titleAttr = originalRef || entry.title; let titleAttr = originalRef || entry.title;
@@ -2562,17 +2560,16 @@
titleAttr = relPath + anchor; titleAttr = relPath + anchor;
} }
} }
tick().then(() => { const transaction = replaceWithWikiLink(
if (!editor) return; editor.state,
editor.chain().focus() from,
.insertContent({ to,
type: 'text', displayText,
text: displayText, { title: titleAttr, path: entry.path || '', aliased: displayText !== titleAttr },
marks: [{ type: 'wikiLink', attrs: { title: titleAttr, path: entry.path, aliased: displayText !== titleAttr } }], );
})
.run();
});
closeWikiLinkMenu(); closeWikiLinkMenu();
editor.view.dispatch(transaction);
editor.view.focus();
} }
function executeWikiLinkCommand(index: number) { function executeWikiLinkCommand(index: number) {
@@ -2759,21 +2756,13 @@
closeWikiLinkMenu(); closeWikiLinkMenu();
tick().then(() => { tick().then(() => {
if (!editor) return; if (!editor) return;
// Use a single ProseMirror transaction to replace [[query] with the editor.view.dispatch(replaceWithWikiLink(
// wiki-link and clear stored marks atomically, preventing the inclusive editor.state,
// mark from bleeding into subsequent text. Do NOT call deleteRange first menuFrom,
// — that would shift positions and make menuFrom/curTo invalid here. curTo,
const { tr, schema } = editor.view.state; display,
const wikiLinkMark = schema.marks.wikiLink.create({ { title: noteRef, path: '', aliased: display !== noteRef },
title: noteRef, ));
path: '',
aliased: display !== noteRef,
});
const textNode = schema.text(display, [wikiLinkMark]);
tr.replaceWith(menuFrom, curTo, textNode);
tr.setSelection(TextSelection.create(tr.doc, menuFrom + display.length));
tr.setStoredMarks([]);
editor.view.dispatch(tr);
}); });
} }
} else { } else {
+22
View File
@@ -0,0 +1,22 @@
import { TextSelection, type EditorState, type Transaction } from '@tiptap/pm/state';
export type WikiLinkAttributes = {
title: string;
path: string;
aliased: boolean;
};
export function replaceWithWikiLink(
state: EditorState,
from: number,
to: number,
text: string,
attrs: WikiLinkAttributes
): Transaction {
const wikiLinkMark = state.schema.marks.wikiLink.create(attrs);
const textNode = state.schema.text(text, [wikiLinkMark]);
const transaction = state.tr.replaceWith(from, to, textNode);
transaction.setSelection(TextSelection.create(transaction.doc, from + text.length));
transaction.setStoredMarks([]);
return transaction;
}