mirror of
https://github.com/kou029w/quot.git
synced 2025-01-18 16:08:03 +00:00
create indent-plugin
This commit is contained in:
parent
ba0206a4d2
commit
c9d33c28d6
3 changed files with 83 additions and 21 deletions
79
app/syntax/indent-plugins.ts
Normal file
79
app/syntax/indent-plugins.ts
Normal file
|
@ -0,0 +1,79 @@
|
|||
import { indentWithTab } from "@codemirror/commands";
|
||||
import { indentService, indentUnit, syntaxTree } from "@codemirror/language";
|
||||
import {
|
||||
type DecorationSet,
|
||||
type EditorView,
|
||||
type ViewUpdate,
|
||||
Decoration,
|
||||
ViewPlugin,
|
||||
WidgetType,
|
||||
keymap,
|
||||
} from "@codemirror/view";
|
||||
|
||||
class IndentWidget extends WidgetType {
|
||||
constructor(readonly bullet: boolean) {
|
||||
super();
|
||||
}
|
||||
toDOM() {
|
||||
const indent = document.createElement("span");
|
||||
indent.textContent = this.bullet ? "•" : " ";
|
||||
indent.style.paddingInline = "0.5em";
|
||||
return indent;
|
||||
}
|
||||
}
|
||||
|
||||
function indentDecorations(view: EditorView) {
|
||||
const decorations: Array<{
|
||||
from: number;
|
||||
to: number;
|
||||
value: Decoration;
|
||||
}> = [];
|
||||
for (const { from, to } of view.visibleRanges) {
|
||||
syntaxTree(view.state).iterate({
|
||||
from,
|
||||
to,
|
||||
enter(node) {
|
||||
if (node.name === "Indent") {
|
||||
const next = view.state.doc.sliceString(node.to, node.to + 1);
|
||||
const decoration = Decoration.widget({
|
||||
widget: new IndentWidget(/^[^ \t]?$/.test(next)),
|
||||
});
|
||||
decorations.push(decoration.range(node.from));
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
return Decoration.set(decorations);
|
||||
}
|
||||
|
||||
const indentDecorationsPlugin = ViewPlugin.fromClass(
|
||||
class {
|
||||
decorations: DecorationSet;
|
||||
constructor(view: EditorView) {
|
||||
this.decorations = indentDecorations(view);
|
||||
}
|
||||
update(update: ViewUpdate) {
|
||||
if (update.docChanged || update.viewportChanged) {
|
||||
this.decorations = indentDecorations(update.view);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
decorations(v) {
|
||||
return v.decorations;
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const indentPlugins = [
|
||||
keymap.of([indentWithTab]),
|
||||
indentUnit.of(" "),
|
||||
indentService.of((context, pos) => {
|
||||
const previousLine = context.lineAt(pos, -1).text;
|
||||
if (previousLine.trim() === "") return null;
|
||||
return /^[ \t]*/.exec(previousLine)?.[0]?.length ?? null;
|
||||
}),
|
||||
indentDecorationsPlugin,
|
||||
];
|
||||
|
||||
export default indentPlugins;
|
|
@ -11,7 +11,6 @@ export const quotLanguage = LRLanguage.define({
|
|||
props: [
|
||||
styleTags({
|
||||
Heading: t.heading,
|
||||
Indent: t.separator,
|
||||
AutoLink: t.link,
|
||||
Code: t.monospace,
|
||||
}),
|
||||
|
@ -27,14 +26,6 @@ export const quotHighlighting = syntaxHighlighting(
|
|||
fontSize: "1.25em",
|
||||
marginBlockEnd: "0.5em",
|
||||
},
|
||||
{
|
||||
tag: t.separator,
|
||||
letterSpacing: "1.5em",
|
||||
"&:last-child:after": {
|
||||
content: `"•"`,
|
||||
marginInline: "-0.9em",
|
||||
},
|
||||
},
|
||||
{
|
||||
tag: t.link,
|
||||
class: "auto-link",
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { onCleanup, onMount } from "solid-js";
|
||||
import { minimalSetup } from "codemirror";
|
||||
import { emacsStyleKeymap, indentWithTab } from "@codemirror/commands";
|
||||
import { indentService, indentUnit } from "@codemirror/language";
|
||||
import { emacsStyleKeymap } from "@codemirror/commands";
|
||||
import { EditorView, keymap } from "@codemirror/view";
|
||||
import type Pages from "../../protocol/pages";
|
||||
import "./editor.css";
|
||||
import { quotHighlighting, quotLanguage } from "../../syntax/quot";
|
||||
import indentPlugins from "../../syntax/indent-plugins";
|
||||
|
||||
export default (props: {
|
||||
id: number;
|
||||
|
@ -36,19 +36,11 @@ export default (props: {
|
|||
props.onUpdatePage({ id: props.id, title, text });
|
||||
}),
|
||||
EditorView.lineWrapping,
|
||||
indentUnit.of(" "),
|
||||
indentService.of((context, pos) => {
|
||||
const previousLine = context.lineAt(pos, -1).text;
|
||||
if (previousLine.trim() === "") return null;
|
||||
return /^[ \t]*/.exec(previousLine)?.[0]?.length ?? null;
|
||||
}),
|
||||
keymap.of([
|
||||
indentWithTab,
|
||||
...emacsStyleKeymap.filter(({ key }) => key !== "Ctrl-v"),
|
||||
]),
|
||||
keymap.of(emacsStyleKeymap.filter(({ key }) => key !== "Ctrl-v")),
|
||||
minimalSetup,
|
||||
quotLanguage,
|
||||
quotHighlighting,
|
||||
...indentPlugins,
|
||||
],
|
||||
});
|
||||
ref.addEventListener("click", (e) => {
|
||||
|
|
Loading…
Add table
Reference in a new issue