import type { Monaco } from '@monaco-editor/react'; import { dataTypes } from '@/lib/data/data-types/data-types'; export const setupDBMLLanguage = (monaco: Monaco) => { monaco.languages.register({ id: 'dbml' }); // Define themes for DBML monaco.editor.defineTheme('dbml-dark', { base: 'vs-dark', inherit: true, rules: [ { token: 'comment', foreground: '6A9955' }, // Comments { token: 'keyword', foreground: '569CD6' }, // Table, Ref keywords { token: 'string', foreground: 'CE9178' }, // Strings { token: 'annotation', foreground: '9CDCFE' }, // [annotations] { token: 'delimiter', foreground: 'D4D4D4' }, // Braces {} { token: 'operator', foreground: 'D4D4D4' }, // Operators { token: 'type', foreground: '4EC9B0' }, // Data types { token: 'identifier', foreground: '9CDCFE' }, // Field names ], colors: {}, }); monaco.editor.defineTheme('dbml-light', { base: 'vs', inherit: true, rules: [ { token: 'comment', foreground: '008000' }, // Comments { token: 'keyword', foreground: '0000FF' }, // Table, Ref keywords { token: 'string', foreground: 'A31515' }, // Strings { token: 'annotation', foreground: '001080' }, // [annotations] { token: 'delimiter', foreground: '000000' }, // Braces {} { token: 'operator', foreground: '000000' }, // Operators { token: 'type', foreground: '267F99' }, // Data types { token: 'identifier', foreground: '001080' }, // Field names ], colors: {}, }); const dataTypesNames = dataTypes.map((dt) => dt.name); const datatypePattern = dataTypesNames.join('|'); monaco.languages.setMonarchTokensProvider('dbml', { keywords: ['Table', 'Ref', 'Indexes', 'Note', 'Enum', 'enum'], datatypes: dataTypesNames, operators: ['>', '<', '-'], tokenizer: { root: [ // Comments [/\/\/.*$/, 'comment'], // Keywords - case insensitive [ /\b([Tt][Aa][Bb][Ll][Ee]|[Ee][Nn][Uu][Mm]|[Rr][Ee][Ff]|[Ii][Nn][Dd][Ee][Xx][Ee][Ss]|[Nn][Oo][Tt][Ee])\b/, 'keyword', ], // Annotations in brackets [/\[.*?\]/, 'annotation'], // Strings [/'''/, 'string', '@tripleQuoteString'], [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-terminated string [/'([^'\\]|\\.)*$/, 'string.invalid'], // non-terminated string [/"/, 'string', '@string_double'], [/'/, 'string', '@string_single'], [/`.*?`/, 'string'], // Delimiters and operators [/[{}()]/, 'delimiter'], [/[<>-]/, 'operator'], [/:/, 'delimiter'], // Data types [new RegExp(`\\b(${datatypePattern})\\b`, 'i'), 'type'], // Numbers [/\d+/, 'number'], // Identifiers [/[a-zA-Z_]\w*/, 'identifier'], ], string_double: [ [/[^\\"]+/, 'string'], [/\\./, 'string.escape'], [/"/, 'string', '@pop'], ], string_single: [ [/[^\\']+/, 'string'], [/\\./, 'string.escape'], [/'/, 'string', '@pop'], ], tripleQuoteString: [ [/[^']+/, 'string'], [/'''/, 'string', '@pop'], [/'/, 'string'], ], }, }); };