1
0
silverbullet/web/cm_plugins/frontmatter.ts

54 lines
1.7 KiB
TypeScript
Raw Normal View History

2024-01-08 08:21:19 +00:00
import { Decoration, EditorState, foldedRanges, syntaxTree } from "../deps.ts";
import { decoratorStateField, HtmlWidget, isCursorInRange } from "./util.ts";
2024-01-08 08:21:19 +00:00
export function frontmatterPlugin() {
return decoratorStateField(
(state: EditorState) => {
const widgets: any[] = [];
2024-01-08 08:21:19 +00:00
const foldRanges = foldedRanges(state);
syntaxTree(state).iterate({
enter(node) {
if (
2024-01-08 08:21:19 +00:00
node.name === "FrontMatterMarker"
) {
2024-01-08 08:21:19 +00:00
const parent = node.node.parent!;
2024-01-08 08:21:19 +00:00
const folded = foldRanges.iter();
let shouldShowFrontmatterBanner = false;
while (folded.value) {
// Check if cursor is in the folded range
if (isCursorInRange(state, [folded.from, folded.to])) {
// console.log("Cursor is in folded area, ");
shouldShowFrontmatterBanner = true;
break;
}
2024-01-08 08:21:19 +00:00
folded.next();
}
if (!isCursorInRange(state, [parent.from, parent.to])) {
widgets.push(
Decoration.line({
class: "sb-line-frontmatter-outside",
}).range(node.from),
);
shouldShowFrontmatterBanner = true;
}
if (shouldShowFrontmatterBanner && parent.from === node.from) {
// Only put this on the first line of the frontmatter
widgets.push(
Decoration.widget({
widget: new HtmlWidget(
`frontmatter`,
"sb-frontmatter-marker",
),
}).range(node.from),
);
}
}
},
});
return Decoration.set(widgets, true);
},
);
}