mirror of
https://github.com/dnlbauer/obsidian-dataview-autocompletion.git
synced 2026-09-11 06:35:29 +00:00
70 lines
2.6 KiB
TypeScript
70 lines
2.6 KiB
TypeScript
/**
|
|
* Maches parantheses or single square brackets or parantheses
|
|
* and captures the enclosed text
|
|
* If the brackets start a markdown link, they are ignored.
|
|
* Wiki links don't need to be ignored since Obsidian overwrites suggestions for them.
|
|
* We are not allowd to use lookbehinds, because iOS does not support them in older versions.
|
|
*/
|
|
const filledRegex = new RegExp(
|
|
[
|
|
// pattern for parantheses
|
|
// look for opening parantheses; no closing or opening square bracket before to exlude markdown links, etc.
|
|
/(?:^\(|[^\[\]]\()/,
|
|
/(.+?)/,
|
|
// pos. lookahead for closing paranthesis; not followed by another one for nested ((test))
|
|
/(?=\)$|\)[^\)])/,
|
|
|
|
/|/,
|
|
|
|
// pattern for square brackets
|
|
// look for opening square brackets
|
|
/(?:\[)/,
|
|
/(.+?)/,
|
|
// pos. lookahead for closing bracket; not followed by another one ([[test]]) or an opening paranthese (markdown link!)
|
|
/(?=\]$|\][^\]\(])/,
|
|
]
|
|
.map((s) => s.source)
|
|
.join(""),
|
|
"g",
|
|
);
|
|
|
|
/**
|
|
* Finds the dataview metadata field the user is currently inside.
|
|
* It returns [text, start, end] where text is the text inside the field,
|
|
* and start and end are the cursor positions of the start and end of the field.
|
|
* If the user is not inside a field, it returns null.
|
|
*/
|
|
export function getTriggerText(line: string, cursorPos: number): [string, number, number] | null {
|
|
let match = getTriggerTextFromRegex(line, cursorPos, filledRegex);
|
|
if (match !== null) {
|
|
return match;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Given a regex with a capture group, a line of text, and the users cursor position,
|
|
* this function finds the match of the regex in the line that the user is currently inside.
|
|
* If the user is inside the capture group, returns [text, start, end] where text is the text inside the match,
|
|
* start is the position of the start of the match, and end is the position of the end of the match.
|
|
* Otherwise, returns null.
|
|
*/
|
|
function getTriggerTextFromRegex(line: string, cursorPos: number, regex: RegExp): [string, number, number] | null {
|
|
let matches = Array.from(line.matchAll(regex));
|
|
for (const match of matches) {
|
|
if (match.index === undefined) {
|
|
continue;
|
|
}
|
|
|
|
const matchText = match[1] || match[2];
|
|
const matchStart = match!.index + match[0].indexOf(matchText);
|
|
const matchEnd = matchStart + matchText.length;
|
|
const cursorInMatch = cursorPos >= matchStart && cursorPos <= matchEnd;
|
|
|
|
if (cursorInMatch) {
|
|
return [matchText, matchStart, matchEnd];
|
|
}
|
|
}
|
|
return null;
|
|
}
|