70 lines
2.5 KiB
JavaScript
70 lines
2.5 KiB
JavaScript
import { LRLanguage, LanguageSupport, HighlightStyle, syntaxHighlighting, foldNodeProp, indentNodeProp } from '@codemirror/language';
|
|
import { styleTags, tags as t } from '@lezer/highlight';
|
|
import { parser } from './decodal-parser.js';
|
|
|
|
const parserWithMetadata = parser.configure({
|
|
props: [
|
|
styleTags({
|
|
'Let In Match Import Default': t.keyword,
|
|
'True False': t.bool,
|
|
Identifier: t.variableName,
|
|
String: t.string,
|
|
Regex: t.regexp,
|
|
'Integer Float': t.number,
|
|
Comment: t.lineComment,
|
|
'Plus Minus Star Slash PlusPlus Equal EqualEqual Bang BangEqual Amp AmpAmp PipePipe SlashSlash Gt Gte Lt Lte Arrow': t.operator,
|
|
'LBrace RBrace': t.brace,
|
|
'LBracket RBracket': t.squareBracket,
|
|
'LParen RParen': t.paren,
|
|
'Semicolon Comma Dot Colon': t.punctuation,
|
|
}),
|
|
indentNodeProp.add({
|
|
Object: context => context.column(context.node.from) + context.unit,
|
|
Array: context => context.column(context.node.from) + context.unit,
|
|
MatchExpression: context => context.column(context.node.from) + context.unit,
|
|
LetExpression: context => context.column(context.node.from) + context.unit,
|
|
}),
|
|
foldNodeProp.add({
|
|
Object: foldDelimited('{', '}'),
|
|
Array: foldDelimited('[', ']'),
|
|
MatchExpression: foldDelimited('{', '}'),
|
|
}),
|
|
],
|
|
});
|
|
|
|
function foldDelimited(open, close) {
|
|
return (node, state) => {
|
|
const text = state.doc.sliceString(node.from, node.to);
|
|
const openIndex = text.indexOf(open);
|
|
const closeIndex = text.lastIndexOf(close);
|
|
if (openIndex < 0 || closeIndex <= openIndex) return null;
|
|
const from = node.from + openIndex + open.length;
|
|
const to = node.from + closeIndex;
|
|
return from < to ? { from, to } : null;
|
|
};
|
|
}
|
|
|
|
export const decodalLanguage = LRLanguage.define({
|
|
parser: parserWithMetadata,
|
|
languageData: {
|
|
commentTokens: { line: '#' },
|
|
closeBrackets: { brackets: ['(', '[', '{', '"'] },
|
|
},
|
|
});
|
|
|
|
export const decodalHighlightStyle = HighlightStyle.define([
|
|
{ tag: t.keyword, color: '#93c5fd', fontWeight: '700' },
|
|
{ tag: t.variableName, color: 'inherit' },
|
|
{ tag: t.bool, color: '#fbbf24' },
|
|
{ tag: t.number, color: '#fbbf24' },
|
|
{ tag: t.string, color: '#86efac' },
|
|
{ tag: t.regexp, color: '#86efac' },
|
|
{ tag: t.lineComment, color: '#94a3b8', fontStyle: 'italic' },
|
|
{ tag: t.operator, color: '#f9a8d4' },
|
|
{ tag: [t.brace, t.squareBracket, t.paren, t.punctuation], color: '#f9a8d4' },
|
|
]);
|
|
|
|
export function decodal() {
|
|
return new LanguageSupport(decodalLanguage, [syntaxHighlighting(decodalHighlightStyle)]);
|
|
}
|