feat(editor): Mermaid syntax highlighting, linter and autocomplete
- StreamLanguage tokenizer for Mermaid: diagram-type keywords, general keywords, directions, arrows/links, strings, %% comments, init directives and YAML frontmatter, with a dark-theme HighlightStyle - live linter via mermaid.parse: maps parse errors to the right editor line (accounting for the frontmatter lines mermaid strips), with wavy underline, gutter marker and message tooltip - autocomplete: Mermaid keyword/type/direction options plus starter diagram snippets offered on the first line; bracket closing - dark-themed completion + diagnostic tooltips Adds @codemirror/lint, @codemirror/autocomplete and @lezer/highlight.
This commit is contained in:
@@ -17,7 +17,10 @@
|
||||
indentWithTab,
|
||||
} from '@codemirror/commands';
|
||||
import { bracketMatching, indentOnInput } from '@codemirror/language';
|
||||
import { closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete';
|
||||
import { lintKeymap } from '@codemirror/lint';
|
||||
import { store } from '../store.svelte';
|
||||
import { mermaidSupport } from '../cm-mermaid';
|
||||
|
||||
let host: HTMLDivElement;
|
||||
let view: EditorView | undefined;
|
||||
@@ -48,6 +51,43 @@
|
||||
backgroundColor: 'var(--accent-soft) !important',
|
||||
},
|
||||
'.cm-matchingBracket': { backgroundColor: 'var(--accent-soft)', outline: 'none' },
|
||||
|
||||
// Autocomplete popup
|
||||
'.cm-tooltip': {
|
||||
backgroundColor: 'var(--bg-elev-2)',
|
||||
border: '1px solid var(--border-strong)',
|
||||
borderRadius: '6px',
|
||||
color: 'var(--text)',
|
||||
boxShadow: '0 8px 28px rgba(0,0,0,0.45)',
|
||||
},
|
||||
'.cm-tooltip.cm-tooltip-autocomplete > ul': { fontFamily: 'var(--mono)', maxHeight: '16em' },
|
||||
'.cm-tooltip-autocomplete ul li[aria-selected]': {
|
||||
backgroundColor: 'var(--accent)',
|
||||
color: '#fff',
|
||||
},
|
||||
'.cm-completionIcon': { color: 'var(--text-dim)', paddingRight: '0.6em' },
|
||||
'.cm-completionDetail': { color: 'var(--text-faint)', fontStyle: 'normal' },
|
||||
'.cm-completionInfo': {
|
||||
backgroundColor: 'var(--bg-elev-2)',
|
||||
border: '1px solid var(--border-strong)',
|
||||
borderRadius: '6px',
|
||||
color: 'var(--text-dim)',
|
||||
},
|
||||
|
||||
// Lint diagnostics
|
||||
'.cm-diagnostic': {
|
||||
fontFamily: 'var(--mono)',
|
||||
fontSize: '12px',
|
||||
borderLeft: '3px solid var(--red)',
|
||||
padding: '6px 8px',
|
||||
},
|
||||
'.cm-diagnostic-error': { borderLeftColor: 'var(--red)' },
|
||||
'.cm-lintRange-error': {
|
||||
backgroundImage: 'none',
|
||||
textDecoration: 'underline wavy var(--red)',
|
||||
textDecorationSkipInk: 'none',
|
||||
},
|
||||
'.cm-lint-marker-error': { content: '""' },
|
||||
},
|
||||
{ dark: true }
|
||||
);
|
||||
@@ -65,8 +105,16 @@
|
||||
drawSelection(),
|
||||
indentOnInput(),
|
||||
bracketMatching(),
|
||||
closeBrackets(),
|
||||
highlightActiveLine(),
|
||||
keymap.of([...defaultKeymap, ...historyKeymap, indentWithTab]),
|
||||
...mermaidSupport(),
|
||||
keymap.of([
|
||||
...closeBracketsKeymap,
|
||||
...defaultKeymap,
|
||||
...historyKeymap,
|
||||
...lintKeymap,
|
||||
indentWithTab,
|
||||
]),
|
||||
theme,
|
||||
EditorView.lineWrapping,
|
||||
EditorView.updateListener.of((u) => {
|
||||
|
||||
Reference in New Issue
Block a user