You've already forked obsidian-visualiser
Mass updates
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import type { CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { EditorView } from '@codemirror/view';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { Element, MarkdownConfig } from '@lezer/markdown';
|
||||
import { styleTags, tags } from '@lezer/highlight';
|
||||
import { Content } from '../content.util';
|
||||
import { selectAll } from 'hast-util-select';
|
||||
|
||||
function fuzzyMatch(text: string, search: string): number {
|
||||
const textLower = text.toLowerCase().normalize('NFC');
|
||||
@@ -23,10 +25,10 @@ function fuzzyMatch(text: string, search: string): number {
|
||||
|
||||
export const wikilink: MarkdownConfig = {
|
||||
defineNodes: [
|
||||
'Wikilink',
|
||||
'WikilinkMeta',
|
||||
'WikilinkHref',
|
||||
'WikilinkTitle',
|
||||
'Wikilink', //Whole group
|
||||
'WikilinkMeta', //Meta characters ([[ & ]])
|
||||
'WikilinkHref', //Link
|
||||
'WikilinkTitle', //Title (always visible)
|
||||
],
|
||||
parseInline: [{
|
||||
name: 'Wikilink',
|
||||
@@ -41,6 +43,8 @@ export const wikilink: MarkdownConfig = {
|
||||
|
||||
const start = pos, children: Element[] = [], end = start + match[0].length;
|
||||
|
||||
if(match[0] === '[[]]') return end;
|
||||
|
||||
children.push(cx.elt('WikilinkMeta', start, start + 2));
|
||||
|
||||
if(match[1] && !match[2] && !match[3]) //Link only
|
||||
@@ -89,32 +93,69 @@ export const wikilink: MarkdownConfig = {
|
||||
})
|
||||
]
|
||||
};
|
||||
export const autocompletion = (context: CompletionContext): CompletionResult | null => {
|
||||
const word = context.matchBefore(/\[\[[\w\s-]*/);
|
||||
if (!word || (word.from === word.to && !context.explicit))
|
||||
return null;
|
||||
|
||||
const searchTerm = word.text.slice(2).toLowerCase();
|
||||
export const autocompletion = (context: CompletionContext): CompletionResult | Promise<CompletionResult | null> | null => {
|
||||
const header = context.matchBefore(/\[\[[^\[\]\|\#]+#[^\[\]\|\#]*/);
|
||||
if(!header || (header.from === header.to && !context.explicit))
|
||||
{
|
||||
const word = context.matchBefore(/\[\[[\w\s-]*/);
|
||||
if (!word || (word.from === word.to && !context.explicit)) return null;
|
||||
|
||||
const options = Object.values(Content.files).filter(e => e.type !== 'folder').map(e => ({ ...e, score: fuzzyMatch(e.title, searchTerm) })).filter(e => e.score > 0).sort((a, b) => b.score - a.score).slice(0, 50);
|
||||
const options = Object.values(Content.files).filter(e => e.type !== 'folder');
|
||||
|
||||
return {
|
||||
from: word.from + 2,
|
||||
options: options.map(e => ({
|
||||
label: e.title,
|
||||
detail: e.path,
|
||||
apply: (view, completion, from, to) => {
|
||||
view.dispatch({
|
||||
changes: {
|
||||
from: word.from,
|
||||
to: word.to,
|
||||
insert: `[[${e.path}]]`
|
||||
return {
|
||||
from: word.from + 2,
|
||||
options: options.map(e => ({
|
||||
label: e.title,
|
||||
detail: e.path,
|
||||
apply: (view, completion, from, to) => {
|
||||
const closed = view.state.sliceDoc(from, to + 2).endsWith(']]');
|
||||
view.dispatch({
|
||||
changes: {
|
||||
from: from - 2,
|
||||
to: to,
|
||||
insert: closed ? `[[${completion.detail}` : `[[${completion.detail}]]`
|
||||
},
|
||||
selection: { anchor: from + (completion.detail?.length ?? 0) }
|
||||
});
|
||||
},
|
||||
type: 'text',
|
||||
})),
|
||||
commitCharacters: ['#', '|'],
|
||||
validFor: /^[\[\w\s-]*$/,
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const path = header.text.match(/^\[\[([^\[\]\|\#]+)#/);
|
||||
|
||||
if(!path || !path[1]) return null;
|
||||
const content = Content.getFromPath(path[1]);
|
||||
if(!content || content.type !== 'markdown') return null;
|
||||
|
||||
return (async () => {
|
||||
const headers = selectAll('h1, h2, h3, h4, h5, h6', await useMarkdown().parse((await Content.getContent(content.id))!.content as string));
|
||||
|
||||
return {
|
||||
from: header.from + path[1]!.length + 3,
|
||||
options: headers.map(e => ({
|
||||
label: e.properties.id as string,
|
||||
apply: (view, completion, from, to) => {
|
||||
const closed = view.state.sliceDoc(from, to + 2).endsWith(']]');
|
||||
view.dispatch({
|
||||
changes: {
|
||||
from: from,
|
||||
to: to,
|
||||
insert: closed ? `${completion.label}` : `${completion.label}]]`
|
||||
},
|
||||
selection: { anchor: from + (completion.label?.length ?? 0) }
|
||||
});
|
||||
},
|
||||
selection: { anchor: word.from + e.path.length + 2 }
|
||||
});
|
||||
},
|
||||
type: 'text'
|
||||
})),
|
||||
validFor: /^[\[\w\s-]*$/,
|
||||
type: 'text',
|
||||
})),
|
||||
commitCharacters: ['#', '|'],
|
||||
validFor: new RegExp(`\\[\\[${path[1]}#[^\[\]\|\#]*`),
|
||||
};
|
||||
})();
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user