mirror of
https://github.com/ParkerTenBroeck/automata.git
synced 2026-06-06 21:24:06 -04:00
starting work on highlights
This commit is contained in:
parent
ba996ee942
commit
58fb1b956c
3 changed files with 73 additions and 1 deletions
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Decoration,
|
Decoration,
|
||||||
|
DecorationSet,
|
||||||
EditorView,
|
EditorView,
|
||||||
highlightActiveLine,
|
highlightActiveLine,
|
||||||
highlightActiveLineGutter,
|
highlightActiveLineGutter,
|
||||||
|
|
@ -10,7 +11,7 @@ import {
|
||||||
lineNumbers,
|
lineNumbers,
|
||||||
} from "npm:@codemirror/view";
|
} from "npm:@codemirror/view";
|
||||||
|
|
||||||
import { EditorState, StateField, Text } from "npm:@codemirror/state";
|
import { EditorState, RangeSetBuilder, StateEffect, StateField, Text } from "npm:@codemirror/state";
|
||||||
import {
|
import {
|
||||||
defaultKeymap,
|
defaultKeymap,
|
||||||
history,
|
history,
|
||||||
|
|
@ -45,6 +46,57 @@ function compile(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type HighlightKind = "focus" | "success" | "warning" | "error";
|
||||||
|
|
||||||
|
export type HighlightSpan = {
|
||||||
|
from: number;
|
||||||
|
to: number;
|
||||||
|
kind: HighlightKind;
|
||||||
|
};
|
||||||
|
|
||||||
|
function decoForKind(kind: HighlightKind) {
|
||||||
|
// Use a class per kind so each gets a distinct color via CSS
|
||||||
|
return Decoration.mark({ class: `cm-highlight cm-highlight-${kind}` });
|
||||||
|
}
|
||||||
|
|
||||||
|
export function applyHighlights(view: EditorView, spans: HighlightSpan[]) {
|
||||||
|
view.dispatch({ effects: setHighlights.of(spans) });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const highlightsField = StateField.define<DecorationSet>({
|
||||||
|
create() {
|
||||||
|
return Decoration.none;
|
||||||
|
},
|
||||||
|
|
||||||
|
update(highlights, tr) {
|
||||||
|
// Keep highlights aligned with document edits
|
||||||
|
// highlights = highlights.map(tr.changes);
|
||||||
|
|
||||||
|
for (const e of tr.effects) {
|
||||||
|
if (e.is(setHighlights)) {
|
||||||
|
const spans = e.value;
|
||||||
|
|
||||||
|
const builder = new RangeSetBuilder<Decoration>();
|
||||||
|
for (const s of spans) {
|
||||||
|
const from = Math.max(0, Math.min(s.from, tr.state.doc.length));
|
||||||
|
const to = Math.max(0, Math.min(s.to, tr.state.doc.length));
|
||||||
|
if (to > from) builder.add(from, to, decoForKind(s.kind));
|
||||||
|
}
|
||||||
|
highlights = builder.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return highlights;
|
||||||
|
},
|
||||||
|
|
||||||
|
provide: (f) => EditorView.decorations.from(f),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const setHighlights = StateEffect.define<HighlightSpan[]>();
|
||||||
|
|
||||||
const eventBusConnection = StateField.define({
|
const eventBusConnection = StateField.define({
|
||||||
create(state) {
|
create(state) {
|
||||||
const text = state.doc.toString();
|
const text = state.doc.toString();
|
||||||
|
|
@ -198,6 +250,7 @@ const state = EditorState.create({
|
||||||
keymap.of([...defaultKeymap, ...historyKeymap]),
|
keymap.of([...defaultKeymap, ...historyKeymap]),
|
||||||
|
|
||||||
eventBusConnection,
|
eventBusConnection,
|
||||||
|
highlightsField,
|
||||||
diagHover,
|
diagHover,
|
||||||
|
|
||||||
EditorView.lineWrapping,
|
EditorView.lineWrapping,
|
||||||
|
|
@ -223,3 +276,11 @@ bus.on("controls/editor/set_text", ({ text }) => {
|
||||||
bus.on("example/selected", ({ example }) => {
|
bus.on("example/selected", ({ example }) => {
|
||||||
bus.emit("controls/editor/set_text", { text: example.machine });
|
bus.emit("controls/editor/set_text", { text: example.machine });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
applyHighlights(editor, [
|
||||||
|
{ from: 0, to: 10, kind: "focus" },
|
||||||
|
{ from: 10, to: 20, kind: "success" },
|
||||||
|
{ from: 20, to: 30, kind: "warning" },
|
||||||
|
{ from: 30, to: 40, kind: "error" },
|
||||||
|
])
|
||||||
0
web/root/src/focus.ts
Normal file
0
web/root/src/focus.ts
Normal file
|
|
@ -132,3 +132,14 @@
|
||||||
text-underline-offset: 2px;
|
text-underline-offset: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.cm-highlight {
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-highlight-warning { background: color-mix(in srgb, var(--warning) 40%, var(--bg-0)); }
|
||||||
|
.cm-highlight-focus { background: color-mix(in srgb, var(--focus) 40%, var(--bg-0)); }
|
||||||
|
.cm-highlight-success { background: color-mix(in srgb, var(--success) 40%, var(--bg-0)); }
|
||||||
|
.cm-highlight-error { background: color-mix(in srgb, var(--error) 40%, var(--bg-0)); }
|
||||||
Loading…
Add table
Add a link
Reference in a new issue